├── .gitattributes ├── .gitignore ├── README.md ├── assets ├── browserbase-demo.png ├── browserbase-mcp.png ├── cover-mcp.png ├── cover.png ├── session.png └── stagehand-mcp.png ├── browserbase ├── README.md ├── package-lock.json ├── package.json ├── src │ └── index.ts └── tsconfig.json └── stagehand ├── README.md ├── package-lock.json ├── package.json ├── src ├── index.ts ├── logging.ts ├── prompts.ts ├── resources.ts ├── server.ts ├── tools.ts └── utils.ts └── tsconfig.json /.gitattributes: -------------------------------------------------------------------------------- 1 | package-lock.json linguist-generated=true 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | 132 | build/ 133 | 134 | gcp-oauth.keys.json 135 | .*-server-credentials.json 136 | 137 | # Byte-compiled / optimized / DLL files 138 | __pycache__/ 139 | *.py[cod] 140 | *$py.class 141 | 142 | # C extensions 143 | *.so 144 | 145 | # Distribution / packaging 146 | .Python 147 | build/ 148 | develop-eggs/ 149 | dist/ 150 | downloads/ 151 | eggs/ 152 | .eggs/ 153 | lib/ 154 | lib64/ 155 | parts/ 156 | sdist/ 157 | var/ 158 | wheels/ 159 | share/python-wheels/ 160 | *.egg-info/ 161 | .installed.cfg 162 | *.egg 163 | MANIFEST 164 | 165 | # PyInstaller 166 | # Usually these files are written by a python script from a template 167 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 168 | *.manifest 169 | *.spec 170 | 171 | # Installer logs 172 | pip-log.txt 173 | pip-delete-this-directory.txt 174 | 175 | # Unit test / coverage reports 176 | htmlcov/ 177 | .tox/ 178 | .nox/ 179 | .coverage 180 | .coverage.* 181 | .cache 182 | nosetests.xml 183 | coverage.xml 184 | *.cover 185 | *.py,cover 186 | .hypothesis/ 187 | .pytest_cache/ 188 | cover/ 189 | 190 | # Translations 191 | *.mo 192 | *.pot 193 | 194 | # Django stuff: 195 | *.log 196 | local_settings.py 197 | db.sqlite3 198 | db.sqlite3-journal 199 | 200 | # Flask stuff: 201 | instance/ 202 | .webassets-cache 203 | 204 | # Scrapy stuff: 205 | .scrapy 206 | 207 | # Sphinx documentation 208 | docs/_build/ 209 | 210 | # PyBuilder 211 | .pybuilder/ 212 | target/ 213 | 214 | # Jupyter Notebook 215 | .ipynb_checkpoints 216 | 217 | # IPython 218 | profile_default/ 219 | ipython_config.py 220 | 221 | # pyenv 222 | # For a library or package, you might want to ignore these files since the code is 223 | # intended to run in multiple environments; otherwise, check them in: 224 | # .python-version 225 | 226 | # pipenv 227 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 228 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 229 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 230 | # install all needed dependencies. 231 | #Pipfile.lock 232 | 233 | # poetry 234 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 235 | # This is especially recommended for binary packages to ensure reproducibility, and is more 236 | # commonly ignored for libraries. 237 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 238 | #poetry.lock 239 | 240 | # pdm 241 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 242 | #pdm.lock 243 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 244 | # in version control. 245 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 246 | .pdm.toml 247 | .pdm-python 248 | .pdm-build/ 249 | 250 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 251 | __pypackages__/ 252 | 253 | # Celery stuff 254 | celerybeat-schedule 255 | celerybeat.pid 256 | 257 | # SageMath parsed files 258 | *.sage.py 259 | 260 | # Environments 261 | .env 262 | .venv 263 | env/ 264 | venv/ 265 | ENV/ 266 | env.bak/ 267 | venv.bak/ 268 | 269 | # Spyder project settings 270 | .spyderproject 271 | .spyproject 272 | 273 | # Rope project settings 274 | .ropeproject 275 | 276 | # mkdocs documentation 277 | /site 278 | 279 | # mypy 280 | .mypy_cache/ 281 | .dmypy.json 282 | dmypy.json 283 | 284 | # Pyre type checker 285 | .pyre/ 286 | 287 | # pytype static type analyzer 288 | .pytype/ 289 | 290 | # Cython debug symbols 291 | cython_debug/ 292 | 293 | .DS_Store 294 | 295 | # PyCharm 296 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 297 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 298 | # and can be added to the global gitignore or merged into this file. For a more nuclear 299 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 300 | #.idea/ 301 | 302 | 303 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Browserbase MCP Server 2 | 3 | ![cover](assets/cover-mcp.png) 4 | 5 | [The Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open protocol that enables seamless integration between LLM applications and external data sources and tools. Whether you’re building an AI-powered IDE, enhancing a chat interface, or creating custom AI workflows, MCP provides a standardized way to connect LLMs with the context they need. 6 | 7 | This server provides cloud browser automation capabilities using [Browserbase](https://www.browserbase.com/), [Puppeteer](https://pptr.dev/), and [Stagehand](https://github.com/browserbase/stagehand). This server enables LLMs to interact with web pages, take screenshots, and execute JavaScript in a cloud browser environment. 8 | 9 | To learn to get started with Browserbase, check out [Browserbase MCP](./browserbase/README.md) or [Stagehand MCP](./stagehand/README.md). 10 | 11 | ## Getting Started with available MCPs 12 | 13 | 🌐 **Browserbase MCP** - Located in [`browserbase/`](./browserbase/) 14 | 15 | | Feature | Description | 16 | | ------------------ | ----------------------------------------- | 17 | | Browser Automation | Control and orchestrate cloud browsers | 18 | | Data Extraction | Extract structured data from any webpage | 19 | | Console Monitoring | Track and analyze browser console logs | 20 | | Screenshots | Capture full-page and element screenshots | 21 | | JavaScript | Execute custom JS in the browser context | 22 | | Web Interaction | Navigate, click, and fill forms with ease | 23 | 24 | 🤘 **Stagehand MCP** - Located in [`stagehand/`](./stagehand/) 25 | 26 | | Feature | Description | 27 | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | 28 | | Atomic Instructions | Execute precise actions like `act("click the login button")` or `extract("find the red shoes")` | 29 | | Model Flexibility | Supports multiple models, including OpenAI's GPT-4 and Anthropic's Claude-3.7 Sonnet | 30 | | Modular Design | Easily integrate new models with minimal changes | 31 | | Vision Support | Use annotated screenshots for complex DOMs | 32 | | Open Source | Contribute to the project and join the [Slack community](https://join.slack.com/t/stagehand-dev/shared_invite/zt-2uvuobu50-~wVSx2Si75CPa3332hwVEw) for support | 33 | 34 | ### Alternative Installation Methods 35 | 36 | [Smithery](https://smithery.ai/server/@browserbasehq/mcp-browserbase) 37 | -------------------------------------------------------------------------------- /assets/browserbase-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserbase/mcp-server-browserbase/0fb9286c0c1ad79c757d7ac5213fa8a8e671e1be/assets/browserbase-demo.png -------------------------------------------------------------------------------- /assets/browserbase-mcp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserbase/mcp-server-browserbase/0fb9286c0c1ad79c757d7ac5213fa8a8e671e1be/assets/browserbase-mcp.png -------------------------------------------------------------------------------- /assets/cover-mcp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserbase/mcp-server-browserbase/0fb9286c0c1ad79c757d7ac5213fa8a8e671e1be/assets/cover-mcp.png -------------------------------------------------------------------------------- /assets/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserbase/mcp-server-browserbase/0fb9286c0c1ad79c757d7ac5213fa8a8e671e1be/assets/cover.png -------------------------------------------------------------------------------- /assets/session.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserbase/mcp-server-browserbase/0fb9286c0c1ad79c757d7ac5213fa8a8e671e1be/assets/session.png -------------------------------------------------------------------------------- /assets/stagehand-mcp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserbase/mcp-server-browserbase/0fb9286c0c1ad79c757d7ac5213fa8a8e671e1be/assets/stagehand-mcp.png -------------------------------------------------------------------------------- /browserbase/README.md: -------------------------------------------------------------------------------- 1 | # Browserbase MCP Server 2 | 3 | ![cover](../assets/browserbase-mcp.png) 4 | 5 | ## Get Started 6 | 7 | 1. Run `npm install` to install the necessary dependencies, then run `npm run build` to get `dist/index.js`. 8 | 9 | 2. Set up your Claude Desktop configuration to use the server. 10 | 11 | ```json 12 | { 13 | "mcpServers": { 14 | "browserbase": { 15 | "command": "node", 16 | "args": ["path/to/mcp-server-browserbase/browserbase/dist/index.js"], 17 | "env": { 18 | "BROWSERBASE_API_KEY": "", 19 | "BROWSERBASE_PROJECT_ID": "" 20 | } 21 | } 22 | } 23 | } 24 | ``` 25 | 26 | 3. Restart your Claude Desktop app and you should see the tools available clicking the 🔨 icon. 27 | 28 | 4. Start using the tools! Below is an image of Claude closing a browser session. 29 | 30 |

31 | demo 32 |

33 | 34 | 35 | ## Tools 36 | 37 | ### Browserbase API 38 | 39 | - **browserbase_create_session** 40 | 41 | - Create a new cloud browser session using Browserbase 42 | - No required inputs 43 | 44 | - **browserbase_navigate** 45 | 46 | - Navigate to any URL in the browser 47 | - Input: `url` (string) 48 | 49 | - **browserbase_screenshot** 50 | 51 | - Capture screenshots of the entire page or specific elements 52 | - Inputs: 53 | - `name` (string, required): Name for the screenshot 54 | - `selector` (string, optional): CSS selector for element to screenshot 55 | - `width` (number, optional, default: 800): Screenshot width 56 | - `height` (number, optional, default: 600): Screenshot height 57 | 58 | - **browserbase_click** 59 | 60 | - Click elements on the page 61 | - Input: `selector` (string): CSS selector for element to click 62 | 63 | - **browserbase_fill** 64 | 65 | - Fill out input fields 66 | - Inputs: 67 | - `selector` (string): CSS selector for input field 68 | - `value` (string): Value to fill 69 | 70 | - **browserbase_evaluate** 71 | 72 | - Execute JavaScript in the browser console 73 | - Input: `script` (string): JavaScript code to execute 74 | 75 | - **browserbase_get_content** 76 | 77 | - Extract all content from the current page 78 | - Input: `selector` (string, optional): CSS selector to get content from specific elements 79 | 80 | - **browserbase_parallel_sessions** 81 | - Create multiple browser sessions and navigate to different URLs 82 | - Input: `sessions` (array): Array of objects containing: 83 | - `url` (string): URL to navigate to 84 | - `id` (string): Session identifier 85 | 86 | ### Resources 87 | 88 | The server provides access to two types of resources: 89 | 90 | 1. **Console Logs** (`console://logs`) 91 | 92 | - Browser console output in text format 93 | - Includes all console messages from the browser 94 | 95 | 2. **Screenshots** (`screenshot://`) 96 | - PNG images of captured screenshots 97 | - Accessible via the screenshot name specified during capture 98 | 99 | ## Key Features 100 | 101 | - Cloud browser automation 102 | - Web data extraction 103 | - Console log monitoring 104 | - Screenshot capabilities 105 | - JavaScript execution 106 | - Basic web interaction (navigation, clicking, form filling) 107 | 108 | ## License 109 | 110 | This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository. 111 | -------------------------------------------------------------------------------- /browserbase/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@browserbasehq/mcp-browserbase", 3 | "version": "0.5.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@browserbasehq/mcp-browserbase", 9 | "version": "0.5.1", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@browserbasehq/sdk": "^2.0.0", 13 | "@modelcontextprotocol/sdk": "^1.0.3", 14 | "puppeteer-core": "^23.9.0" 15 | }, 16 | "bin": { 17 | "mcp-server-browserbase": "dist/index.js" 18 | }, 19 | "devDependencies": { 20 | "shx": "^0.3.4", 21 | "typescript": "^5.6.2" 22 | } 23 | }, 24 | "node_modules/@browserbasehq/sdk": { 25 | "version": "2.0.0", 26 | "resolved": "https://registry.npmjs.org/@browserbasehq/sdk/-/sdk-2.0.0.tgz", 27 | "integrity": "sha512-BdPlZyn0dpXlL70gNK4acpqWIRB+edo2z0/GalQdWghRq8iQjySd9fVIF3evKH1p2wCYekZJRK6tm29YfXB67g==", 28 | "license": "Apache-2.0", 29 | "dependencies": { 30 | "@types/node": "^18.11.18", 31 | "@types/node-fetch": "^2.6.4", 32 | "abort-controller": "^3.0.0", 33 | "agentkeepalive": "^4.2.1", 34 | "form-data-encoder": "1.7.2", 35 | "formdata-node": "^4.3.2", 36 | "node-fetch": "^2.6.7" 37 | } 38 | }, 39 | "node_modules/@modelcontextprotocol/sdk": { 40 | "version": "1.0.3", 41 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.3.tgz", 42 | "integrity": "sha512-2as3cX/VJ0YBHGmdv3GFyTpoM8q2gqE98zh3Vf1NwnsSY0h3mvoO07MUzfygCKkWsFjcZm4otIiqD6Xh7kiSBQ==", 43 | "dependencies": { 44 | "content-type": "^1.0.5", 45 | "raw-body": "^3.0.0", 46 | "zod": "^3.23.8" 47 | } 48 | }, 49 | "node_modules/@puppeteer/browsers": { 50 | "version": "2.5.0", 51 | "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.5.0.tgz", 52 | "integrity": "sha512-6TQAc/5uRILE6deixJ1CR8rXyTbzXIXNgO1D0Woi9Bqicz2FV5iKP3BHYEg6o4UATCMcbQQ0jbmeaOkn/HQk2w==", 53 | "license": "Apache-2.0", 54 | "dependencies": { 55 | "debug": "^4.3.7", 56 | "extract-zip": "^2.0.1", 57 | "progress": "^2.0.3", 58 | "proxy-agent": "^6.4.0", 59 | "semver": "^7.6.3", 60 | "tar-fs": "^3.0.6", 61 | "unbzip2-stream": "^1.4.3", 62 | "yargs": "^17.7.2" 63 | }, 64 | "bin": { 65 | "browsers": "lib/cjs/main-cli.js" 66 | }, 67 | "engines": { 68 | "node": ">=18" 69 | } 70 | }, 71 | "node_modules/@tootallnate/quickjs-emscripten": { 72 | "version": "0.23.0", 73 | "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", 74 | "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", 75 | "license": "MIT" 76 | }, 77 | "node_modules/@types/node": { 78 | "version": "18.19.67", 79 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.67.tgz", 80 | "integrity": "sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==", 81 | "license": "MIT", 82 | "dependencies": { 83 | "undici-types": "~5.26.4" 84 | } 85 | }, 86 | "node_modules/@types/node-fetch": { 87 | "version": "2.6.12", 88 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", 89 | "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", 90 | "license": "MIT", 91 | "dependencies": { 92 | "@types/node": "*", 93 | "form-data": "^4.0.0" 94 | } 95 | }, 96 | "node_modules/@types/yauzl": { 97 | "version": "2.10.3", 98 | "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", 99 | "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", 100 | "license": "MIT", 101 | "optional": true, 102 | "dependencies": { 103 | "@types/node": "*" 104 | } 105 | }, 106 | "node_modules/abort-controller": { 107 | "version": "3.0.0", 108 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 109 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 110 | "license": "MIT", 111 | "dependencies": { 112 | "event-target-shim": "^5.0.0" 113 | }, 114 | "engines": { 115 | "node": ">=6.5" 116 | } 117 | }, 118 | "node_modules/agent-base": { 119 | "version": "7.1.1", 120 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", 121 | "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", 122 | "license": "MIT", 123 | "dependencies": { 124 | "debug": "^4.3.4" 125 | }, 126 | "engines": { 127 | "node": ">= 14" 128 | } 129 | }, 130 | "node_modules/agentkeepalive": { 131 | "version": "4.5.0", 132 | "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", 133 | "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", 134 | "license": "MIT", 135 | "dependencies": { 136 | "humanize-ms": "^1.2.1" 137 | }, 138 | "engines": { 139 | "node": ">= 8.0.0" 140 | } 141 | }, 142 | "node_modules/ansi-regex": { 143 | "version": "5.0.1", 144 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 145 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 146 | "license": "MIT", 147 | "engines": { 148 | "node": ">=8" 149 | } 150 | }, 151 | "node_modules/ansi-styles": { 152 | "version": "4.3.0", 153 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 154 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 155 | "license": "MIT", 156 | "dependencies": { 157 | "color-convert": "^2.0.1" 158 | }, 159 | "engines": { 160 | "node": ">=8" 161 | }, 162 | "funding": { 163 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 164 | } 165 | }, 166 | "node_modules/ast-types": { 167 | "version": "0.13.4", 168 | "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", 169 | "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", 170 | "license": "MIT", 171 | "dependencies": { 172 | "tslib": "^2.0.1" 173 | }, 174 | "engines": { 175 | "node": ">=4" 176 | } 177 | }, 178 | "node_modules/asynckit": { 179 | "version": "0.4.0", 180 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 181 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", 182 | "license": "MIT" 183 | }, 184 | "node_modules/b4a": { 185 | "version": "1.6.7", 186 | "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", 187 | "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", 188 | "license": "Apache-2.0" 189 | }, 190 | "node_modules/balanced-match": { 191 | "version": "1.0.2", 192 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 193 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 194 | "dev": true, 195 | "license": "MIT" 196 | }, 197 | "node_modules/bare-events": { 198 | "version": "2.5.0", 199 | "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", 200 | "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", 201 | "license": "Apache-2.0", 202 | "optional": true 203 | }, 204 | "node_modules/bare-fs": { 205 | "version": "2.3.5", 206 | "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", 207 | "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", 208 | "license": "Apache-2.0", 209 | "optional": true, 210 | "dependencies": { 211 | "bare-events": "^2.0.0", 212 | "bare-path": "^2.0.0", 213 | "bare-stream": "^2.0.0" 214 | } 215 | }, 216 | "node_modules/bare-os": { 217 | "version": "2.4.4", 218 | "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", 219 | "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", 220 | "license": "Apache-2.0", 221 | "optional": true 222 | }, 223 | "node_modules/bare-path": { 224 | "version": "2.1.3", 225 | "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", 226 | "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", 227 | "license": "Apache-2.0", 228 | "optional": true, 229 | "dependencies": { 230 | "bare-os": "^2.1.0" 231 | } 232 | }, 233 | "node_modules/bare-stream": { 234 | "version": "2.4.2", 235 | "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.4.2.tgz", 236 | "integrity": "sha512-XZ4ln/KV4KT+PXdIWTKjsLY+quqCaEtqqtgGJVPw9AoM73By03ij64YjepK0aQvHSWDb6AfAZwqKaFu68qkrdA==", 237 | "license": "Apache-2.0", 238 | "optional": true, 239 | "dependencies": { 240 | "streamx": "^2.20.0" 241 | } 242 | }, 243 | "node_modules/base64-js": { 244 | "version": "1.5.1", 245 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 246 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 247 | "funding": [ 248 | { 249 | "type": "github", 250 | "url": "https://github.com/sponsors/feross" 251 | }, 252 | { 253 | "type": "patreon", 254 | "url": "https://www.patreon.com/feross" 255 | }, 256 | { 257 | "type": "consulting", 258 | "url": "https://feross.org/support" 259 | } 260 | ], 261 | "license": "MIT" 262 | }, 263 | "node_modules/basic-ftp": { 264 | "version": "5.0.5", 265 | "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", 266 | "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", 267 | "license": "MIT", 268 | "engines": { 269 | "node": ">=10.0.0" 270 | } 271 | }, 272 | "node_modules/brace-expansion": { 273 | "version": "1.1.11", 274 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 275 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 276 | "dev": true, 277 | "license": "MIT", 278 | "dependencies": { 279 | "balanced-match": "^1.0.0", 280 | "concat-map": "0.0.1" 281 | } 282 | }, 283 | "node_modules/buffer": { 284 | "version": "5.7.1", 285 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 286 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 287 | "funding": [ 288 | { 289 | "type": "github", 290 | "url": "https://github.com/sponsors/feross" 291 | }, 292 | { 293 | "type": "patreon", 294 | "url": "https://www.patreon.com/feross" 295 | }, 296 | { 297 | "type": "consulting", 298 | "url": "https://feross.org/support" 299 | } 300 | ], 301 | "license": "MIT", 302 | "dependencies": { 303 | "base64-js": "^1.3.1", 304 | "ieee754": "^1.1.13" 305 | } 306 | }, 307 | "node_modules/buffer-crc32": { 308 | "version": "0.2.13", 309 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 310 | "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", 311 | "license": "MIT", 312 | "engines": { 313 | "node": "*" 314 | } 315 | }, 316 | "node_modules/bytes": { 317 | "version": "3.1.2", 318 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 319 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 320 | "license": "MIT", 321 | "engines": { 322 | "node": ">= 0.8" 323 | } 324 | }, 325 | "node_modules/chromium-bidi": { 326 | "version": "0.8.0", 327 | "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.8.0.tgz", 328 | "integrity": "sha512-uJydbGdTw0DEUjhoogGveneJVWX/9YuqkWePzMmkBYwtdAqo5d3J/ovNKFr+/2hWXYmYCr6it8mSSTIj6SS6Ug==", 329 | "license": "Apache-2.0", 330 | "dependencies": { 331 | "mitt": "3.0.1", 332 | "urlpattern-polyfill": "10.0.0", 333 | "zod": "3.23.8" 334 | }, 335 | "peerDependencies": { 336 | "devtools-protocol": "*" 337 | } 338 | }, 339 | "node_modules/cliui": { 340 | "version": "8.0.1", 341 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", 342 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", 343 | "license": "ISC", 344 | "dependencies": { 345 | "string-width": "^4.2.0", 346 | "strip-ansi": "^6.0.1", 347 | "wrap-ansi": "^7.0.0" 348 | }, 349 | "engines": { 350 | "node": ">=12" 351 | } 352 | }, 353 | "node_modules/color-convert": { 354 | "version": "2.0.1", 355 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 356 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 357 | "license": "MIT", 358 | "dependencies": { 359 | "color-name": "~1.1.4" 360 | }, 361 | "engines": { 362 | "node": ">=7.0.0" 363 | } 364 | }, 365 | "node_modules/color-name": { 366 | "version": "1.1.4", 367 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 368 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 369 | "license": "MIT" 370 | }, 371 | "node_modules/combined-stream": { 372 | "version": "1.0.8", 373 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 374 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 375 | "license": "MIT", 376 | "dependencies": { 377 | "delayed-stream": "~1.0.0" 378 | }, 379 | "engines": { 380 | "node": ">= 0.8" 381 | } 382 | }, 383 | "node_modules/concat-map": { 384 | "version": "0.0.1", 385 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 386 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 387 | "dev": true, 388 | "license": "MIT" 389 | }, 390 | "node_modules/content-type": { 391 | "version": "1.0.5", 392 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 393 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 394 | "license": "MIT", 395 | "engines": { 396 | "node": ">= 0.6" 397 | } 398 | }, 399 | "node_modules/data-uri-to-buffer": { 400 | "version": "6.0.2", 401 | "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", 402 | "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", 403 | "license": "MIT", 404 | "engines": { 405 | "node": ">= 14" 406 | } 407 | }, 408 | "node_modules/debug": { 409 | "version": "4.3.7", 410 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", 411 | "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", 412 | "license": "MIT", 413 | "dependencies": { 414 | "ms": "^2.1.3" 415 | }, 416 | "engines": { 417 | "node": ">=6.0" 418 | }, 419 | "peerDependenciesMeta": { 420 | "supports-color": { 421 | "optional": true 422 | } 423 | } 424 | }, 425 | "node_modules/degenerator": { 426 | "version": "5.0.1", 427 | "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", 428 | "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", 429 | "license": "MIT", 430 | "dependencies": { 431 | "ast-types": "^0.13.4", 432 | "escodegen": "^2.1.0", 433 | "esprima": "^4.0.1" 434 | }, 435 | "engines": { 436 | "node": ">= 14" 437 | } 438 | }, 439 | "node_modules/delayed-stream": { 440 | "version": "1.0.0", 441 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 442 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 443 | "license": "MIT", 444 | "engines": { 445 | "node": ">=0.4.0" 446 | } 447 | }, 448 | "node_modules/depd": { 449 | "version": "2.0.0", 450 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 451 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 452 | "license": "MIT", 453 | "engines": { 454 | "node": ">= 0.8" 455 | } 456 | }, 457 | "node_modules/devtools-protocol": { 458 | "version": "0.0.1367902", 459 | "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1367902.tgz", 460 | "integrity": "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg==", 461 | "license": "BSD-3-Clause" 462 | }, 463 | "node_modules/emoji-regex": { 464 | "version": "8.0.0", 465 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 466 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 467 | "license": "MIT" 468 | }, 469 | "node_modules/end-of-stream": { 470 | "version": "1.4.4", 471 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 472 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 473 | "license": "MIT", 474 | "dependencies": { 475 | "once": "^1.4.0" 476 | } 477 | }, 478 | "node_modules/escalade": { 479 | "version": "3.2.0", 480 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 481 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 482 | "license": "MIT", 483 | "engines": { 484 | "node": ">=6" 485 | } 486 | }, 487 | "node_modules/escodegen": { 488 | "version": "2.1.0", 489 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", 490 | "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", 491 | "license": "BSD-2-Clause", 492 | "dependencies": { 493 | "esprima": "^4.0.1", 494 | "estraverse": "^5.2.0", 495 | "esutils": "^2.0.2" 496 | }, 497 | "bin": { 498 | "escodegen": "bin/escodegen.js", 499 | "esgenerate": "bin/esgenerate.js" 500 | }, 501 | "engines": { 502 | "node": ">=6.0" 503 | }, 504 | "optionalDependencies": { 505 | "source-map": "~0.6.1" 506 | } 507 | }, 508 | "node_modules/esprima": { 509 | "version": "4.0.1", 510 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 511 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 512 | "license": "BSD-2-Clause", 513 | "bin": { 514 | "esparse": "bin/esparse.js", 515 | "esvalidate": "bin/esvalidate.js" 516 | }, 517 | "engines": { 518 | "node": ">=4" 519 | } 520 | }, 521 | "node_modules/estraverse": { 522 | "version": "5.3.0", 523 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 524 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 525 | "license": "BSD-2-Clause", 526 | "engines": { 527 | "node": ">=4.0" 528 | } 529 | }, 530 | "node_modules/esutils": { 531 | "version": "2.0.3", 532 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 533 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 534 | "license": "BSD-2-Clause", 535 | "engines": { 536 | "node": ">=0.10.0" 537 | } 538 | }, 539 | "node_modules/event-target-shim": { 540 | "version": "5.0.1", 541 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 542 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", 543 | "license": "MIT", 544 | "engines": { 545 | "node": ">=6" 546 | } 547 | }, 548 | "node_modules/extract-zip": { 549 | "version": "2.0.1", 550 | "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", 551 | "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", 552 | "license": "BSD-2-Clause", 553 | "dependencies": { 554 | "debug": "^4.1.1", 555 | "get-stream": "^5.1.0", 556 | "yauzl": "^2.10.0" 557 | }, 558 | "bin": { 559 | "extract-zip": "cli.js" 560 | }, 561 | "engines": { 562 | "node": ">= 10.17.0" 563 | }, 564 | "optionalDependencies": { 565 | "@types/yauzl": "^2.9.1" 566 | } 567 | }, 568 | "node_modules/fast-fifo": { 569 | "version": "1.3.2", 570 | "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", 571 | "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", 572 | "license": "MIT" 573 | }, 574 | "node_modules/fd-slicer": { 575 | "version": "1.1.0", 576 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", 577 | "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", 578 | "license": "MIT", 579 | "dependencies": { 580 | "pend": "~1.2.0" 581 | } 582 | }, 583 | "node_modules/form-data": { 584 | "version": "4.0.1", 585 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", 586 | "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", 587 | "license": "MIT", 588 | "dependencies": { 589 | "asynckit": "^0.4.0", 590 | "combined-stream": "^1.0.8", 591 | "mime-types": "^2.1.12" 592 | }, 593 | "engines": { 594 | "node": ">= 6" 595 | } 596 | }, 597 | "node_modules/form-data-encoder": { 598 | "version": "1.7.2", 599 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", 600 | "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", 601 | "license": "MIT" 602 | }, 603 | "node_modules/formdata-node": { 604 | "version": "4.4.1", 605 | "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", 606 | "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", 607 | "license": "MIT", 608 | "dependencies": { 609 | "node-domexception": "1.0.0", 610 | "web-streams-polyfill": "4.0.0-beta.3" 611 | }, 612 | "engines": { 613 | "node": ">= 12.20" 614 | } 615 | }, 616 | "node_modules/fs.realpath": { 617 | "version": "1.0.0", 618 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 619 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 620 | "dev": true, 621 | "license": "ISC" 622 | }, 623 | "node_modules/function-bind": { 624 | "version": "1.1.2", 625 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 626 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 627 | "dev": true, 628 | "license": "MIT", 629 | "funding": { 630 | "url": "https://github.com/sponsors/ljharb" 631 | } 632 | }, 633 | "node_modules/get-caller-file": { 634 | "version": "2.0.5", 635 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 636 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 637 | "license": "ISC", 638 | "engines": { 639 | "node": "6.* || 8.* || >= 10.*" 640 | } 641 | }, 642 | "node_modules/get-stream": { 643 | "version": "5.2.0", 644 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 645 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 646 | "license": "MIT", 647 | "dependencies": { 648 | "pump": "^3.0.0" 649 | }, 650 | "engines": { 651 | "node": ">=8" 652 | }, 653 | "funding": { 654 | "url": "https://github.com/sponsors/sindresorhus" 655 | } 656 | }, 657 | "node_modules/get-uri": { 658 | "version": "6.0.4", 659 | "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", 660 | "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", 661 | "license": "MIT", 662 | "dependencies": { 663 | "basic-ftp": "^5.0.2", 664 | "data-uri-to-buffer": "^6.0.2", 665 | "debug": "^4.3.4" 666 | }, 667 | "engines": { 668 | "node": ">= 14" 669 | } 670 | }, 671 | "node_modules/glob": { 672 | "version": "7.2.3", 673 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 674 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 675 | "deprecated": "Glob versions prior to v9 are no longer supported", 676 | "dev": true, 677 | "license": "ISC", 678 | "dependencies": { 679 | "fs.realpath": "^1.0.0", 680 | "inflight": "^1.0.4", 681 | "inherits": "2", 682 | "minimatch": "^3.1.1", 683 | "once": "^1.3.0", 684 | "path-is-absolute": "^1.0.0" 685 | }, 686 | "engines": { 687 | "node": "*" 688 | }, 689 | "funding": { 690 | "url": "https://github.com/sponsors/isaacs" 691 | } 692 | }, 693 | "node_modules/hasown": { 694 | "version": "2.0.2", 695 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 696 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 697 | "dev": true, 698 | "license": "MIT", 699 | "dependencies": { 700 | "function-bind": "^1.1.2" 701 | }, 702 | "engines": { 703 | "node": ">= 0.4" 704 | } 705 | }, 706 | "node_modules/http-errors": { 707 | "version": "2.0.0", 708 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 709 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 710 | "license": "MIT", 711 | "dependencies": { 712 | "depd": "2.0.0", 713 | "inherits": "2.0.4", 714 | "setprototypeof": "1.2.0", 715 | "statuses": "2.0.1", 716 | "toidentifier": "1.0.1" 717 | }, 718 | "engines": { 719 | "node": ">= 0.8" 720 | } 721 | }, 722 | "node_modules/http-proxy-agent": { 723 | "version": "7.0.2", 724 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", 725 | "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", 726 | "license": "MIT", 727 | "dependencies": { 728 | "agent-base": "^7.1.0", 729 | "debug": "^4.3.4" 730 | }, 731 | "engines": { 732 | "node": ">= 14" 733 | } 734 | }, 735 | "node_modules/https-proxy-agent": { 736 | "version": "7.0.5", 737 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", 738 | "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", 739 | "license": "MIT", 740 | "dependencies": { 741 | "agent-base": "^7.0.2", 742 | "debug": "4" 743 | }, 744 | "engines": { 745 | "node": ">= 14" 746 | } 747 | }, 748 | "node_modules/humanize-ms": { 749 | "version": "1.2.1", 750 | "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", 751 | "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", 752 | "license": "MIT", 753 | "dependencies": { 754 | "ms": "^2.0.0" 755 | } 756 | }, 757 | "node_modules/iconv-lite": { 758 | "version": "0.6.3", 759 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 760 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 761 | "license": "MIT", 762 | "dependencies": { 763 | "safer-buffer": ">= 2.1.2 < 3.0.0" 764 | }, 765 | "engines": { 766 | "node": ">=0.10.0" 767 | } 768 | }, 769 | "node_modules/ieee754": { 770 | "version": "1.2.1", 771 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 772 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 773 | "funding": [ 774 | { 775 | "type": "github", 776 | "url": "https://github.com/sponsors/feross" 777 | }, 778 | { 779 | "type": "patreon", 780 | "url": "https://www.patreon.com/feross" 781 | }, 782 | { 783 | "type": "consulting", 784 | "url": "https://feross.org/support" 785 | } 786 | ], 787 | "license": "BSD-3-Clause" 788 | }, 789 | "node_modules/inflight": { 790 | "version": "1.0.6", 791 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 792 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 793 | "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", 794 | "dev": true, 795 | "license": "ISC", 796 | "dependencies": { 797 | "once": "^1.3.0", 798 | "wrappy": "1" 799 | } 800 | }, 801 | "node_modules/inherits": { 802 | "version": "2.0.4", 803 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 804 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 805 | "license": "ISC" 806 | }, 807 | "node_modules/interpret": { 808 | "version": "1.4.0", 809 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", 810 | "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", 811 | "dev": true, 812 | "license": "MIT", 813 | "engines": { 814 | "node": ">= 0.10" 815 | } 816 | }, 817 | "node_modules/ip-address": { 818 | "version": "9.0.5", 819 | "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", 820 | "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", 821 | "license": "MIT", 822 | "dependencies": { 823 | "jsbn": "1.1.0", 824 | "sprintf-js": "^1.1.3" 825 | }, 826 | "engines": { 827 | "node": ">= 12" 828 | } 829 | }, 830 | "node_modules/is-core-module": { 831 | "version": "2.15.1", 832 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", 833 | "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", 834 | "dev": true, 835 | "license": "MIT", 836 | "dependencies": { 837 | "hasown": "^2.0.2" 838 | }, 839 | "engines": { 840 | "node": ">= 0.4" 841 | }, 842 | "funding": { 843 | "url": "https://github.com/sponsors/ljharb" 844 | } 845 | }, 846 | "node_modules/is-fullwidth-code-point": { 847 | "version": "3.0.0", 848 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 849 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 850 | "license": "MIT", 851 | "engines": { 852 | "node": ">=8" 853 | } 854 | }, 855 | "node_modules/jsbn": { 856 | "version": "1.1.0", 857 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", 858 | "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", 859 | "license": "MIT" 860 | }, 861 | "node_modules/lru-cache": { 862 | "version": "7.18.3", 863 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", 864 | "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", 865 | "license": "ISC", 866 | "engines": { 867 | "node": ">=12" 868 | } 869 | }, 870 | "node_modules/mime-db": { 871 | "version": "1.52.0", 872 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 873 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 874 | "license": "MIT", 875 | "engines": { 876 | "node": ">= 0.6" 877 | } 878 | }, 879 | "node_modules/mime-types": { 880 | "version": "2.1.35", 881 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 882 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 883 | "license": "MIT", 884 | "dependencies": { 885 | "mime-db": "1.52.0" 886 | }, 887 | "engines": { 888 | "node": ">= 0.6" 889 | } 890 | }, 891 | "node_modules/minimatch": { 892 | "version": "3.1.2", 893 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 894 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 895 | "dev": true, 896 | "license": "ISC", 897 | "dependencies": { 898 | "brace-expansion": "^1.1.7" 899 | }, 900 | "engines": { 901 | "node": "*" 902 | } 903 | }, 904 | "node_modules/minimist": { 905 | "version": "1.2.8", 906 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 907 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 908 | "dev": true, 909 | "license": "MIT", 910 | "funding": { 911 | "url": "https://github.com/sponsors/ljharb" 912 | } 913 | }, 914 | "node_modules/mitt": { 915 | "version": "3.0.1", 916 | "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", 917 | "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", 918 | "license": "MIT" 919 | }, 920 | "node_modules/ms": { 921 | "version": "2.1.3", 922 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 923 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 924 | "license": "MIT" 925 | }, 926 | "node_modules/netmask": { 927 | "version": "2.0.2", 928 | "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", 929 | "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", 930 | "license": "MIT", 931 | "engines": { 932 | "node": ">= 0.4.0" 933 | } 934 | }, 935 | "node_modules/node-domexception": { 936 | "version": "1.0.0", 937 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", 938 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", 939 | "funding": [ 940 | { 941 | "type": "github", 942 | "url": "https://github.com/sponsors/jimmywarting" 943 | }, 944 | { 945 | "type": "github", 946 | "url": "https://paypal.me/jimmywarting" 947 | } 948 | ], 949 | "license": "MIT", 950 | "engines": { 951 | "node": ">=10.5.0" 952 | } 953 | }, 954 | "node_modules/node-fetch": { 955 | "version": "2.7.0", 956 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 957 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 958 | "license": "MIT", 959 | "dependencies": { 960 | "whatwg-url": "^5.0.0" 961 | }, 962 | "engines": { 963 | "node": "4.x || >=6.0.0" 964 | }, 965 | "peerDependencies": { 966 | "encoding": "^0.1.0" 967 | }, 968 | "peerDependenciesMeta": { 969 | "encoding": { 970 | "optional": true 971 | } 972 | } 973 | }, 974 | "node_modules/once": { 975 | "version": "1.4.0", 976 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 977 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 978 | "license": "ISC", 979 | "dependencies": { 980 | "wrappy": "1" 981 | } 982 | }, 983 | "node_modules/pac-proxy-agent": { 984 | "version": "7.0.2", 985 | "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", 986 | "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", 987 | "license": "MIT", 988 | "dependencies": { 989 | "@tootallnate/quickjs-emscripten": "^0.23.0", 990 | "agent-base": "^7.0.2", 991 | "debug": "^4.3.4", 992 | "get-uri": "^6.0.1", 993 | "http-proxy-agent": "^7.0.0", 994 | "https-proxy-agent": "^7.0.5", 995 | "pac-resolver": "^7.0.1", 996 | "socks-proxy-agent": "^8.0.4" 997 | }, 998 | "engines": { 999 | "node": ">= 14" 1000 | } 1001 | }, 1002 | "node_modules/pac-resolver": { 1003 | "version": "7.0.1", 1004 | "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", 1005 | "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", 1006 | "license": "MIT", 1007 | "dependencies": { 1008 | "degenerator": "^5.0.0", 1009 | "netmask": "^2.0.2" 1010 | }, 1011 | "engines": { 1012 | "node": ">= 14" 1013 | } 1014 | }, 1015 | "node_modules/path-is-absolute": { 1016 | "version": "1.0.1", 1017 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1018 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1019 | "dev": true, 1020 | "license": "MIT", 1021 | "engines": { 1022 | "node": ">=0.10.0" 1023 | } 1024 | }, 1025 | "node_modules/path-parse": { 1026 | "version": "1.0.7", 1027 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1028 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1029 | "dev": true, 1030 | "license": "MIT" 1031 | }, 1032 | "node_modules/pend": { 1033 | "version": "1.2.0", 1034 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 1035 | "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", 1036 | "license": "MIT" 1037 | }, 1038 | "node_modules/progress": { 1039 | "version": "2.0.3", 1040 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 1041 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 1042 | "license": "MIT", 1043 | "engines": { 1044 | "node": ">=0.4.0" 1045 | } 1046 | }, 1047 | "node_modules/proxy-agent": { 1048 | "version": "6.4.0", 1049 | "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", 1050 | "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", 1051 | "license": "MIT", 1052 | "dependencies": { 1053 | "agent-base": "^7.0.2", 1054 | "debug": "^4.3.4", 1055 | "http-proxy-agent": "^7.0.1", 1056 | "https-proxy-agent": "^7.0.3", 1057 | "lru-cache": "^7.14.1", 1058 | "pac-proxy-agent": "^7.0.1", 1059 | "proxy-from-env": "^1.1.0", 1060 | "socks-proxy-agent": "^8.0.2" 1061 | }, 1062 | "engines": { 1063 | "node": ">= 14" 1064 | } 1065 | }, 1066 | "node_modules/proxy-from-env": { 1067 | "version": "1.1.0", 1068 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 1069 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", 1070 | "license": "MIT" 1071 | }, 1072 | "node_modules/pump": { 1073 | "version": "3.0.2", 1074 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", 1075 | "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", 1076 | "license": "MIT", 1077 | "dependencies": { 1078 | "end-of-stream": "^1.1.0", 1079 | "once": "^1.3.1" 1080 | } 1081 | }, 1082 | "node_modules/puppeteer-core": { 1083 | "version": "23.10.0", 1084 | "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.10.0.tgz", 1085 | "integrity": "sha512-7pv6kFget4Iki0RLBDowi35vaccz73XpC6/FAnfCrYa2IXVUlBHfZw+HGWzlvvTGwM9HHd32rgCrIDzil3kj+w==", 1086 | "license": "Apache-2.0", 1087 | "dependencies": { 1088 | "@puppeteer/browsers": "2.5.0", 1089 | "chromium-bidi": "0.8.0", 1090 | "debug": "^4.3.7", 1091 | "devtools-protocol": "0.0.1367902", 1092 | "typed-query-selector": "^2.12.0", 1093 | "ws": "^8.18.0" 1094 | }, 1095 | "engines": { 1096 | "node": ">=18" 1097 | } 1098 | }, 1099 | "node_modules/queue-tick": { 1100 | "version": "1.0.1", 1101 | "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", 1102 | "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", 1103 | "license": "MIT" 1104 | }, 1105 | "node_modules/raw-body": { 1106 | "version": "3.0.0", 1107 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 1108 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 1109 | "license": "MIT", 1110 | "dependencies": { 1111 | "bytes": "3.1.2", 1112 | "http-errors": "2.0.0", 1113 | "iconv-lite": "0.6.3", 1114 | "unpipe": "1.0.0" 1115 | }, 1116 | "engines": { 1117 | "node": ">= 0.8" 1118 | } 1119 | }, 1120 | "node_modules/rechoir": { 1121 | "version": "0.6.2", 1122 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 1123 | "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", 1124 | "dev": true, 1125 | "dependencies": { 1126 | "resolve": "^1.1.6" 1127 | }, 1128 | "engines": { 1129 | "node": ">= 0.10" 1130 | } 1131 | }, 1132 | "node_modules/require-directory": { 1133 | "version": "2.1.1", 1134 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1135 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 1136 | "license": "MIT", 1137 | "engines": { 1138 | "node": ">=0.10.0" 1139 | } 1140 | }, 1141 | "node_modules/resolve": { 1142 | "version": "1.22.8", 1143 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", 1144 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", 1145 | "dev": true, 1146 | "license": "MIT", 1147 | "dependencies": { 1148 | "is-core-module": "^2.13.0", 1149 | "path-parse": "^1.0.7", 1150 | "supports-preserve-symlinks-flag": "^1.0.0" 1151 | }, 1152 | "bin": { 1153 | "resolve": "bin/resolve" 1154 | }, 1155 | "funding": { 1156 | "url": "https://github.com/sponsors/ljharb" 1157 | } 1158 | }, 1159 | "node_modules/safer-buffer": { 1160 | "version": "2.1.2", 1161 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1162 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1163 | "license": "MIT" 1164 | }, 1165 | "node_modules/semver": { 1166 | "version": "7.6.3", 1167 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", 1168 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", 1169 | "license": "ISC", 1170 | "bin": { 1171 | "semver": "bin/semver.js" 1172 | }, 1173 | "engines": { 1174 | "node": ">=10" 1175 | } 1176 | }, 1177 | "node_modules/setprototypeof": { 1178 | "version": "1.2.0", 1179 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1180 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 1181 | "license": "ISC" 1182 | }, 1183 | "node_modules/shelljs": { 1184 | "version": "0.8.5", 1185 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", 1186 | "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", 1187 | "dev": true, 1188 | "license": "BSD-3-Clause", 1189 | "dependencies": { 1190 | "glob": "^7.0.0", 1191 | "interpret": "^1.0.0", 1192 | "rechoir": "^0.6.2" 1193 | }, 1194 | "bin": { 1195 | "shjs": "bin/shjs" 1196 | }, 1197 | "engines": { 1198 | "node": ">=4" 1199 | } 1200 | }, 1201 | "node_modules/shx": { 1202 | "version": "0.3.4", 1203 | "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", 1204 | "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", 1205 | "dev": true, 1206 | "license": "MIT", 1207 | "dependencies": { 1208 | "minimist": "^1.2.3", 1209 | "shelljs": "^0.8.5" 1210 | }, 1211 | "bin": { 1212 | "shx": "lib/cli.js" 1213 | }, 1214 | "engines": { 1215 | "node": ">=6" 1216 | } 1217 | }, 1218 | "node_modules/smart-buffer": { 1219 | "version": "4.2.0", 1220 | "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", 1221 | "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", 1222 | "license": "MIT", 1223 | "engines": { 1224 | "node": ">= 6.0.0", 1225 | "npm": ">= 3.0.0" 1226 | } 1227 | }, 1228 | "node_modules/socks": { 1229 | "version": "2.8.3", 1230 | "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", 1231 | "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", 1232 | "license": "MIT", 1233 | "dependencies": { 1234 | "ip-address": "^9.0.5", 1235 | "smart-buffer": "^4.2.0" 1236 | }, 1237 | "engines": { 1238 | "node": ">= 10.0.0", 1239 | "npm": ">= 3.0.0" 1240 | } 1241 | }, 1242 | "node_modules/socks-proxy-agent": { 1243 | "version": "8.0.4", 1244 | "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", 1245 | "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", 1246 | "license": "MIT", 1247 | "dependencies": { 1248 | "agent-base": "^7.1.1", 1249 | "debug": "^4.3.4", 1250 | "socks": "^2.8.3" 1251 | }, 1252 | "engines": { 1253 | "node": ">= 14" 1254 | } 1255 | }, 1256 | "node_modules/source-map": { 1257 | "version": "0.6.1", 1258 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1259 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1260 | "license": "BSD-3-Clause", 1261 | "optional": true, 1262 | "engines": { 1263 | "node": ">=0.10.0" 1264 | } 1265 | }, 1266 | "node_modules/sprintf-js": { 1267 | "version": "1.1.3", 1268 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", 1269 | "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", 1270 | "license": "BSD-3-Clause" 1271 | }, 1272 | "node_modules/statuses": { 1273 | "version": "2.0.1", 1274 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1275 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1276 | "license": "MIT", 1277 | "engines": { 1278 | "node": ">= 0.8" 1279 | } 1280 | }, 1281 | "node_modules/streamx": { 1282 | "version": "2.21.0", 1283 | "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.0.tgz", 1284 | "integrity": "sha512-Qz6MsDZXJ6ur9u+b+4xCG18TluU7PGlRfXVAAjNiGsFrBUt/ioyLkxbFaKJygoPs+/kW4VyBj0bSj89Qu0IGyg==", 1285 | "license": "MIT", 1286 | "dependencies": { 1287 | "fast-fifo": "^1.3.2", 1288 | "queue-tick": "^1.0.1", 1289 | "text-decoder": "^1.1.0" 1290 | }, 1291 | "optionalDependencies": { 1292 | "bare-events": "^2.2.0" 1293 | } 1294 | }, 1295 | "node_modules/string-width": { 1296 | "version": "4.2.3", 1297 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1298 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1299 | "license": "MIT", 1300 | "dependencies": { 1301 | "emoji-regex": "^8.0.0", 1302 | "is-fullwidth-code-point": "^3.0.0", 1303 | "strip-ansi": "^6.0.1" 1304 | }, 1305 | "engines": { 1306 | "node": ">=8" 1307 | } 1308 | }, 1309 | "node_modules/strip-ansi": { 1310 | "version": "6.0.1", 1311 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1312 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1313 | "license": "MIT", 1314 | "dependencies": { 1315 | "ansi-regex": "^5.0.1" 1316 | }, 1317 | "engines": { 1318 | "node": ">=8" 1319 | } 1320 | }, 1321 | "node_modules/supports-preserve-symlinks-flag": { 1322 | "version": "1.0.0", 1323 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1324 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1325 | "dev": true, 1326 | "license": "MIT", 1327 | "engines": { 1328 | "node": ">= 0.4" 1329 | }, 1330 | "funding": { 1331 | "url": "https://github.com/sponsors/ljharb" 1332 | } 1333 | }, 1334 | "node_modules/tar-fs": { 1335 | "version": "3.0.6", 1336 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", 1337 | "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", 1338 | "license": "MIT", 1339 | "dependencies": { 1340 | "pump": "^3.0.0", 1341 | "tar-stream": "^3.1.5" 1342 | }, 1343 | "optionalDependencies": { 1344 | "bare-fs": "^2.1.1", 1345 | "bare-path": "^2.1.0" 1346 | } 1347 | }, 1348 | "node_modules/tar-stream": { 1349 | "version": "3.1.7", 1350 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", 1351 | "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", 1352 | "license": "MIT", 1353 | "dependencies": { 1354 | "b4a": "^1.6.4", 1355 | "fast-fifo": "^1.2.0", 1356 | "streamx": "^2.15.0" 1357 | } 1358 | }, 1359 | "node_modules/text-decoder": { 1360 | "version": "1.2.1", 1361 | "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", 1362 | "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", 1363 | "license": "Apache-2.0" 1364 | }, 1365 | "node_modules/through": { 1366 | "version": "2.3.8", 1367 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1368 | "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", 1369 | "license": "MIT" 1370 | }, 1371 | "node_modules/toidentifier": { 1372 | "version": "1.0.1", 1373 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1374 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 1375 | "license": "MIT", 1376 | "engines": { 1377 | "node": ">=0.6" 1378 | } 1379 | }, 1380 | "node_modules/tr46": { 1381 | "version": "0.0.3", 1382 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 1383 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", 1384 | "license": "MIT" 1385 | }, 1386 | "node_modules/tslib": { 1387 | "version": "2.8.1", 1388 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 1389 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", 1390 | "license": "0BSD" 1391 | }, 1392 | "node_modules/typed-query-selector": { 1393 | "version": "2.12.0", 1394 | "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", 1395 | "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", 1396 | "license": "MIT" 1397 | }, 1398 | "node_modules/typescript": { 1399 | "version": "5.7.2", 1400 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", 1401 | "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", 1402 | "dev": true, 1403 | "license": "Apache-2.0", 1404 | "bin": { 1405 | "tsc": "bin/tsc", 1406 | "tsserver": "bin/tsserver" 1407 | }, 1408 | "engines": { 1409 | "node": ">=14.17" 1410 | } 1411 | }, 1412 | "node_modules/unbzip2-stream": { 1413 | "version": "1.4.3", 1414 | "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", 1415 | "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", 1416 | "license": "MIT", 1417 | "dependencies": { 1418 | "buffer": "^5.2.1", 1419 | "through": "^2.3.8" 1420 | } 1421 | }, 1422 | "node_modules/undici-types": { 1423 | "version": "5.26.5", 1424 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 1425 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 1426 | "license": "MIT" 1427 | }, 1428 | "node_modules/unpipe": { 1429 | "version": "1.0.0", 1430 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1431 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 1432 | "license": "MIT", 1433 | "engines": { 1434 | "node": ">= 0.8" 1435 | } 1436 | }, 1437 | "node_modules/urlpattern-polyfill": { 1438 | "version": "10.0.0", 1439 | "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", 1440 | "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", 1441 | "license": "MIT" 1442 | }, 1443 | "node_modules/web-streams-polyfill": { 1444 | "version": "4.0.0-beta.3", 1445 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", 1446 | "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", 1447 | "license": "MIT", 1448 | "engines": { 1449 | "node": ">= 14" 1450 | } 1451 | }, 1452 | "node_modules/webidl-conversions": { 1453 | "version": "3.0.1", 1454 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 1455 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", 1456 | "license": "BSD-2-Clause" 1457 | }, 1458 | "node_modules/whatwg-url": { 1459 | "version": "5.0.0", 1460 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 1461 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 1462 | "license": "MIT", 1463 | "dependencies": { 1464 | "tr46": "~0.0.3", 1465 | "webidl-conversions": "^3.0.0" 1466 | } 1467 | }, 1468 | "node_modules/wrap-ansi": { 1469 | "version": "7.0.0", 1470 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 1471 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 1472 | "license": "MIT", 1473 | "dependencies": { 1474 | "ansi-styles": "^4.0.0", 1475 | "string-width": "^4.1.0", 1476 | "strip-ansi": "^6.0.0" 1477 | }, 1478 | "engines": { 1479 | "node": ">=10" 1480 | }, 1481 | "funding": { 1482 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 1483 | } 1484 | }, 1485 | "node_modules/wrappy": { 1486 | "version": "1.0.2", 1487 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1488 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1489 | "license": "ISC" 1490 | }, 1491 | "node_modules/ws": { 1492 | "version": "8.18.0", 1493 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", 1494 | "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", 1495 | "license": "MIT", 1496 | "engines": { 1497 | "node": ">=10.0.0" 1498 | }, 1499 | "peerDependencies": { 1500 | "bufferutil": "^4.0.1", 1501 | "utf-8-validate": ">=5.0.2" 1502 | }, 1503 | "peerDependenciesMeta": { 1504 | "bufferutil": { 1505 | "optional": true 1506 | }, 1507 | "utf-8-validate": { 1508 | "optional": true 1509 | } 1510 | } 1511 | }, 1512 | "node_modules/y18n": { 1513 | "version": "5.0.8", 1514 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 1515 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 1516 | "license": "ISC", 1517 | "engines": { 1518 | "node": ">=10" 1519 | } 1520 | }, 1521 | "node_modules/yargs": { 1522 | "version": "17.7.2", 1523 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", 1524 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", 1525 | "license": "MIT", 1526 | "dependencies": { 1527 | "cliui": "^8.0.1", 1528 | "escalade": "^3.1.1", 1529 | "get-caller-file": "^2.0.5", 1530 | "require-directory": "^2.1.1", 1531 | "string-width": "^4.2.3", 1532 | "y18n": "^5.0.5", 1533 | "yargs-parser": "^21.1.1" 1534 | }, 1535 | "engines": { 1536 | "node": ">=12" 1537 | } 1538 | }, 1539 | "node_modules/yargs-parser": { 1540 | "version": "21.1.1", 1541 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 1542 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", 1543 | "license": "ISC", 1544 | "engines": { 1545 | "node": ">=12" 1546 | } 1547 | }, 1548 | "node_modules/yauzl": { 1549 | "version": "2.10.0", 1550 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", 1551 | "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", 1552 | "license": "MIT", 1553 | "dependencies": { 1554 | "buffer-crc32": "~0.2.3", 1555 | "fd-slicer": "~1.1.0" 1556 | } 1557 | }, 1558 | "node_modules/zod": { 1559 | "version": "3.23.8", 1560 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", 1561 | "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", 1562 | "license": "MIT", 1563 | "funding": { 1564 | "url": "https://github.com/sponsors/colinhacks" 1565 | } 1566 | } 1567 | } 1568 | } 1569 | -------------------------------------------------------------------------------- /browserbase/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@browserbasehq/mcp-browserbase", 3 | "version": "0.5.1", 4 | "description": "MCP server for browser automation using browserbase", 5 | "license": "MIT", 6 | "author": "Anthropic, PBC (https://anthropic.com)", 7 | "homepage": "https://modelcontextprotocol.io", 8 | "bugs": "https://github.com/modelcontextprotocol/servers/issues", 9 | "type": "module", 10 | "bin": { 11 | "mcp-server-browserbase": "dist/index.js" 12 | }, 13 | "files": [ 14 | "dist" 15 | ], 16 | "scripts": { 17 | "build": "tsc && shx chmod +x dist/*.js", 18 | "prepare": "npm run build", 19 | "watch": "tsc --watch", 20 | "inspector": "npx @modelcontextprotocol/inspector build/index.js" 21 | }, 22 | "dependencies": { 23 | "@browserbasehq/sdk": "^2.0.0", 24 | "@modelcontextprotocol/sdk": "^1.0.3", 25 | "puppeteer-core": "^23.9.0" 26 | }, 27 | "devDependencies": { 28 | "shx": "^0.3.4", 29 | "typescript": "^5.6.2" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /browserbase/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 4 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 5 | import { 6 | CallToolRequestSchema, 7 | ListResourcesRequestSchema, 8 | ListToolsRequestSchema, 9 | ReadResourceRequestSchema, 10 | CallToolResult, 11 | TextContent, 12 | ImageContent, 13 | Tool, 14 | } from "@modelcontextprotocol/sdk/types.js"; 15 | import puppeteer, { Browser, Page } from "puppeteer-core"; 16 | import { Browserbase } from "@browserbasehq/sdk"; 17 | 18 | // Environment variables configuration 19 | const requiredEnvVars = { 20 | BROWSERBASE_API_KEY: process.env.BROWSERBASE_API_KEY, 21 | BROWSERBASE_PROJECT_ID: process.env.BROWSERBASE_PROJECT_ID, 22 | }; 23 | 24 | // Validate required environment variables 25 | Object.entries(requiredEnvVars).forEach(([name, value]) => { 26 | if (!value) throw new Error(`${name} environment variable is required`); 27 | }); 28 | 29 | // 2. Global State 30 | const browsers = new Map(); 31 | const screenshots = new Map(); 32 | 33 | // Global state variable for the default browser session 34 | let defaultBrowserSession: { browser: Browser; page: Page } | null = null; 35 | const sessionId = "default"; // Using a consistent session ID for the default session 36 | 37 | // Ensure browser session is initialized and valid 38 | async function ensureBrowserSession(): Promise<{ 39 | browser: Browser; 40 | page: Page; 41 | }> { 42 | try { 43 | // If no session exists, create one 44 | if (!defaultBrowserSession) { 45 | defaultBrowserSession = await createNewBrowserSession(sessionId); 46 | return defaultBrowserSession; 47 | } 48 | 49 | // Try to perform a simple operation to check if the session is still valid 50 | try { 51 | await defaultBrowserSession.page.evaluate(() => document.title); 52 | return defaultBrowserSession; 53 | } catch (error) { 54 | // If we get an error indicating the session is invalid, reinitialize 55 | if ( 56 | error instanceof Error && 57 | (error.message.includes( 58 | "Target page, context or browser has been closed" 59 | ) || 60 | error.message.includes("Session expired") || 61 | error.message.includes("context destroyed") || 62 | error.message.includes("Protocol error") || 63 | error.message.includes("detached") || 64 | error.message.includes("Attempted to use detached Frame")) 65 | ) { 66 | // Force cleanup of all sessions 67 | try { 68 | // Try to close the session if it's still accessible 69 | if (defaultBrowserSession) { 70 | try { 71 | await defaultBrowserSession.browser.close(); 72 | } catch (e) { 73 | // Ignore errors when closing an already closed browser 74 | } 75 | } 76 | // Clean up all existing browser sessions 77 | for (const [id, sessionObj] of browsers.entries()) { 78 | try { 79 | await sessionObj.browser.close(); 80 | } catch { 81 | // Ignore errors when closing 82 | } 83 | browsers.delete(id); 84 | } 85 | } catch { 86 | // Continue with reset even if cleanup fails 87 | } 88 | 89 | // Reset state 90 | browsers.clear(); 91 | defaultBrowserSession = null; 92 | 93 | // Create a completely new session with delay to allow system to clean up 94 | await new Promise((resolve) => setTimeout(resolve, 1000)); 95 | defaultBrowserSession = await createNewBrowserSession(sessionId); 96 | return defaultBrowserSession; 97 | } 98 | throw error; // Re-throw if it's a different type of error 99 | } 100 | } catch (error) { 101 | // If we still have a detached frame error after the first attempt, try a more aggressive approach 102 | if ( 103 | error instanceof Error && 104 | (error.message.includes("detached") || 105 | error.message.includes("Attempted to use detached Frame")) 106 | ) { 107 | try { 108 | // Force cleanup 109 | browsers.clear(); 110 | defaultBrowserSession = null; 111 | 112 | // Wait a bit longer to ensure resources are released 113 | await new Promise((resolve) => setTimeout(resolve, 2000)); 114 | 115 | // Create a completely fresh connection 116 | defaultBrowserSession = await createNewBrowserSession( 117 | `fresh_${Date.now()}` 118 | ); 119 | return defaultBrowserSession; 120 | } catch (retryError) { 121 | throw retryError; 122 | } 123 | } 124 | throw error; 125 | } 126 | } 127 | 128 | // 3. Helper Functions 129 | async function createNewBrowserSession(sessionId: string) { 130 | const bb = new Browserbase({ 131 | apiKey: process.env.BROWSERBASE_API_KEY!, 132 | }); 133 | const session = await bb.sessions.create({ 134 | projectId: process.env.BROWSERBASE_PROJECT_ID!, 135 | }); 136 | const browser = await puppeteer.connect({ 137 | browserWSEndpoint: session.connectUrl, 138 | }); 139 | 140 | const page = (await browser.pages())[0]; 141 | browsers.set(sessionId, { browser, page }); 142 | 143 | return { browser, page }; 144 | } 145 | 146 | // 4. Tool Definitions 147 | const TOOLS: Tool[] = [ 148 | { 149 | name: "browserbase_create_session", 150 | description: "Create a new cloud browser session using Browserbase", 151 | inputSchema: { 152 | type: "object", 153 | properties: {}, 154 | required: [], 155 | }, 156 | }, 157 | { 158 | name: "browserbase_navigate", 159 | description: "Navigate to a URL", 160 | inputSchema: { 161 | type: "object", 162 | properties: { 163 | url: { type: "string" }, 164 | }, 165 | required: ["url"], 166 | }, 167 | }, 168 | { 169 | name: "browserbase_screenshot", 170 | description: "Takes a screenshot of the current page. Use this tool to learn where you are on the page when controlling the browser with Stagehand. Only use this tool when the other tools are not sufficient to get the information you need.", 171 | inputSchema: { 172 | type: "object", 173 | properties: {}, 174 | }, 175 | }, 176 | { 177 | name: "browserbase_click", 178 | description: "Click an element on the page", 179 | inputSchema: { 180 | type: "object", 181 | properties: { 182 | selector: { 183 | type: "string", 184 | description: "CSS selector for element to click", 185 | }, 186 | }, 187 | required: ["selector"], 188 | }, 189 | }, 190 | { 191 | name: "browserbase_fill", 192 | description: "Fill out an input field", 193 | inputSchema: { 194 | type: "object", 195 | properties: { 196 | selector: { 197 | type: "string", 198 | description: "CSS selector for input field", 199 | }, 200 | value: { type: "string", description: "Value to fill" }, 201 | }, 202 | required: ["selector", "value"], 203 | }, 204 | }, 205 | { 206 | name: "browserbase_get_text", 207 | description: "Extract all text content from the current page", 208 | inputSchema: { 209 | type: "object", 210 | properties: {}, 211 | required: [], 212 | }, 213 | }, 214 | ]; 215 | 216 | // 5. Tool Handler Implementation 217 | async function handleToolCall( 218 | name: string, 219 | args: any 220 | ): Promise { 221 | try { 222 | let session: { browser: Browser; page: Page } | undefined; 223 | 224 | // For tools that don't need a session, skip session check 225 | if (!["browserbase_create_session"].includes(name)) { 226 | // Check if a specific session ID is requested 227 | if (args.sessionId && args.sessionId !== sessionId) { 228 | // Check if the requested session exists 229 | if (!browsers.has(args.sessionId)) { 230 | return { 231 | content: [ 232 | { 233 | type: "text", 234 | text: `Session with ID '${args.sessionId}' does not exist. Please create a session first.`, 235 | }, 236 | ], 237 | isError: true, 238 | }; 239 | } 240 | // Use the specified session 241 | session = browsers.get(args.sessionId); 242 | } else { 243 | // Use or create the default session 244 | session = await ensureBrowserSession(); 245 | } 246 | } 247 | 248 | switch (name) { 249 | case "browserbase_create_session": 250 | try { 251 | // Check if session already exists 252 | if (browsers.has(args.sessionId)) { 253 | return { 254 | content: [ 255 | { 256 | type: "text", 257 | text: "Session already exists", 258 | }, 259 | ], 260 | isError: false, 261 | }; 262 | } 263 | await createNewBrowserSession(args.sessionId); 264 | return { 265 | content: [ 266 | { 267 | type: "text", 268 | text: "Created new browser session", 269 | }, 270 | ], 271 | isError: false, 272 | }; 273 | } catch (error) { 274 | return { 275 | content: [ 276 | { 277 | type: "text", 278 | text: `Failed to create browser session: ${ 279 | (error as Error).message 280 | }`, 281 | }, 282 | ], 283 | isError: true, 284 | }; 285 | } 286 | case "browserbase_navigate": 287 | await session!.page.goto(args.url); 288 | return { 289 | content: [ 290 | { 291 | type: "text", 292 | text: `Navigated to ${args.url}`, 293 | }, 294 | ], 295 | isError: false, 296 | }; 297 | 298 | case "browserbase_screenshot": { 299 | 300 | const screenshot = await session!.page.screenshot({ 301 | encoding: "base64", 302 | fullPage: false, 303 | 304 | }); 305 | 306 | if (!screenshot) { 307 | return { 308 | content: [ 309 | { 310 | type: "text", 311 | text: "Screenshot failed", 312 | }, 313 | ], 314 | isError: true, 315 | }; 316 | } 317 | 318 | screenshots.set(args.name, screenshot as string); 319 | server.notification({ 320 | method: "notifications/resources/list_changed", 321 | }); 322 | 323 | return { 324 | content: [ 325 | { 326 | type: "text", 327 | text: `Screenshot taken`, 328 | } as TextContent, 329 | { 330 | type: "image", 331 | data: screenshot, 332 | mimeType: "image/png", 333 | } as ImageContent, 334 | ], 335 | isError: false, 336 | }; 337 | } 338 | 339 | case "browserbase_click": 340 | try { 341 | await session!.page.click(args.selector); 342 | return { 343 | content: [ 344 | { 345 | type: "text", 346 | text: `Clicked: ${args.selector}`, 347 | }, 348 | ], 349 | isError: false, 350 | }; 351 | } catch (error) { 352 | return { 353 | content: [ 354 | { 355 | type: "text", 356 | text: `Failed to click ${args.selector}: ${ 357 | (error as Error).message 358 | }`, 359 | }, 360 | ], 361 | isError: true, 362 | }; 363 | } 364 | 365 | case "browserbase_fill": 366 | try { 367 | await session!.page.waitForSelector(args.selector); 368 | await session!.page.type(args.selector, args.value); 369 | return { 370 | 371 | content: [ 372 | { 373 | type: "text", 374 | text: `Filled ${args.selector} with: ${args.value}`, 375 | }, 376 | ], 377 | isError: false, 378 | 379 | }; 380 | } catch (error) { 381 | return { 382 | content: [ 383 | { 384 | type: "text", 385 | text: `Failed to fill ${args.selector}: ${ 386 | (error as Error).message 387 | }`, 388 | }, 389 | ], 390 | isError: true, 391 | }; 392 | } 393 | 394 | case "browserbase_get_json": 395 | try { 396 | const result = await session!.page.evaluate((selector) => { 397 | // Helper function to find JSON in text 398 | function extractJSON(text: string) { 399 | const jsonObjects = []; 400 | let braceCount = 0; 401 | let start = -1; 402 | 403 | for (let i = 0; i < text.length; i++) { 404 | if (text[i] === "{") { 405 | if (braceCount === 0) start = i; 406 | braceCount++; 407 | } else if (text[i] === "}") { 408 | braceCount--; 409 | if (braceCount === 0 && start !== -1) { 410 | try { 411 | const jsonStr = text.slice(start, i + 1); 412 | const parsed = JSON.parse(jsonStr); 413 | jsonObjects.push(parsed); 414 | } catch (e) { 415 | // Invalid JSON, continue searching 416 | } 417 | } 418 | } 419 | } 420 | return jsonObjects; 421 | } 422 | 423 | // Get all text content based on selector or full page 424 | const elements = selector 425 | ? Array.from(document.querySelectorAll(selector)) 426 | : [document.body]; 427 | 428 | const results = { 429 | // Look for JSON in text content 430 | textContent: elements.flatMap((el) => 431 | extractJSON(el.textContent || "") 432 | ), 433 | 434 | // Look for JSON in script tags 435 | scriptTags: Array.from( 436 | document.getElementsByTagName("script") 437 | ).flatMap((script) => { 438 | try { 439 | if (script.type === "application/json") { 440 | return [JSON.parse(script.textContent || "")]; 441 | } 442 | return extractJSON(script.textContent || ""); 443 | } catch (e) { 444 | return []; 445 | } 446 | }), 447 | 448 | // Look for JSON in meta tags 449 | metaTags: Array.from(document.getElementsByTagName("meta")).flatMap( 450 | (meta) => { 451 | try { 452 | const content = meta.getAttribute("content") || ""; 453 | return extractJSON(content); 454 | } catch (e) { 455 | return []; 456 | } 457 | } 458 | ), 459 | 460 | // Look for JSON-LD 461 | jsonLd: Array.from( 462 | document.querySelectorAll('script[type="application/ld+json"]') 463 | ).flatMap((script) => { 464 | try { 465 | return [JSON.parse(script.textContent || "")]; 466 | } catch (e) { 467 | return []; 468 | } 469 | }), 470 | }; 471 | 472 | return results; 473 | }, args.selector); 474 | 475 | return { 476 | content: [ 477 | { 478 | type: "text", 479 | text: `Found JSON content:\n${JSON.stringify(result, null, 2)}`, 480 | }, 481 | ], 482 | isError: false, 483 | }; 484 | } catch (error) { 485 | return { 486 | content: [ 487 | { 488 | type: "text", 489 | text: `Failed to extract JSON: ${(error as Error).message}`, 490 | }, 491 | ], 492 | isError: true, 493 | }; 494 | } 495 | 496 | case "browserbase_get_text": { 497 | try { 498 | const bodyText = await session!.page.evaluate(() => document.body.innerText); 499 | const content = bodyText 500 | .split('\n') 501 | .map(line => line.trim()) 502 | .filter(line => { 503 | if (!line) return false; 504 | 505 | if ( 506 | (line.includes('{') && line.includes('}')) || 507 | line.includes('@keyframes') || // Remove CSS animations 508 | line.match(/^\.[a-zA-Z0-9_-]+\s*{/) || // Remove CSS lines starting with .className { 509 | line.match(/^[a-zA-Z-]+:[a-zA-Z0-9%\s\(\)\.,-]+;$/) // Remove lines like "color: blue;" or "margin: 10px;" 510 | ) { 511 | return false; 512 | } 513 | return true; 514 | }) 515 | .map(line => { 516 | return line.replace(/\\u([0-9a-fA-F]{4})/g, (_, hex) => 517 | String.fromCharCode(parseInt(hex, 16)) 518 | ); 519 | }); 520 | 521 | return { 522 | content: [ 523 | { 524 | type: "text", 525 | text: `Extracted content:\n${content.join('\n')}`, 526 | }, 527 | ], 528 | isError: false, 529 | }; 530 | } catch (error) { 531 | return { 532 | content: [ 533 | { 534 | type: "text", 535 | text: `Failed to extract content: ${(error as Error).message}`, 536 | }, 537 | ], 538 | isError: true, 539 | }; 540 | } 541 | } 542 | 543 | default: 544 | return { 545 | content: [ 546 | { 547 | type: "text", 548 | text: `Unknown tool: ${name}`, 549 | }, 550 | ], 551 | isError: true, 552 | }; 553 | } 554 | } catch (error) { 555 | const errorMsg = error instanceof Error ? error.message : String(error); 556 | console.error( 557 | `Failed to handle tool call: ${errorMsg}` 558 | ); 559 | return { 560 | content: [ 561 | { 562 | type: "text", 563 | text: `Failed to handle tool call: ${errorMsg}`, 564 | }, 565 | ], 566 | isError: true, 567 | }; 568 | } 569 | } 570 | 571 | // 6. Server Setup and Configuration 572 | const server = new Server( 573 | { 574 | name: "example-servers/browserbase", 575 | version: "0.1.0", 576 | }, 577 | { 578 | capabilities: { 579 | resources: {}, 580 | tools: {}, 581 | }, 582 | } 583 | ); 584 | 585 | // 7. Request Handlers 586 | server.setRequestHandler(ListResourcesRequestSchema, async () => ({ 587 | resources: [ 588 | ...Array.from(screenshots.keys()).map((name) => ({ 589 | uri: `screenshot://${name}`, 590 | mimeType: "image/png", 591 | name: `Screenshot: ${name}`, 592 | })), 593 | ], 594 | })); 595 | 596 | server.setRequestHandler(ReadResourceRequestSchema, async (request) => { 597 | const uri = request.params.uri.toString(); 598 | 599 | 600 | if (uri.startsWith("screenshot://")) { 601 | const name = uri.split("://")[1]; 602 | const screenshot = screenshots.get(name); 603 | if (screenshot) { 604 | return { 605 | contents: [ 606 | { 607 | uri, 608 | mimeType: "image/png", 609 | blob: screenshot, 610 | }, 611 | ], 612 | }; 613 | } 614 | } 615 | 616 | throw new Error(`Resource not found: ${uri}`); 617 | }); 618 | 619 | server.setRequestHandler(ListToolsRequestSchema, async () => ({ 620 | tools: TOOLS, 621 | })); 622 | 623 | server.setRequestHandler(CallToolRequestSchema, async (request) => 624 | handleToolCall(request.params.name, request.params.arguments ?? {}) 625 | ); 626 | 627 | // 8. Server Initialization 628 | async function runServer() { 629 | const transport = new StdioServerTransport(); 630 | await server.connect(transport); 631 | } 632 | 633 | runServer().catch(console.error); -------------------------------------------------------------------------------- /browserbase/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "resolveJsonModule": true, 11 | "outDir": "dist", 12 | "rootDir": "src" 13 | }, 14 | "include": ["src/**/*.ts"], 15 | "exclude": ["node_modules"] 16 | } 17 | -------------------------------------------------------------------------------- /stagehand/README.md: -------------------------------------------------------------------------------- 1 | # Stagehand MCP Server 2 | 3 | ![cover](../assets/stagehand-mcp.png) 4 | 5 | A Model Context Protocol (MCP) server that provides AI-powered web automation capabilities using [Stagehand](https://github.com/browserbase/stagehand). This server enables LLMs to interact with web pages, perform actions, extract data, and observe possible actions in a real browser environment. 6 | 7 | ## Get Started 8 | 9 | 1. Run `npm install` to install the necessary dependencies, then run `npm run build` to get `dist/index.js`. 10 | 11 | 2. Set up your Claude Desktop configuration to use the server. 12 | 13 | ```json 14 | { 15 | "mcpServers": { 16 | "stagehand": { 17 | "command": "node", 18 | "args": ["path/to/mcp-server-browserbase/stagehand/dist/index.js"], 19 | "env": { 20 | "BROWSERBASE_API_KEY": "", 21 | "BROWSERBASE_PROJECT_ID": "", 22 | "OPENAI_API_KEY": "", 23 | "CONTEXT_ID": "" 24 | } 25 | } 26 | } 27 | } 28 | ``` 29 | or, for running locally, first [**open Chrome in debug mode**](https://docs.stagehand.dev/examples/customize_browser#use-your-personal-browser) like so: 30 | 31 | `open -a "Google Chrome" --args --remote-debugging-port=9222` 32 | ```json 33 | { 34 | "mcpServers": { 35 | "stagehand": { 36 | "command": "node", 37 | "args": ["path/to/mcp-server-browserbase/stagehand/dist/index.js"], 38 | "env": { 39 | "OPENAI_API_KEY": "", 40 | "LOCAL_CDP_URL": "http://localhost:9222" 41 | } 42 | } 43 | } 44 | } 45 | ``` 46 | > 💡 Check out our [documentation](https://docs.stagehand.dev/examples/customize_browser#use-your-personal-browser) for getting your local CDP url! 47 | 48 | 3. Restart your Claude Desktop app and you should see the tools available clicking the 🔨 icon. 49 | 50 | 4. Start using the tools! Below is a demo video of Claude doing a Google search for OpenAI using stagehand MCP server and Browserbase for a remote headless browser. 51 | 52 | 60 | 61 | ## Tools 62 | 63 | ### Stagehand commands 64 | 65 | - **stagehand_navigate** 66 | - Navigate to any URL in the browser 67 | - Input: 68 | - `url` (string): The URL to navigate to 69 | 70 | - **stagehand_act** 71 | - Perform an action on the web page 72 | - Inputs: 73 | - `action` (string): The action to perform (e.g., "click the login button") 74 | - `variables` (object, optional): Variables used in the action template 75 | 76 | - **stagehand_extract** 77 | - Extract data from the web page 78 | 79 | - **stagehand_observe** 80 | - Observe actions that can be performed on the web page 81 | - Input: 82 | - `instruction` (string, optional): Instruction for observation 83 | 84 | ### Resources 85 | 86 | The server provides access to one resource: 87 | 88 | 1. **Console Logs** (`console://logs`) 89 | 90 | - Browser console output in text format 91 | - Includes all console messages from the browser 92 | 93 | 2. **Screenshots** (`screenshot://`) 94 | - PNG images of captured screenshots 95 | - Accessible via the screenshot name specified during capture 96 | 97 | ## File Structure 98 | 99 | The codebase is organized into the following modules: 100 | 101 | - **index.ts**: Entry point that initializes and runs the server. 102 | - **server.ts**: Core server logic, including server creation, configuration, and request handling. 103 | - **tools.ts**: Definitions and implementations of tools that can be called by MCP clients. 104 | - **prompts.ts**: Prompt templates that can be used by MCP clients. 105 | - **resources.ts**: Resource definitions and handlers for resource-related requests. 106 | - **logging.ts**: Comprehensive logging system with rotation and formatting capabilities. 107 | - **utils.ts**: Utility functions including JSON Schema to Zod schema conversion and message sanitization. 108 | 109 | ## Module Descriptions 110 | 111 | ### index.ts 112 | 113 | The main entry point for the application. It: 114 | - Initializes the logging system 115 | - Creates the server instance 116 | - Connects to the stdio transport to receive and respond to requests 117 | 118 | ### server.ts 119 | 120 | Contains core server functionality: 121 | - Creates and configures the MCP server 122 | - Defines Stagehand configuration 123 | - Sets up request handlers for all MCP operations 124 | - Manages the Stagehand browser instance 125 | 126 | ### tools.ts 127 | 128 | Implements the tools that can be called by MCP clients: 129 | - `stagehand_navigate`: Navigate to URLs 130 | - `stagehand_act`: Perform actions on web elements 131 | - `stagehand_extract`: Extract structured data from web pages 132 | - `stagehand_observe`: Observe elements on the page 133 | - `screenshot`: Take screenshots of the current page 134 | 135 | ### prompts.ts 136 | 137 | Defines prompt templates for MCP clients: 138 | - `click_search_button`: Template for clicking search buttons 139 | 140 | ### resources.ts 141 | 142 | Manages resources in the MCP protocol: 143 | - Currently provides empty resource and resource template lists 144 | 145 | ### logging.ts 146 | 147 | Implements a comprehensive logging system: 148 | - File-based logging with rotation 149 | - In-memory operation logs 150 | - Log formatting and sanitization 151 | - Console logging for debugging 152 | 153 | ### utils.ts 154 | 155 | Provides utility functions: 156 | - `jsonSchemaToZod`: Converts JSON Schema to Zod schema for validation 157 | - `sanitizeMessage`: Ensures messages are properly formatted JSON 158 | 159 | ## Key Features 160 | 161 | - AI-powered web automation 162 | - Perform actions on web pages 163 | - Extract structured data from web pages 164 | - Observe possible actions on web pages 165 | - Simple and extensible API 166 | - Model-agnostic support for various LLM providers 167 | 168 | ## Environment Variables 169 | 170 | - `BROWSERBASE_API_KEY`: API key for BrowserBase authentication 171 | - `BROWSERBASE_PROJECT_ID`: Project ID for BrowserBase 172 | - `OPENAI_API_KEY`: API key for OpenAI (used by Stagehand) 173 | - `DEBUG`: Enable debug logging 174 | 175 | ## MCP Capabilities 176 | 177 | This server implements the following MCP capabilities: 178 | 179 | - **Tools**: Allows clients to call tools that control a browser instance 180 | - **Prompts**: Provides prompt templates for common operations 181 | - **Resources**: (Currently empty but structured for future expansion) 182 | - **Logging**: Provides detailed logging capabilities 183 | 184 | For more information about the Model Context Protocol, visit: 185 | - [MCP Documentation](https://modelcontextprotocol.io/docs) 186 | - [MCP Specification](https://spec.modelcontextprotocol.io/) 187 | 188 | ## License 189 | 190 | Licensed under the MIT License. 191 | 192 | Copyright 2024 Browserbase, Inc. 193 | -------------------------------------------------------------------------------- /stagehand/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@browserbasehq/mcp-stagehand", 3 | "version": "0.5.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@browserbasehq/mcp-stagehand", 9 | "version": "0.5.1", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@browserbasehq/sdk": "^2.0.0", 13 | "@browserbasehq/stagehand": "^2.0.0", 14 | "@modelcontextprotocol/sdk": "^1.0.3", 15 | "@modelcontextprotocol/server-stagehand": "file:", 16 | "@playwright/test": "^1.49.0" 17 | }, 18 | "bin": { 19 | "mcp-server-stagehand": "dist/index.js" 20 | }, 21 | "devDependencies": { 22 | "shx": "^0.3.4", 23 | "typescript": "^5.6.2" 24 | } 25 | }, 26 | "node_modules/@anthropic-ai/sdk": { 27 | "version": "0.39.0", 28 | "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.39.0.tgz", 29 | "integrity": "sha512-eMyDIPRZbt1CCLErRCi3exlAvNkBtRe+kW5vvJyef93PmNr/clstYgHhtvmkxN82nlKgzyGPCyGxrm0JQ1ZIdg==", 30 | "license": "MIT", 31 | "dependencies": { 32 | "@types/node": "^18.11.18", 33 | "@types/node-fetch": "^2.6.4", 34 | "abort-controller": "^3.0.0", 35 | "agentkeepalive": "^4.2.1", 36 | "form-data-encoder": "1.7.2", 37 | "formdata-node": "^4.3.2", 38 | "node-fetch": "^2.6.7" 39 | } 40 | }, 41 | "node_modules/@browserbasehq/sdk": { 42 | "version": "2.5.0", 43 | "resolved": "https://registry.npmjs.org/@browserbasehq/sdk/-/sdk-2.5.0.tgz", 44 | "integrity": "sha512-bcnbYZvm5Ht1nrHUfWDK4crspiTy1ESJYMApsMiOTUnlKOan0ocRD6m7hZH34iSC2c2XWsoryR80cwsYgCBWzQ==", 45 | "license": "Apache-2.0", 46 | "dependencies": { 47 | "@types/node": "^18.11.18", 48 | "@types/node-fetch": "^2.6.4", 49 | "abort-controller": "^3.0.0", 50 | "agentkeepalive": "^4.2.1", 51 | "form-data-encoder": "1.7.2", 52 | "formdata-node": "^4.3.2", 53 | "node-fetch": "^2.6.7" 54 | } 55 | }, 56 | "node_modules/@browserbasehq/stagehand": { 57 | "version": "2.0.0", 58 | "resolved": "https://registry.npmjs.org/@browserbasehq/stagehand/-/stagehand-2.0.0.tgz", 59 | "integrity": "sha512-zYSuF/mjq3579ezPWlvMkGTJacSFhz4bEkimstgb6V+ychdFocAMwuF9SrTPmJF5dYUK8FR1nbjZ52+w2sRRoQ==", 60 | "license": "MIT", 61 | "dependencies": { 62 | "@anthropic-ai/sdk": "0.39.0", 63 | "@browserbasehq/sdk": "^2.4.0", 64 | "ws": "^8.18.0", 65 | "zod-to-json-schema": "^3.23.5" 66 | }, 67 | "peerDependencies": { 68 | "@playwright/test": "^1.42.1", 69 | "deepmerge": "^4.3.1", 70 | "dotenv": "^16.4.5", 71 | "openai": "^4.87.1", 72 | "pino": "^9.6.0", 73 | "pino-pretty": "^13.0.0", 74 | "zod": "^3.23.8" 75 | } 76 | }, 77 | "node_modules/@modelcontextprotocol/sdk": { 78 | "version": "1.6.1", 79 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.6.1.tgz", 80 | "integrity": "sha512-oxzMzYCkZHMntzuyerehK3fV6A2Kwh5BD6CGEJSVDU2QNEhfLOptf2X7esQgaHZXHZY0oHmMsOtIDLP71UJXgA==", 81 | "license": "MIT", 82 | "dependencies": { 83 | "content-type": "^1.0.5", 84 | "cors": "^2.8.5", 85 | "eventsource": "^3.0.2", 86 | "express": "^5.0.1", 87 | "express-rate-limit": "^7.5.0", 88 | "pkce-challenge": "^4.1.0", 89 | "raw-body": "^3.0.0", 90 | "zod": "^3.23.8", 91 | "zod-to-json-schema": "^3.24.1" 92 | }, 93 | "engines": { 94 | "node": ">=18" 95 | } 96 | }, 97 | "node_modules/@modelcontextprotocol/server-stagehand": { 98 | "resolved": "", 99 | "link": true 100 | }, 101 | "node_modules/@playwright/test": { 102 | "version": "1.51.0", 103 | "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.51.0.tgz", 104 | "integrity": "sha512-dJ0dMbZeHhI+wb77+ljx/FeC8VBP6j/rj9OAojO08JI80wTZy6vRk9KvHKiDCUh4iMpEiseMgqRBIeW+eKX6RA==", 105 | "license": "Apache-2.0", 106 | "dependencies": { 107 | "playwright": "1.51.0" 108 | }, 109 | "bin": { 110 | "playwright": "cli.js" 111 | }, 112 | "engines": { 113 | "node": ">=18" 114 | } 115 | }, 116 | "node_modules/@types/node": { 117 | "version": "18.19.80", 118 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.80.tgz", 119 | "integrity": "sha512-kEWeMwMeIvxYkeg1gTc01awpwLbfMRZXdIhwRcakd/KlK53jmRC26LqcbIt7fnAQTu5GzlnWmzA3H6+l1u6xxQ==", 120 | "license": "MIT", 121 | "dependencies": { 122 | "undici-types": "~5.26.4" 123 | } 124 | }, 125 | "node_modules/@types/node-fetch": { 126 | "version": "2.6.12", 127 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", 128 | "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", 129 | "license": "MIT", 130 | "dependencies": { 131 | "@types/node": "*", 132 | "form-data": "^4.0.0" 133 | } 134 | }, 135 | "node_modules/abort-controller": { 136 | "version": "3.0.0", 137 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 138 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 139 | "license": "MIT", 140 | "dependencies": { 141 | "event-target-shim": "^5.0.0" 142 | }, 143 | "engines": { 144 | "node": ">=6.5" 145 | } 146 | }, 147 | "node_modules/accepts": { 148 | "version": "2.0.0", 149 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", 150 | "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", 151 | "license": "MIT", 152 | "dependencies": { 153 | "mime-types": "^3.0.0", 154 | "negotiator": "^1.0.0" 155 | }, 156 | "engines": { 157 | "node": ">= 0.6" 158 | } 159 | }, 160 | "node_modules/agentkeepalive": { 161 | "version": "4.6.0", 162 | "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", 163 | "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", 164 | "license": "MIT", 165 | "dependencies": { 166 | "humanize-ms": "^1.2.1" 167 | }, 168 | "engines": { 169 | "node": ">= 8.0.0" 170 | } 171 | }, 172 | "node_modules/asynckit": { 173 | "version": "0.4.0", 174 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 175 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", 176 | "license": "MIT" 177 | }, 178 | "node_modules/atomic-sleep": { 179 | "version": "1.0.0", 180 | "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", 181 | "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", 182 | "license": "MIT", 183 | "peer": true, 184 | "engines": { 185 | "node": ">=8.0.0" 186 | } 187 | }, 188 | "node_modules/balanced-match": { 189 | "version": "1.0.2", 190 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 191 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 192 | "dev": true, 193 | "license": "MIT" 194 | }, 195 | "node_modules/body-parser": { 196 | "version": "2.1.0", 197 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.1.0.tgz", 198 | "integrity": "sha512-/hPxh61E+ll0Ujp24Ilm64cykicul1ypfwjVttduAiEdtnJFvLePSrIPk+HMImtNv5270wOGCb1Tns2rybMkoQ==", 199 | "license": "MIT", 200 | "dependencies": { 201 | "bytes": "^3.1.2", 202 | "content-type": "^1.0.5", 203 | "debug": "^4.4.0", 204 | "http-errors": "^2.0.0", 205 | "iconv-lite": "^0.5.2", 206 | "on-finished": "^2.4.1", 207 | "qs": "^6.14.0", 208 | "raw-body": "^3.0.0", 209 | "type-is": "^2.0.0" 210 | }, 211 | "engines": { 212 | "node": ">=18" 213 | } 214 | }, 215 | "node_modules/body-parser/node_modules/debug": { 216 | "version": "4.4.0", 217 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 218 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 219 | "license": "MIT", 220 | "dependencies": { 221 | "ms": "^2.1.3" 222 | }, 223 | "engines": { 224 | "node": ">=6.0" 225 | }, 226 | "peerDependenciesMeta": { 227 | "supports-color": { 228 | "optional": true 229 | } 230 | } 231 | }, 232 | "node_modules/body-parser/node_modules/ms": { 233 | "version": "2.1.3", 234 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 235 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 236 | "license": "MIT" 237 | }, 238 | "node_modules/body-parser/node_modules/qs": { 239 | "version": "6.14.0", 240 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", 241 | "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", 242 | "license": "BSD-3-Clause", 243 | "dependencies": { 244 | "side-channel": "^1.1.0" 245 | }, 246 | "engines": { 247 | "node": ">=0.6" 248 | }, 249 | "funding": { 250 | "url": "https://github.com/sponsors/ljharb" 251 | } 252 | }, 253 | "node_modules/brace-expansion": { 254 | "version": "1.1.11", 255 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 256 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 257 | "dev": true, 258 | "license": "MIT", 259 | "dependencies": { 260 | "balanced-match": "^1.0.0", 261 | "concat-map": "0.0.1" 262 | } 263 | }, 264 | "node_modules/bytes": { 265 | "version": "3.1.2", 266 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 267 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 268 | "license": "MIT", 269 | "engines": { 270 | "node": ">= 0.8" 271 | } 272 | }, 273 | "node_modules/call-bind-apply-helpers": { 274 | "version": "1.0.2", 275 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 276 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 277 | "license": "MIT", 278 | "dependencies": { 279 | "es-errors": "^1.3.0", 280 | "function-bind": "^1.1.2" 281 | }, 282 | "engines": { 283 | "node": ">= 0.4" 284 | } 285 | }, 286 | "node_modules/call-bound": { 287 | "version": "1.0.4", 288 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", 289 | "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", 290 | "license": "MIT", 291 | "dependencies": { 292 | "call-bind-apply-helpers": "^1.0.2", 293 | "get-intrinsic": "^1.3.0" 294 | }, 295 | "engines": { 296 | "node": ">= 0.4" 297 | }, 298 | "funding": { 299 | "url": "https://github.com/sponsors/ljharb" 300 | } 301 | }, 302 | "node_modules/colorette": { 303 | "version": "2.0.20", 304 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", 305 | "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", 306 | "license": "MIT", 307 | "peer": true 308 | }, 309 | "node_modules/combined-stream": { 310 | "version": "1.0.8", 311 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 312 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 313 | "license": "MIT", 314 | "dependencies": { 315 | "delayed-stream": "~1.0.0" 316 | }, 317 | "engines": { 318 | "node": ">= 0.8" 319 | } 320 | }, 321 | "node_modules/concat-map": { 322 | "version": "0.0.1", 323 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 324 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 325 | "dev": true, 326 | "license": "MIT" 327 | }, 328 | "node_modules/content-disposition": { 329 | "version": "1.0.0", 330 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", 331 | "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", 332 | "license": "MIT", 333 | "dependencies": { 334 | "safe-buffer": "5.2.1" 335 | }, 336 | "engines": { 337 | "node": ">= 0.6" 338 | } 339 | }, 340 | "node_modules/content-type": { 341 | "version": "1.0.5", 342 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 343 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 344 | "license": "MIT", 345 | "engines": { 346 | "node": ">= 0.6" 347 | } 348 | }, 349 | "node_modules/cookie": { 350 | "version": "0.7.1", 351 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", 352 | "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", 353 | "license": "MIT", 354 | "engines": { 355 | "node": ">= 0.6" 356 | } 357 | }, 358 | "node_modules/cookie-signature": { 359 | "version": "1.2.2", 360 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", 361 | "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", 362 | "license": "MIT", 363 | "engines": { 364 | "node": ">=6.6.0" 365 | } 366 | }, 367 | "node_modules/cors": { 368 | "version": "2.8.5", 369 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 370 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 371 | "license": "MIT", 372 | "dependencies": { 373 | "object-assign": "^4", 374 | "vary": "^1" 375 | }, 376 | "engines": { 377 | "node": ">= 0.10" 378 | } 379 | }, 380 | "node_modules/dateformat": { 381 | "version": "4.6.3", 382 | "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", 383 | "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", 384 | "license": "MIT", 385 | "peer": true, 386 | "engines": { 387 | "node": "*" 388 | } 389 | }, 390 | "node_modules/debug": { 391 | "version": "4.3.6", 392 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", 393 | "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", 394 | "license": "MIT", 395 | "dependencies": { 396 | "ms": "2.1.2" 397 | }, 398 | "engines": { 399 | "node": ">=6.0" 400 | }, 401 | "peerDependenciesMeta": { 402 | "supports-color": { 403 | "optional": true 404 | } 405 | } 406 | }, 407 | "node_modules/deepmerge": { 408 | "version": "4.3.1", 409 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", 410 | "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", 411 | "license": "MIT", 412 | "peer": true, 413 | "engines": { 414 | "node": ">=0.10.0" 415 | } 416 | }, 417 | "node_modules/delayed-stream": { 418 | "version": "1.0.0", 419 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 420 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 421 | "license": "MIT", 422 | "engines": { 423 | "node": ">=0.4.0" 424 | } 425 | }, 426 | "node_modules/depd": { 427 | "version": "2.0.0", 428 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 429 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 430 | "license": "MIT", 431 | "engines": { 432 | "node": ">= 0.8" 433 | } 434 | }, 435 | "node_modules/destroy": { 436 | "version": "1.2.0", 437 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 438 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 439 | "license": "MIT", 440 | "engines": { 441 | "node": ">= 0.8", 442 | "npm": "1.2.8000 || >= 1.4.16" 443 | } 444 | }, 445 | "node_modules/dotenv": { 446 | "version": "16.4.7", 447 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", 448 | "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", 449 | "license": "BSD-2-Clause", 450 | "peer": true, 451 | "engines": { 452 | "node": ">=12" 453 | }, 454 | "funding": { 455 | "url": "https://dotenvx.com" 456 | } 457 | }, 458 | "node_modules/dunder-proto": { 459 | "version": "1.0.1", 460 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 461 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 462 | "license": "MIT", 463 | "dependencies": { 464 | "call-bind-apply-helpers": "^1.0.1", 465 | "es-errors": "^1.3.0", 466 | "gopd": "^1.2.0" 467 | }, 468 | "engines": { 469 | "node": ">= 0.4" 470 | } 471 | }, 472 | "node_modules/ee-first": { 473 | "version": "1.1.1", 474 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 475 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", 476 | "license": "MIT" 477 | }, 478 | "node_modules/encodeurl": { 479 | "version": "2.0.0", 480 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", 481 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", 482 | "license": "MIT", 483 | "engines": { 484 | "node": ">= 0.8" 485 | } 486 | }, 487 | "node_modules/end-of-stream": { 488 | "version": "1.4.4", 489 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 490 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 491 | "license": "MIT", 492 | "peer": true, 493 | "dependencies": { 494 | "once": "^1.4.0" 495 | } 496 | }, 497 | "node_modules/es-define-property": { 498 | "version": "1.0.1", 499 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 500 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 501 | "license": "MIT", 502 | "engines": { 503 | "node": ">= 0.4" 504 | } 505 | }, 506 | "node_modules/es-errors": { 507 | "version": "1.3.0", 508 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 509 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 510 | "license": "MIT", 511 | "engines": { 512 | "node": ">= 0.4" 513 | } 514 | }, 515 | "node_modules/es-object-atoms": { 516 | "version": "1.1.1", 517 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 518 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 519 | "license": "MIT", 520 | "dependencies": { 521 | "es-errors": "^1.3.0" 522 | }, 523 | "engines": { 524 | "node": ">= 0.4" 525 | } 526 | }, 527 | "node_modules/es-set-tostringtag": { 528 | "version": "2.1.0", 529 | "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", 530 | "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", 531 | "license": "MIT", 532 | "dependencies": { 533 | "es-errors": "^1.3.0", 534 | "get-intrinsic": "^1.2.6", 535 | "has-tostringtag": "^1.0.2", 536 | "hasown": "^2.0.2" 537 | }, 538 | "engines": { 539 | "node": ">= 0.4" 540 | } 541 | }, 542 | "node_modules/escape-html": { 543 | "version": "1.0.3", 544 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 545 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", 546 | "license": "MIT" 547 | }, 548 | "node_modules/etag": { 549 | "version": "1.8.1", 550 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 551 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 552 | "license": "MIT", 553 | "engines": { 554 | "node": ">= 0.6" 555 | } 556 | }, 557 | "node_modules/event-target-shim": { 558 | "version": "5.0.1", 559 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 560 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", 561 | "license": "MIT", 562 | "engines": { 563 | "node": ">=6" 564 | } 565 | }, 566 | "node_modules/eventsource": { 567 | "version": "3.0.5", 568 | "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.5.tgz", 569 | "integrity": "sha512-LT/5J605bx5SNyE+ITBDiM3FxffBiq9un7Vx0EwMDM3vg8sWKx/tO2zC+LMqZ+smAM0F2hblaDZUVZF0te2pSw==", 570 | "license": "MIT", 571 | "dependencies": { 572 | "eventsource-parser": "^3.0.0" 573 | }, 574 | "engines": { 575 | "node": ">=18.0.0" 576 | } 577 | }, 578 | "node_modules/eventsource-parser": { 579 | "version": "3.0.0", 580 | "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.0.tgz", 581 | "integrity": "sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==", 582 | "license": "MIT", 583 | "engines": { 584 | "node": ">=18.0.0" 585 | } 586 | }, 587 | "node_modules/express": { 588 | "version": "5.0.1", 589 | "resolved": "https://registry.npmjs.org/express/-/express-5.0.1.tgz", 590 | "integrity": "sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==", 591 | "license": "MIT", 592 | "dependencies": { 593 | "accepts": "^2.0.0", 594 | "body-parser": "^2.0.1", 595 | "content-disposition": "^1.0.0", 596 | "content-type": "~1.0.4", 597 | "cookie": "0.7.1", 598 | "cookie-signature": "^1.2.1", 599 | "debug": "4.3.6", 600 | "depd": "2.0.0", 601 | "encodeurl": "~2.0.0", 602 | "escape-html": "~1.0.3", 603 | "etag": "~1.8.1", 604 | "finalhandler": "^2.0.0", 605 | "fresh": "2.0.0", 606 | "http-errors": "2.0.0", 607 | "merge-descriptors": "^2.0.0", 608 | "methods": "~1.1.2", 609 | "mime-types": "^3.0.0", 610 | "on-finished": "2.4.1", 611 | "once": "1.4.0", 612 | "parseurl": "~1.3.3", 613 | "proxy-addr": "~2.0.7", 614 | "qs": "6.13.0", 615 | "range-parser": "~1.2.1", 616 | "router": "^2.0.0", 617 | "safe-buffer": "5.2.1", 618 | "send": "^1.1.0", 619 | "serve-static": "^2.1.0", 620 | "setprototypeof": "1.2.0", 621 | "statuses": "2.0.1", 622 | "type-is": "^2.0.0", 623 | "utils-merge": "1.0.1", 624 | "vary": "~1.1.2" 625 | }, 626 | "engines": { 627 | "node": ">= 18" 628 | } 629 | }, 630 | "node_modules/express-rate-limit": { 631 | "version": "7.5.0", 632 | "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", 633 | "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", 634 | "license": "MIT", 635 | "engines": { 636 | "node": ">= 16" 637 | }, 638 | "funding": { 639 | "url": "https://github.com/sponsors/express-rate-limit" 640 | }, 641 | "peerDependencies": { 642 | "express": "^4.11 || 5 || ^5.0.0-beta.1" 643 | } 644 | }, 645 | "node_modules/fast-copy": { 646 | "version": "3.0.2", 647 | "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", 648 | "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", 649 | "license": "MIT", 650 | "peer": true 651 | }, 652 | "node_modules/fast-redact": { 653 | "version": "3.5.0", 654 | "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", 655 | "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", 656 | "license": "MIT", 657 | "peer": true, 658 | "engines": { 659 | "node": ">=6" 660 | } 661 | }, 662 | "node_modules/fast-safe-stringify": { 663 | "version": "2.1.1", 664 | "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", 665 | "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", 666 | "license": "MIT", 667 | "peer": true 668 | }, 669 | "node_modules/finalhandler": { 670 | "version": "2.1.0", 671 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", 672 | "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", 673 | "license": "MIT", 674 | "dependencies": { 675 | "debug": "^4.4.0", 676 | "encodeurl": "^2.0.0", 677 | "escape-html": "^1.0.3", 678 | "on-finished": "^2.4.1", 679 | "parseurl": "^1.3.3", 680 | "statuses": "^2.0.1" 681 | }, 682 | "engines": { 683 | "node": ">= 0.8" 684 | } 685 | }, 686 | "node_modules/finalhandler/node_modules/debug": { 687 | "version": "4.4.0", 688 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 689 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 690 | "license": "MIT", 691 | "dependencies": { 692 | "ms": "^2.1.3" 693 | }, 694 | "engines": { 695 | "node": ">=6.0" 696 | }, 697 | "peerDependenciesMeta": { 698 | "supports-color": { 699 | "optional": true 700 | } 701 | } 702 | }, 703 | "node_modules/finalhandler/node_modules/ms": { 704 | "version": "2.1.3", 705 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 706 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 707 | "license": "MIT" 708 | }, 709 | "node_modules/form-data": { 710 | "version": "4.0.2", 711 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", 712 | "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", 713 | "license": "MIT", 714 | "dependencies": { 715 | "asynckit": "^0.4.0", 716 | "combined-stream": "^1.0.8", 717 | "es-set-tostringtag": "^2.1.0", 718 | "mime-types": "^2.1.12" 719 | }, 720 | "engines": { 721 | "node": ">= 6" 722 | } 723 | }, 724 | "node_modules/form-data-encoder": { 725 | "version": "1.7.2", 726 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", 727 | "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", 728 | "license": "MIT" 729 | }, 730 | "node_modules/form-data/node_modules/mime-db": { 731 | "version": "1.52.0", 732 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 733 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 734 | "license": "MIT", 735 | "engines": { 736 | "node": ">= 0.6" 737 | } 738 | }, 739 | "node_modules/form-data/node_modules/mime-types": { 740 | "version": "2.1.35", 741 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 742 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 743 | "license": "MIT", 744 | "dependencies": { 745 | "mime-db": "1.52.0" 746 | }, 747 | "engines": { 748 | "node": ">= 0.6" 749 | } 750 | }, 751 | "node_modules/formdata-node": { 752 | "version": "4.4.1", 753 | "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", 754 | "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", 755 | "license": "MIT", 756 | "dependencies": { 757 | "node-domexception": "1.0.0", 758 | "web-streams-polyfill": "4.0.0-beta.3" 759 | }, 760 | "engines": { 761 | "node": ">= 12.20" 762 | } 763 | }, 764 | "node_modules/forwarded": { 765 | "version": "0.2.0", 766 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 767 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 768 | "license": "MIT", 769 | "engines": { 770 | "node": ">= 0.6" 771 | } 772 | }, 773 | "node_modules/fresh": { 774 | "version": "2.0.0", 775 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", 776 | "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", 777 | "license": "MIT", 778 | "engines": { 779 | "node": ">= 0.8" 780 | } 781 | }, 782 | "node_modules/fs.realpath": { 783 | "version": "1.0.0", 784 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 785 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 786 | "dev": true, 787 | "license": "ISC" 788 | }, 789 | "node_modules/fsevents": { 790 | "version": "2.3.2", 791 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 792 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 793 | "hasInstallScript": true, 794 | "license": "MIT", 795 | "optional": true, 796 | "os": [ 797 | "darwin" 798 | ], 799 | "engines": { 800 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 801 | } 802 | }, 803 | "node_modules/function-bind": { 804 | "version": "1.1.2", 805 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 806 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 807 | "license": "MIT", 808 | "funding": { 809 | "url": "https://github.com/sponsors/ljharb" 810 | } 811 | }, 812 | "node_modules/get-intrinsic": { 813 | "version": "1.3.0", 814 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 815 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 816 | "license": "MIT", 817 | "dependencies": { 818 | "call-bind-apply-helpers": "^1.0.2", 819 | "es-define-property": "^1.0.1", 820 | "es-errors": "^1.3.0", 821 | "es-object-atoms": "^1.1.1", 822 | "function-bind": "^1.1.2", 823 | "get-proto": "^1.0.1", 824 | "gopd": "^1.2.0", 825 | "has-symbols": "^1.1.0", 826 | "hasown": "^2.0.2", 827 | "math-intrinsics": "^1.1.0" 828 | }, 829 | "engines": { 830 | "node": ">= 0.4" 831 | }, 832 | "funding": { 833 | "url": "https://github.com/sponsors/ljharb" 834 | } 835 | }, 836 | "node_modules/get-proto": { 837 | "version": "1.0.1", 838 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 839 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 840 | "license": "MIT", 841 | "dependencies": { 842 | "dunder-proto": "^1.0.1", 843 | "es-object-atoms": "^1.0.0" 844 | }, 845 | "engines": { 846 | "node": ">= 0.4" 847 | } 848 | }, 849 | "node_modules/glob": { 850 | "version": "7.2.3", 851 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 852 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 853 | "deprecated": "Glob versions prior to v9 are no longer supported", 854 | "dev": true, 855 | "license": "ISC", 856 | "dependencies": { 857 | "fs.realpath": "^1.0.0", 858 | "inflight": "^1.0.4", 859 | "inherits": "2", 860 | "minimatch": "^3.1.1", 861 | "once": "^1.3.0", 862 | "path-is-absolute": "^1.0.0" 863 | }, 864 | "engines": { 865 | "node": "*" 866 | }, 867 | "funding": { 868 | "url": "https://github.com/sponsors/isaacs" 869 | } 870 | }, 871 | "node_modules/gopd": { 872 | "version": "1.2.0", 873 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 874 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 875 | "license": "MIT", 876 | "engines": { 877 | "node": ">= 0.4" 878 | }, 879 | "funding": { 880 | "url": "https://github.com/sponsors/ljharb" 881 | } 882 | }, 883 | "node_modules/has-symbols": { 884 | "version": "1.1.0", 885 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 886 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 887 | "license": "MIT", 888 | "engines": { 889 | "node": ">= 0.4" 890 | }, 891 | "funding": { 892 | "url": "https://github.com/sponsors/ljharb" 893 | } 894 | }, 895 | "node_modules/has-tostringtag": { 896 | "version": "1.0.2", 897 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", 898 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", 899 | "license": "MIT", 900 | "dependencies": { 901 | "has-symbols": "^1.0.3" 902 | }, 903 | "engines": { 904 | "node": ">= 0.4" 905 | }, 906 | "funding": { 907 | "url": "https://github.com/sponsors/ljharb" 908 | } 909 | }, 910 | "node_modules/hasown": { 911 | "version": "2.0.2", 912 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 913 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 914 | "license": "MIT", 915 | "dependencies": { 916 | "function-bind": "^1.1.2" 917 | }, 918 | "engines": { 919 | "node": ">= 0.4" 920 | } 921 | }, 922 | "node_modules/help-me": { 923 | "version": "5.0.0", 924 | "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", 925 | "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", 926 | "license": "MIT", 927 | "peer": true 928 | }, 929 | "node_modules/http-errors": { 930 | "version": "2.0.0", 931 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 932 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 933 | "license": "MIT", 934 | "dependencies": { 935 | "depd": "2.0.0", 936 | "inherits": "2.0.4", 937 | "setprototypeof": "1.2.0", 938 | "statuses": "2.0.1", 939 | "toidentifier": "1.0.1" 940 | }, 941 | "engines": { 942 | "node": ">= 0.8" 943 | } 944 | }, 945 | "node_modules/humanize-ms": { 946 | "version": "1.2.1", 947 | "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", 948 | "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", 949 | "license": "MIT", 950 | "dependencies": { 951 | "ms": "^2.0.0" 952 | } 953 | }, 954 | "node_modules/iconv-lite": { 955 | "version": "0.5.2", 956 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", 957 | "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", 958 | "license": "MIT", 959 | "dependencies": { 960 | "safer-buffer": ">= 2.1.2 < 3" 961 | }, 962 | "engines": { 963 | "node": ">=0.10.0" 964 | } 965 | }, 966 | "node_modules/inflight": { 967 | "version": "1.0.6", 968 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 969 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 970 | "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", 971 | "dev": true, 972 | "license": "ISC", 973 | "dependencies": { 974 | "once": "^1.3.0", 975 | "wrappy": "1" 976 | } 977 | }, 978 | "node_modules/inherits": { 979 | "version": "2.0.4", 980 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 981 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 982 | "license": "ISC" 983 | }, 984 | "node_modules/interpret": { 985 | "version": "1.4.0", 986 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", 987 | "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", 988 | "dev": true, 989 | "license": "MIT", 990 | "engines": { 991 | "node": ">= 0.10" 992 | } 993 | }, 994 | "node_modules/ipaddr.js": { 995 | "version": "1.9.1", 996 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 997 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 998 | "license": "MIT", 999 | "engines": { 1000 | "node": ">= 0.10" 1001 | } 1002 | }, 1003 | "node_modules/is-core-module": { 1004 | "version": "2.16.1", 1005 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", 1006 | "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", 1007 | "dev": true, 1008 | "license": "MIT", 1009 | "dependencies": { 1010 | "hasown": "^2.0.2" 1011 | }, 1012 | "engines": { 1013 | "node": ">= 0.4" 1014 | }, 1015 | "funding": { 1016 | "url": "https://github.com/sponsors/ljharb" 1017 | } 1018 | }, 1019 | "node_modules/is-promise": { 1020 | "version": "4.0.0", 1021 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", 1022 | "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", 1023 | "license": "MIT" 1024 | }, 1025 | "node_modules/joycon": { 1026 | "version": "3.1.1", 1027 | "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", 1028 | "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", 1029 | "license": "MIT", 1030 | "peer": true, 1031 | "engines": { 1032 | "node": ">=10" 1033 | } 1034 | }, 1035 | "node_modules/math-intrinsics": { 1036 | "version": "1.1.0", 1037 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 1038 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 1039 | "license": "MIT", 1040 | "engines": { 1041 | "node": ">= 0.4" 1042 | } 1043 | }, 1044 | "node_modules/media-typer": { 1045 | "version": "1.1.0", 1046 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", 1047 | "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", 1048 | "license": "MIT", 1049 | "engines": { 1050 | "node": ">= 0.8" 1051 | } 1052 | }, 1053 | "node_modules/merge-descriptors": { 1054 | "version": "2.0.0", 1055 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", 1056 | "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", 1057 | "license": "MIT", 1058 | "engines": { 1059 | "node": ">=18" 1060 | }, 1061 | "funding": { 1062 | "url": "https://github.com/sponsors/sindresorhus" 1063 | } 1064 | }, 1065 | "node_modules/methods": { 1066 | "version": "1.1.2", 1067 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1068 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 1069 | "license": "MIT", 1070 | "engines": { 1071 | "node": ">= 0.6" 1072 | } 1073 | }, 1074 | "node_modules/mime-db": { 1075 | "version": "1.53.0", 1076 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", 1077 | "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", 1078 | "license": "MIT", 1079 | "engines": { 1080 | "node": ">= 0.6" 1081 | } 1082 | }, 1083 | "node_modules/mime-types": { 1084 | "version": "3.0.0", 1085 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz", 1086 | "integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==", 1087 | "license": "MIT", 1088 | "dependencies": { 1089 | "mime-db": "^1.53.0" 1090 | }, 1091 | "engines": { 1092 | "node": ">= 0.6" 1093 | } 1094 | }, 1095 | "node_modules/minimatch": { 1096 | "version": "3.1.2", 1097 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1098 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1099 | "dev": true, 1100 | "license": "ISC", 1101 | "dependencies": { 1102 | "brace-expansion": "^1.1.7" 1103 | }, 1104 | "engines": { 1105 | "node": "*" 1106 | } 1107 | }, 1108 | "node_modules/minimist": { 1109 | "version": "1.2.8", 1110 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 1111 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 1112 | "license": "MIT", 1113 | "funding": { 1114 | "url": "https://github.com/sponsors/ljharb" 1115 | } 1116 | }, 1117 | "node_modules/ms": { 1118 | "version": "2.1.2", 1119 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1120 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1121 | "license": "MIT" 1122 | }, 1123 | "node_modules/negotiator": { 1124 | "version": "1.0.0", 1125 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", 1126 | "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", 1127 | "license": "MIT", 1128 | "engines": { 1129 | "node": ">= 0.6" 1130 | } 1131 | }, 1132 | "node_modules/node-domexception": { 1133 | "version": "1.0.0", 1134 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", 1135 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", 1136 | "funding": [ 1137 | { 1138 | "type": "github", 1139 | "url": "https://github.com/sponsors/jimmywarting" 1140 | }, 1141 | { 1142 | "type": "github", 1143 | "url": "https://paypal.me/jimmywarting" 1144 | } 1145 | ], 1146 | "license": "MIT", 1147 | "engines": { 1148 | "node": ">=10.5.0" 1149 | } 1150 | }, 1151 | "node_modules/node-fetch": { 1152 | "version": "2.7.0", 1153 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 1154 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 1155 | "license": "MIT", 1156 | "dependencies": { 1157 | "whatwg-url": "^5.0.0" 1158 | }, 1159 | "engines": { 1160 | "node": "4.x || >=6.0.0" 1161 | }, 1162 | "peerDependencies": { 1163 | "encoding": "^0.1.0" 1164 | }, 1165 | "peerDependenciesMeta": { 1166 | "encoding": { 1167 | "optional": true 1168 | } 1169 | } 1170 | }, 1171 | "node_modules/object-assign": { 1172 | "version": "4.1.1", 1173 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1174 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1175 | "license": "MIT", 1176 | "engines": { 1177 | "node": ">=0.10.0" 1178 | } 1179 | }, 1180 | "node_modules/object-inspect": { 1181 | "version": "1.13.4", 1182 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", 1183 | "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", 1184 | "license": "MIT", 1185 | "engines": { 1186 | "node": ">= 0.4" 1187 | }, 1188 | "funding": { 1189 | "url": "https://github.com/sponsors/ljharb" 1190 | } 1191 | }, 1192 | "node_modules/on-exit-leak-free": { 1193 | "version": "2.1.2", 1194 | "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", 1195 | "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", 1196 | "license": "MIT", 1197 | "peer": true, 1198 | "engines": { 1199 | "node": ">=14.0.0" 1200 | } 1201 | }, 1202 | "node_modules/on-finished": { 1203 | "version": "2.4.1", 1204 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1205 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1206 | "license": "MIT", 1207 | "dependencies": { 1208 | "ee-first": "1.1.1" 1209 | }, 1210 | "engines": { 1211 | "node": ">= 0.8" 1212 | } 1213 | }, 1214 | "node_modules/once": { 1215 | "version": "1.4.0", 1216 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1217 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1218 | "license": "ISC", 1219 | "dependencies": { 1220 | "wrappy": "1" 1221 | } 1222 | }, 1223 | "node_modules/openai": { 1224 | "version": "4.92.0", 1225 | "resolved": "https://registry.npmjs.org/openai/-/openai-4.92.0.tgz", 1226 | "integrity": "sha512-vLIBP8gygD5M7XIrdBkUFKnfEq3EmaI+lmGjDDAmjahzmdhwdpzDA+GBA4ZZwj7rgu1WMNh9/SqyTysxMulC2g==", 1227 | "license": "Apache-2.0", 1228 | "peer": true, 1229 | "dependencies": { 1230 | "@types/node": "^18.11.18", 1231 | "@types/node-fetch": "^2.6.4", 1232 | "abort-controller": "^3.0.0", 1233 | "agentkeepalive": "^4.2.1", 1234 | "form-data-encoder": "1.7.2", 1235 | "formdata-node": "^4.3.2", 1236 | "node-fetch": "^2.6.7" 1237 | }, 1238 | "bin": { 1239 | "openai": "bin/cli" 1240 | }, 1241 | "peerDependencies": { 1242 | "ws": "^8.18.0", 1243 | "zod": "^3.23.8" 1244 | }, 1245 | "peerDependenciesMeta": { 1246 | "ws": { 1247 | "optional": true 1248 | }, 1249 | "zod": { 1250 | "optional": true 1251 | } 1252 | } 1253 | }, 1254 | "node_modules/parseurl": { 1255 | "version": "1.3.3", 1256 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1257 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1258 | "license": "MIT", 1259 | "engines": { 1260 | "node": ">= 0.8" 1261 | } 1262 | }, 1263 | "node_modules/path-is-absolute": { 1264 | "version": "1.0.1", 1265 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1266 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1267 | "dev": true, 1268 | "license": "MIT", 1269 | "engines": { 1270 | "node": ">=0.10.0" 1271 | } 1272 | }, 1273 | "node_modules/path-parse": { 1274 | "version": "1.0.7", 1275 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1276 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1277 | "dev": true, 1278 | "license": "MIT" 1279 | }, 1280 | "node_modules/path-to-regexp": { 1281 | "version": "8.2.0", 1282 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", 1283 | "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", 1284 | "license": "MIT", 1285 | "engines": { 1286 | "node": ">=16" 1287 | } 1288 | }, 1289 | "node_modules/pino": { 1290 | "version": "9.6.0", 1291 | "resolved": "https://registry.npmjs.org/pino/-/pino-9.6.0.tgz", 1292 | "integrity": "sha512-i85pKRCt4qMjZ1+L7sy2Ag4t1atFcdbEt76+7iRJn1g2BvsnRMGu9p8pivl9fs63M2kF/A0OacFZhTub+m/qMg==", 1293 | "license": "MIT", 1294 | "peer": true, 1295 | "dependencies": { 1296 | "atomic-sleep": "^1.0.0", 1297 | "fast-redact": "^3.1.1", 1298 | "on-exit-leak-free": "^2.1.0", 1299 | "pino-abstract-transport": "^2.0.0", 1300 | "pino-std-serializers": "^7.0.0", 1301 | "process-warning": "^4.0.0", 1302 | "quick-format-unescaped": "^4.0.3", 1303 | "real-require": "^0.2.0", 1304 | "safe-stable-stringify": "^2.3.1", 1305 | "sonic-boom": "^4.0.1", 1306 | "thread-stream": "^3.0.0" 1307 | }, 1308 | "bin": { 1309 | "pino": "bin.js" 1310 | } 1311 | }, 1312 | "node_modules/pino-abstract-transport": { 1313 | "version": "2.0.0", 1314 | "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", 1315 | "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", 1316 | "license": "MIT", 1317 | "peer": true, 1318 | "dependencies": { 1319 | "split2": "^4.0.0" 1320 | } 1321 | }, 1322 | "node_modules/pino-pretty": { 1323 | "version": "13.0.0", 1324 | "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-13.0.0.tgz", 1325 | "integrity": "sha512-cQBBIVG3YajgoUjo1FdKVRX6t9XPxwB9lcNJVD5GCnNM4Y6T12YYx8c6zEejxQsU0wrg9TwmDulcE9LR7qcJqA==", 1326 | "license": "MIT", 1327 | "peer": true, 1328 | "dependencies": { 1329 | "colorette": "^2.0.7", 1330 | "dateformat": "^4.6.3", 1331 | "fast-copy": "^3.0.2", 1332 | "fast-safe-stringify": "^2.1.1", 1333 | "help-me": "^5.0.0", 1334 | "joycon": "^3.1.1", 1335 | "minimist": "^1.2.6", 1336 | "on-exit-leak-free": "^2.1.0", 1337 | "pino-abstract-transport": "^2.0.0", 1338 | "pump": "^3.0.0", 1339 | "secure-json-parse": "^2.4.0", 1340 | "sonic-boom": "^4.0.1", 1341 | "strip-json-comments": "^3.1.1" 1342 | }, 1343 | "bin": { 1344 | "pino-pretty": "bin.js" 1345 | } 1346 | }, 1347 | "node_modules/pino-std-serializers": { 1348 | "version": "7.0.0", 1349 | "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", 1350 | "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", 1351 | "license": "MIT", 1352 | "peer": true 1353 | }, 1354 | "node_modules/pkce-challenge": { 1355 | "version": "4.1.0", 1356 | "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-4.1.0.tgz", 1357 | "integrity": "sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ==", 1358 | "license": "MIT", 1359 | "engines": { 1360 | "node": ">=16.20.0" 1361 | } 1362 | }, 1363 | "node_modules/playwright": { 1364 | "version": "1.51.0", 1365 | "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.0.tgz", 1366 | "integrity": "sha512-442pTfGM0xxfCYxuBa/Pu6B2OqxqqaYq39JS8QDMGThUvIOCd6s0ANDog3uwA0cHavVlnTQzGCN7Id2YekDSXA==", 1367 | "license": "Apache-2.0", 1368 | "dependencies": { 1369 | "playwright-core": "1.51.0" 1370 | }, 1371 | "bin": { 1372 | "playwright": "cli.js" 1373 | }, 1374 | "engines": { 1375 | "node": ">=18" 1376 | }, 1377 | "optionalDependencies": { 1378 | "fsevents": "2.3.2" 1379 | } 1380 | }, 1381 | "node_modules/playwright-core": { 1382 | "version": "1.51.0", 1383 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.0.tgz", 1384 | "integrity": "sha512-x47yPE3Zwhlil7wlNU/iktF7t2r/URR3VLbH6EknJd/04Qc/PSJ0EY3CMXipmglLG+zyRxW6HNo2EGbKLHPWMg==", 1385 | "license": "Apache-2.0", 1386 | "bin": { 1387 | "playwright-core": "cli.js" 1388 | }, 1389 | "engines": { 1390 | "node": ">=18" 1391 | } 1392 | }, 1393 | "node_modules/process-warning": { 1394 | "version": "4.0.1", 1395 | "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.1.tgz", 1396 | "integrity": "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==", 1397 | "funding": [ 1398 | { 1399 | "type": "github", 1400 | "url": "https://github.com/sponsors/fastify" 1401 | }, 1402 | { 1403 | "type": "opencollective", 1404 | "url": "https://opencollective.com/fastify" 1405 | } 1406 | ], 1407 | "license": "MIT", 1408 | "peer": true 1409 | }, 1410 | "node_modules/proxy-addr": { 1411 | "version": "2.0.7", 1412 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1413 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1414 | "license": "MIT", 1415 | "dependencies": { 1416 | "forwarded": "0.2.0", 1417 | "ipaddr.js": "1.9.1" 1418 | }, 1419 | "engines": { 1420 | "node": ">= 0.10" 1421 | } 1422 | }, 1423 | "node_modules/pump": { 1424 | "version": "3.0.2", 1425 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", 1426 | "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", 1427 | "license": "MIT", 1428 | "peer": true, 1429 | "dependencies": { 1430 | "end-of-stream": "^1.1.0", 1431 | "once": "^1.3.1" 1432 | } 1433 | }, 1434 | "node_modules/qs": { 1435 | "version": "6.13.0", 1436 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", 1437 | "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", 1438 | "license": "BSD-3-Clause", 1439 | "dependencies": { 1440 | "side-channel": "^1.0.6" 1441 | }, 1442 | "engines": { 1443 | "node": ">=0.6" 1444 | }, 1445 | "funding": { 1446 | "url": "https://github.com/sponsors/ljharb" 1447 | } 1448 | }, 1449 | "node_modules/quick-format-unescaped": { 1450 | "version": "4.0.4", 1451 | "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", 1452 | "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", 1453 | "license": "MIT", 1454 | "peer": true 1455 | }, 1456 | "node_modules/range-parser": { 1457 | "version": "1.2.1", 1458 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1459 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1460 | "license": "MIT", 1461 | "engines": { 1462 | "node": ">= 0.6" 1463 | } 1464 | }, 1465 | "node_modules/raw-body": { 1466 | "version": "3.0.0", 1467 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 1468 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 1469 | "license": "MIT", 1470 | "dependencies": { 1471 | "bytes": "3.1.2", 1472 | "http-errors": "2.0.0", 1473 | "iconv-lite": "0.6.3", 1474 | "unpipe": "1.0.0" 1475 | }, 1476 | "engines": { 1477 | "node": ">= 0.8" 1478 | } 1479 | }, 1480 | "node_modules/raw-body/node_modules/iconv-lite": { 1481 | "version": "0.6.3", 1482 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 1483 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 1484 | "license": "MIT", 1485 | "dependencies": { 1486 | "safer-buffer": ">= 2.1.2 < 3.0.0" 1487 | }, 1488 | "engines": { 1489 | "node": ">=0.10.0" 1490 | } 1491 | }, 1492 | "node_modules/real-require": { 1493 | "version": "0.2.0", 1494 | "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", 1495 | "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", 1496 | "license": "MIT", 1497 | "peer": true, 1498 | "engines": { 1499 | "node": ">= 12.13.0" 1500 | } 1501 | }, 1502 | "node_modules/rechoir": { 1503 | "version": "0.6.2", 1504 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 1505 | "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", 1506 | "dev": true, 1507 | "dependencies": { 1508 | "resolve": "^1.1.6" 1509 | }, 1510 | "engines": { 1511 | "node": ">= 0.10" 1512 | } 1513 | }, 1514 | "node_modules/resolve": { 1515 | "version": "1.22.10", 1516 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", 1517 | "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", 1518 | "dev": true, 1519 | "license": "MIT", 1520 | "dependencies": { 1521 | "is-core-module": "^2.16.0", 1522 | "path-parse": "^1.0.7", 1523 | "supports-preserve-symlinks-flag": "^1.0.0" 1524 | }, 1525 | "bin": { 1526 | "resolve": "bin/resolve" 1527 | }, 1528 | "engines": { 1529 | "node": ">= 0.4" 1530 | }, 1531 | "funding": { 1532 | "url": "https://github.com/sponsors/ljharb" 1533 | } 1534 | }, 1535 | "node_modules/router": { 1536 | "version": "2.1.0", 1537 | "resolved": "https://registry.npmjs.org/router/-/router-2.1.0.tgz", 1538 | "integrity": "sha512-/m/NSLxeYEgWNtyC+WtNHCF7jbGxOibVWKnn+1Psff4dJGOfoXP+MuC/f2CwSmyiHdOIzYnYFp4W6GxWfekaLA==", 1539 | "license": "MIT", 1540 | "dependencies": { 1541 | "is-promise": "^4.0.0", 1542 | "parseurl": "^1.3.3", 1543 | "path-to-regexp": "^8.0.0" 1544 | }, 1545 | "engines": { 1546 | "node": ">= 18" 1547 | } 1548 | }, 1549 | "node_modules/safe-buffer": { 1550 | "version": "5.2.1", 1551 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1552 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1553 | "funding": [ 1554 | { 1555 | "type": "github", 1556 | "url": "https://github.com/sponsors/feross" 1557 | }, 1558 | { 1559 | "type": "patreon", 1560 | "url": "https://www.patreon.com/feross" 1561 | }, 1562 | { 1563 | "type": "consulting", 1564 | "url": "https://feross.org/support" 1565 | } 1566 | ], 1567 | "license": "MIT" 1568 | }, 1569 | "node_modules/safe-stable-stringify": { 1570 | "version": "2.5.0", 1571 | "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", 1572 | "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", 1573 | "license": "MIT", 1574 | "peer": true, 1575 | "engines": { 1576 | "node": ">=10" 1577 | } 1578 | }, 1579 | "node_modules/safer-buffer": { 1580 | "version": "2.1.2", 1581 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1582 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1583 | "license": "MIT" 1584 | }, 1585 | "node_modules/secure-json-parse": { 1586 | "version": "2.7.0", 1587 | "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", 1588 | "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", 1589 | "license": "BSD-3-Clause", 1590 | "peer": true 1591 | }, 1592 | "node_modules/send": { 1593 | "version": "1.1.0", 1594 | "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz", 1595 | "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==", 1596 | "license": "MIT", 1597 | "dependencies": { 1598 | "debug": "^4.3.5", 1599 | "destroy": "^1.2.0", 1600 | "encodeurl": "^2.0.0", 1601 | "escape-html": "^1.0.3", 1602 | "etag": "^1.8.1", 1603 | "fresh": "^0.5.2", 1604 | "http-errors": "^2.0.0", 1605 | "mime-types": "^2.1.35", 1606 | "ms": "^2.1.3", 1607 | "on-finished": "^2.4.1", 1608 | "range-parser": "^1.2.1", 1609 | "statuses": "^2.0.1" 1610 | }, 1611 | "engines": { 1612 | "node": ">= 18" 1613 | } 1614 | }, 1615 | "node_modules/send/node_modules/fresh": { 1616 | "version": "0.5.2", 1617 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1618 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 1619 | "license": "MIT", 1620 | "engines": { 1621 | "node": ">= 0.6" 1622 | } 1623 | }, 1624 | "node_modules/send/node_modules/mime-db": { 1625 | "version": "1.52.0", 1626 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1627 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1628 | "license": "MIT", 1629 | "engines": { 1630 | "node": ">= 0.6" 1631 | } 1632 | }, 1633 | "node_modules/send/node_modules/mime-types": { 1634 | "version": "2.1.35", 1635 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1636 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1637 | "license": "MIT", 1638 | "dependencies": { 1639 | "mime-db": "1.52.0" 1640 | }, 1641 | "engines": { 1642 | "node": ">= 0.6" 1643 | } 1644 | }, 1645 | "node_modules/send/node_modules/ms": { 1646 | "version": "2.1.3", 1647 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1648 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1649 | "license": "MIT" 1650 | }, 1651 | "node_modules/serve-static": { 1652 | "version": "2.1.0", 1653 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.1.0.tgz", 1654 | "integrity": "sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==", 1655 | "license": "MIT", 1656 | "dependencies": { 1657 | "encodeurl": "^2.0.0", 1658 | "escape-html": "^1.0.3", 1659 | "parseurl": "^1.3.3", 1660 | "send": "^1.0.0" 1661 | }, 1662 | "engines": { 1663 | "node": ">= 18" 1664 | } 1665 | }, 1666 | "node_modules/setprototypeof": { 1667 | "version": "1.2.0", 1668 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1669 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 1670 | "license": "ISC" 1671 | }, 1672 | "node_modules/shelljs": { 1673 | "version": "0.8.5", 1674 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", 1675 | "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", 1676 | "dev": true, 1677 | "license": "BSD-3-Clause", 1678 | "dependencies": { 1679 | "glob": "^7.0.0", 1680 | "interpret": "^1.0.0", 1681 | "rechoir": "^0.6.2" 1682 | }, 1683 | "bin": { 1684 | "shjs": "bin/shjs" 1685 | }, 1686 | "engines": { 1687 | "node": ">=4" 1688 | } 1689 | }, 1690 | "node_modules/shx": { 1691 | "version": "0.3.4", 1692 | "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", 1693 | "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", 1694 | "dev": true, 1695 | "license": "MIT", 1696 | "dependencies": { 1697 | "minimist": "^1.2.3", 1698 | "shelljs": "^0.8.5" 1699 | }, 1700 | "bin": { 1701 | "shx": "lib/cli.js" 1702 | }, 1703 | "engines": { 1704 | "node": ">=6" 1705 | } 1706 | }, 1707 | "node_modules/side-channel": { 1708 | "version": "1.1.0", 1709 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", 1710 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", 1711 | "license": "MIT", 1712 | "dependencies": { 1713 | "es-errors": "^1.3.0", 1714 | "object-inspect": "^1.13.3", 1715 | "side-channel-list": "^1.0.0", 1716 | "side-channel-map": "^1.0.1", 1717 | "side-channel-weakmap": "^1.0.2" 1718 | }, 1719 | "engines": { 1720 | "node": ">= 0.4" 1721 | }, 1722 | "funding": { 1723 | "url": "https://github.com/sponsors/ljharb" 1724 | } 1725 | }, 1726 | "node_modules/side-channel-list": { 1727 | "version": "1.0.0", 1728 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", 1729 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", 1730 | "license": "MIT", 1731 | "dependencies": { 1732 | "es-errors": "^1.3.0", 1733 | "object-inspect": "^1.13.3" 1734 | }, 1735 | "engines": { 1736 | "node": ">= 0.4" 1737 | }, 1738 | "funding": { 1739 | "url": "https://github.com/sponsors/ljharb" 1740 | } 1741 | }, 1742 | "node_modules/side-channel-map": { 1743 | "version": "1.0.1", 1744 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", 1745 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", 1746 | "license": "MIT", 1747 | "dependencies": { 1748 | "call-bound": "^1.0.2", 1749 | "es-errors": "^1.3.0", 1750 | "get-intrinsic": "^1.2.5", 1751 | "object-inspect": "^1.13.3" 1752 | }, 1753 | "engines": { 1754 | "node": ">= 0.4" 1755 | }, 1756 | "funding": { 1757 | "url": "https://github.com/sponsors/ljharb" 1758 | } 1759 | }, 1760 | "node_modules/side-channel-weakmap": { 1761 | "version": "1.0.2", 1762 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", 1763 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", 1764 | "license": "MIT", 1765 | "dependencies": { 1766 | "call-bound": "^1.0.2", 1767 | "es-errors": "^1.3.0", 1768 | "get-intrinsic": "^1.2.5", 1769 | "object-inspect": "^1.13.3", 1770 | "side-channel-map": "^1.0.1" 1771 | }, 1772 | "engines": { 1773 | "node": ">= 0.4" 1774 | }, 1775 | "funding": { 1776 | "url": "https://github.com/sponsors/ljharb" 1777 | } 1778 | }, 1779 | "node_modules/sonic-boom": { 1780 | "version": "4.2.0", 1781 | "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", 1782 | "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==", 1783 | "license": "MIT", 1784 | "peer": true, 1785 | "dependencies": { 1786 | "atomic-sleep": "^1.0.0" 1787 | } 1788 | }, 1789 | "node_modules/split2": { 1790 | "version": "4.2.0", 1791 | "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", 1792 | "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", 1793 | "license": "ISC", 1794 | "peer": true, 1795 | "engines": { 1796 | "node": ">= 10.x" 1797 | } 1798 | }, 1799 | "node_modules/statuses": { 1800 | "version": "2.0.1", 1801 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1802 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1803 | "license": "MIT", 1804 | "engines": { 1805 | "node": ">= 0.8" 1806 | } 1807 | }, 1808 | "node_modules/strip-json-comments": { 1809 | "version": "3.1.1", 1810 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1811 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1812 | "license": "MIT", 1813 | "peer": true, 1814 | "engines": { 1815 | "node": ">=8" 1816 | }, 1817 | "funding": { 1818 | "url": "https://github.com/sponsors/sindresorhus" 1819 | } 1820 | }, 1821 | "node_modules/supports-preserve-symlinks-flag": { 1822 | "version": "1.0.0", 1823 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1824 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1825 | "dev": true, 1826 | "license": "MIT", 1827 | "engines": { 1828 | "node": ">= 0.4" 1829 | }, 1830 | "funding": { 1831 | "url": "https://github.com/sponsors/ljharb" 1832 | } 1833 | }, 1834 | "node_modules/thread-stream": { 1835 | "version": "3.1.0", 1836 | "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", 1837 | "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", 1838 | "license": "MIT", 1839 | "peer": true, 1840 | "dependencies": { 1841 | "real-require": "^0.2.0" 1842 | } 1843 | }, 1844 | "node_modules/toidentifier": { 1845 | "version": "1.0.1", 1846 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1847 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 1848 | "license": "MIT", 1849 | "engines": { 1850 | "node": ">=0.6" 1851 | } 1852 | }, 1853 | "node_modules/tr46": { 1854 | "version": "0.0.3", 1855 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 1856 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", 1857 | "license": "MIT" 1858 | }, 1859 | "node_modules/type-is": { 1860 | "version": "2.0.0", 1861 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.0.tgz", 1862 | "integrity": "sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==", 1863 | "license": "MIT", 1864 | "dependencies": { 1865 | "content-type": "^1.0.5", 1866 | "media-typer": "^1.1.0", 1867 | "mime-types": "^3.0.0" 1868 | }, 1869 | "engines": { 1870 | "node": ">= 0.6" 1871 | } 1872 | }, 1873 | "node_modules/typescript": { 1874 | "version": "5.8.2", 1875 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", 1876 | "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", 1877 | "dev": true, 1878 | "license": "Apache-2.0", 1879 | "bin": { 1880 | "tsc": "bin/tsc", 1881 | "tsserver": "bin/tsserver" 1882 | }, 1883 | "engines": { 1884 | "node": ">=14.17" 1885 | } 1886 | }, 1887 | "node_modules/undici-types": { 1888 | "version": "5.26.5", 1889 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 1890 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 1891 | "license": "MIT" 1892 | }, 1893 | "node_modules/unpipe": { 1894 | "version": "1.0.0", 1895 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1896 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 1897 | "license": "MIT", 1898 | "engines": { 1899 | "node": ">= 0.8" 1900 | } 1901 | }, 1902 | "node_modules/utils-merge": { 1903 | "version": "1.0.1", 1904 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1905 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 1906 | "license": "MIT", 1907 | "engines": { 1908 | "node": ">= 0.4.0" 1909 | } 1910 | }, 1911 | "node_modules/vary": { 1912 | "version": "1.1.2", 1913 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1914 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 1915 | "license": "MIT", 1916 | "engines": { 1917 | "node": ">= 0.8" 1918 | } 1919 | }, 1920 | "node_modules/web-streams-polyfill": { 1921 | "version": "4.0.0-beta.3", 1922 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", 1923 | "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", 1924 | "license": "MIT", 1925 | "engines": { 1926 | "node": ">= 14" 1927 | } 1928 | }, 1929 | "node_modules/webidl-conversions": { 1930 | "version": "3.0.1", 1931 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 1932 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", 1933 | "license": "BSD-2-Clause" 1934 | }, 1935 | "node_modules/whatwg-url": { 1936 | "version": "5.0.0", 1937 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 1938 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 1939 | "license": "MIT", 1940 | "dependencies": { 1941 | "tr46": "~0.0.3", 1942 | "webidl-conversions": "^3.0.0" 1943 | } 1944 | }, 1945 | "node_modules/wrappy": { 1946 | "version": "1.0.2", 1947 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1948 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1949 | "license": "ISC" 1950 | }, 1951 | "node_modules/ws": { 1952 | "version": "8.18.1", 1953 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", 1954 | "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", 1955 | "license": "MIT", 1956 | "engines": { 1957 | "node": ">=10.0.0" 1958 | }, 1959 | "peerDependencies": { 1960 | "bufferutil": "^4.0.1", 1961 | "utf-8-validate": ">=5.0.2" 1962 | }, 1963 | "peerDependenciesMeta": { 1964 | "bufferutil": { 1965 | "optional": true 1966 | }, 1967 | "utf-8-validate": { 1968 | "optional": true 1969 | } 1970 | } 1971 | }, 1972 | "node_modules/zod": { 1973 | "version": "3.24.2", 1974 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", 1975 | "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", 1976 | "license": "MIT", 1977 | "funding": { 1978 | "url": "https://github.com/sponsors/colinhacks" 1979 | } 1980 | }, 1981 | "node_modules/zod-to-json-schema": { 1982 | "version": "3.24.3", 1983 | "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.3.tgz", 1984 | "integrity": "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A==", 1985 | "license": "ISC", 1986 | "peerDependencies": { 1987 | "zod": "^3.24.1" 1988 | } 1989 | } 1990 | } 1991 | } 1992 | -------------------------------------------------------------------------------- /stagehand/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@browserbasehq/mcp-stagehand", 3 | "version": "0.5.1", 4 | "description": "MCP server for AI web browser automation using Stagehand", 5 | "license": "MIT", 6 | "author": "Browserbase, Inc. (https://www.browserbase.com/)", 7 | "homepage": "https://modelcontextprotocol.io", 8 | "bugs": "https://github.com/modelcontextprotocol/servers/issues", 9 | "type": "module", 10 | "bin": { 11 | "mcp-server-stagehand": "dist/index.js" 12 | }, 13 | "files": [ 14 | "dist" 15 | ], 16 | "scripts": { 17 | "build": "tsc && shx chmod +x dist/*.js", 18 | "prepare": "npm run build", 19 | "watch": "tsc --watch" 20 | }, 21 | "dependencies": { 22 | "@browserbasehq/sdk": "^2.0.0", 23 | "@browserbasehq/stagehand": "^2.0.0", 24 | "@modelcontextprotocol/sdk": "^1.0.3", 25 | "@modelcontextprotocol/server-stagehand": "file:", 26 | "@playwright/test": "^1.49.0" 27 | }, 28 | "devDependencies": { 29 | "shx": "^0.3.4", 30 | "typescript": "^5.6.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /stagehand/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 4 | import { createServer } from "./server.js"; 5 | import { ensureLogDirectory, registerExitHandlers, scheduleLogRotation, setupLogRotation } from "./logging.js"; 6 | 7 | // Run setup for logging 8 | ensureLogDirectory(); 9 | setupLogRotation(); 10 | scheduleLogRotation(); 11 | registerExitHandlers(); 12 | 13 | // Run the server 14 | async function runServer() { 15 | const server = createServer(); 16 | const transport = new StdioServerTransport(); 17 | await server.connect(transport); 18 | server.sendLoggingMessage({ 19 | level: "info", 20 | data: "Stagehand MCP server is ready to accept requests", 21 | }); 22 | } 23 | 24 | runServer().catch((error) => { 25 | const errorMsg = error instanceof Error ? error.message : String(error); 26 | console.error(errorMsg); 27 | }); 28 | -------------------------------------------------------------------------------- /stagehand/src/logging.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import { fileURLToPath } from 'url'; 4 | import type { LogLine } from "@browserbasehq/stagehand"; 5 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 6 | 7 | // Get the directory name for the current module 8 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); 9 | 10 | // Configure logging 11 | const LOG_DIR = path.join(__dirname, '../logs'); 12 | const LOG_FILE = path.join(LOG_DIR, `stagehand-${new Date().toISOString().split('T')[0]}.log`); 13 | const MAX_LOG_FILES = 10; // Maximum number of log files to keep 14 | const MAX_LOG_SIZE = 10 * 1024 * 1024; // 10MB max log file size 15 | 16 | // Queue for batching log writes 17 | let logQueue: string[] = []; 18 | let logWriteTimeout: NodeJS.Timeout | null = null; 19 | const LOG_FLUSH_INTERVAL = 1000; // Flush logs every second 20 | const MAX_OPERATION_LOGS = 1000; // Prevent operation logs from growing too large 21 | 22 | // Operation logs stored in memory 23 | export const operationLogs: string[] = []; 24 | export const consoleLogs: string[] = []; 25 | 26 | // Reference to server instance for logging 27 | let serverInstance: Server | undefined; 28 | 29 | // Set server for logging 30 | export function setServerInstance(server: Server) { 31 | serverInstance = server; 32 | } 33 | 34 | // Get server instance for notifications and logging 35 | export function getServerInstance() { 36 | return serverInstance; 37 | } 38 | 39 | // Ensure log directory exists 40 | export function ensureLogDirectory() { 41 | if (!fs.existsSync(LOG_DIR)) { 42 | fs.mkdirSync(LOG_DIR, { recursive: true }); 43 | } 44 | } 45 | 46 | // Setup log rotation management 47 | export function setupLogRotation() { 48 | try { 49 | // Check if current log file exceeds max size 50 | if (fs.existsSync(LOG_FILE) && fs.statSync(LOG_FILE).size > MAX_LOG_SIZE) { 51 | const timestamp = new Date().toISOString().replace(/:/g, '-'); 52 | const rotatedLogFile = path.join(LOG_DIR, `stagehand-${timestamp}.log`); 53 | fs.renameSync(LOG_FILE, rotatedLogFile); 54 | } 55 | 56 | // Clean up old log files if we have too many 57 | const logFiles = fs.readdirSync(LOG_DIR) 58 | .filter(file => file.startsWith('stagehand-') && file.endsWith('.log')) 59 | .map(file => path.join(LOG_DIR, file)) 60 | .sort((a, b) => fs.statSync(b).mtime.getTime() - fs.statSync(a).mtime.getTime()); 61 | 62 | if (logFiles.length > MAX_LOG_FILES) { 63 | logFiles.slice(MAX_LOG_FILES).forEach(file => { 64 | try { 65 | fs.unlinkSync(file); 66 | } catch (err) { 67 | console.error(`Failed to delete old log file ${file}:`, err); 68 | } 69 | }); 70 | } 71 | } catch (err) { 72 | console.error('Error in log rotation:', err); 73 | } 74 | } 75 | 76 | // Flush logs to disk asynchronously 77 | export async function flushLogs() { 78 | if (logQueue.length === 0) return; 79 | 80 | const logsToWrite = logQueue.join('\n') + '\n'; 81 | logQueue = []; 82 | logWriteTimeout = null; 83 | 84 | try { 85 | await fs.promises.appendFile(LOG_FILE, logsToWrite); 86 | 87 | // Check if we need to rotate logs after write 88 | const stats = await fs.promises.stat(LOG_FILE); 89 | if (stats.size > MAX_LOG_SIZE) { 90 | setupLogRotation(); 91 | } 92 | } catch (err) { 93 | console.error('Failed to write logs to file:', err); 94 | // If write fails, try to use sync version as fallback 95 | try { 96 | fs.appendFileSync(LOG_FILE, logsToWrite); 97 | } catch (syncErr) { 98 | console.error('Failed to write logs synchronously:', syncErr); 99 | } 100 | } 101 | } 102 | 103 | // Helper function to convert LogLine to string 104 | export function logLineToString(logLine: LogLine): string { 105 | const timestamp = logLine.timestamp ? new Date(logLine.timestamp).toISOString() : new Date().toISOString(); 106 | const level = logLine.level !== undefined ? 107 | (logLine.level === 0 ? 'DEBUG' : 108 | logLine.level === 1 ? 'INFO' : 109 | logLine.level === 2 ? 'ERROR' : 'UNKNOWN') : 'UNKNOWN'; 110 | return `[${timestamp}] [${level}] ${logLine.message || ''}`; 111 | } 112 | 113 | // Main logging function 114 | export function log(message: string, level: 'info' | 'error' | 'debug' = 'info') { 115 | const timestamp = new Date().toISOString(); 116 | const logMessage = `[${timestamp}] [${level.toUpperCase()}] ${message}`; 117 | 118 | // Manage operation logs with size limit 119 | operationLogs.push(logMessage); 120 | if (operationLogs.length > MAX_OPERATION_LOGS) { 121 | // Keep most recent logs but trim the middle to maintain context 122 | const half = Math.floor(MAX_OPERATION_LOGS / 2); 123 | // Keep first 100 and last (MAX_OPERATION_LOGS - 100) logs 124 | const firstLogs = operationLogs.slice(0, 100); 125 | const lastLogs = operationLogs.slice(operationLogs.length - (MAX_OPERATION_LOGS - 100)); 126 | operationLogs.length = 0; 127 | operationLogs.push(...firstLogs); 128 | operationLogs.push(`[...${operationLogs.length - MAX_OPERATION_LOGS} logs truncated...]`); 129 | operationLogs.push(...lastLogs); 130 | } 131 | 132 | // Queue log for async writing 133 | logQueue.push(logMessage); 134 | 135 | // Setup timer to flush logs if not already scheduled 136 | if (!logWriteTimeout) { 137 | logWriteTimeout = setTimeout(flushLogs, LOG_FLUSH_INTERVAL); 138 | } 139 | 140 | // Console output to stderr for debugging 141 | if (process.env.DEBUG || level === 'error') { 142 | console.error(logMessage); 143 | } 144 | 145 | // Send logging message to client for important events 146 | if (serverInstance && (level === 'info' || level === 'error')) { 147 | serverInstance.sendLoggingMessage({ 148 | level: level, 149 | data: message, 150 | }); 151 | } 152 | } 153 | 154 | // Format logs for response 155 | export function formatLogResponse(logs: string[]): string { 156 | if (logs.length <= 100) { 157 | return logs.join("\n"); 158 | } 159 | 160 | // For very long logs, include first and last parts with truncation notice 161 | const first = logs.slice(0, 50); 162 | const last = logs.slice(-50); 163 | return [ 164 | ...first, 165 | `\n... ${logs.length - 100} more log entries (truncated) ...\n`, 166 | ...last 167 | ].join("\n"); 168 | } 169 | 170 | // Log request 171 | export function logRequest(type: string, params: any) { 172 | const requestLog = { 173 | timestamp: new Date().toISOString(), 174 | type, 175 | params, 176 | }; 177 | log(`REQUEST: ${JSON.stringify(requestLog, null, 2)}`, 'debug'); 178 | } 179 | 180 | // Log response 181 | export function logResponse(type: string, response: any) { 182 | const responseLog = { 183 | timestamp: new Date().toISOString(), 184 | type, 185 | response, 186 | }; 187 | log(`RESPONSE: ${JSON.stringify(responseLog, null, 2)}`, 'debug'); 188 | } 189 | 190 | // Register handlers for process exit 191 | export function registerExitHandlers() { 192 | // Make sure logs are flushed when the process exits 193 | process.on('exit', () => { 194 | if (logQueue.length > 0) { 195 | try { 196 | fs.appendFileSync(LOG_FILE, logQueue.join('\n') + '\n'); 197 | } catch (err) { 198 | console.error('Failed to flush logs on exit:', err); 199 | } 200 | } 201 | }); 202 | 203 | process.on('SIGINT', () => { 204 | // Flush logs and exit 205 | if (logQueue.length > 0) { 206 | try { 207 | fs.appendFileSync(LOG_FILE, logQueue.join('\n') + '\n'); 208 | } catch (err) { 209 | console.error('Failed to flush logs on SIGINT:', err); 210 | } 211 | } 212 | process.exit(0); 213 | }); 214 | } 215 | 216 | // Schedule periodic log rotation 217 | export function scheduleLogRotation() { 218 | // Add log rotation check periodically 219 | setInterval(() => { 220 | setupLogRotation(); 221 | }, 15 * 60 * 1000); // Check every 15 minutes 222 | } -------------------------------------------------------------------------------- /stagehand/src/prompts.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Prompts module for the Stagehand MCP server 3 | * Contains prompts definitions and handlers for prompt-related requests 4 | */ 5 | 6 | // Define the prompts 7 | export const PROMPTS = [ 8 | { 9 | name: "click_search_button", 10 | description: "A prompt template for clicking on a search button", 11 | arguments: [] // No arguments required for this specific prompt 12 | } 13 | ]; 14 | 15 | /** 16 | * Get a prompt by name 17 | * @param name The name of the prompt to retrieve 18 | * @returns The prompt definition or throws an error if not found 19 | */ 20 | export function getPrompt(name: string) { 21 | if (name === "click_search_button") { 22 | return { 23 | description: "This prompt provides instructions for clicking on a search button", 24 | messages: [ 25 | { 26 | role: "user", 27 | content: { 28 | type: "text", 29 | text: "Please click on the search button" 30 | } 31 | } 32 | ] 33 | }; 34 | } 35 | 36 | throw new Error(`Invalid prompt name: ${name}`); 37 | } -------------------------------------------------------------------------------- /stagehand/src/resources.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Resources module for the Stagehand MCP server 3 | * Contains resources definitions and handlers for resource-related requests 4 | */ 5 | 6 | // Define the resources 7 | export const RESOURCES = []; 8 | 9 | // Define the resource templates 10 | export const RESOURCE_TEMPLATES = []; 11 | 12 | // Store screenshots in a map 13 | export const screenshots = new Map(); 14 | 15 | /** 16 | * Handle listing resources request 17 | * @returns A list of available resources including screenshots 18 | */ 19 | export function listResources() { 20 | return { 21 | resources: [ 22 | ...Array.from(screenshots.keys()).map((name) => ({ 23 | uri: `screenshot://${name}`, 24 | mimeType: "image/png", 25 | name: `Screenshot: ${name}`, 26 | })), 27 | ] 28 | }; 29 | } 30 | 31 | /** 32 | * Handle listing resource templates request 33 | * @returns An empty resource templates list response 34 | */ 35 | export function listResourceTemplates() { 36 | return { resourceTemplates: [] }; 37 | } 38 | 39 | /** 40 | * Read a resource by its URI 41 | * @param uri The URI of the resource to read 42 | * @returns The resource content or throws if not found 43 | */ 44 | export function readResource(uri: string) { 45 | if (uri.startsWith("screenshot://")) { 46 | const name = uri.split("://")[1]; 47 | const screenshot = screenshots.get(name); 48 | if (screenshot) { 49 | return { 50 | contents: [ 51 | { 52 | uri, 53 | mimeType: "image/png", 54 | blob: screenshot, 55 | }, 56 | ], 57 | }; 58 | } 59 | } 60 | 61 | throw new Error(`Resource not found: ${uri}`); 62 | } -------------------------------------------------------------------------------- /stagehand/src/server.ts: -------------------------------------------------------------------------------- 1 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 2 | import { 3 | CallToolRequestSchema, 4 | ListToolsRequestSchema, 5 | ListResourcesRequestSchema, 6 | ListResourceTemplatesRequestSchema, 7 | ListPromptsRequestSchema, 8 | GetPromptRequestSchema, 9 | ReadResourceRequestSchema, 10 | } from "@modelcontextprotocol/sdk/types.js"; 11 | import { Stagehand } from "@browserbasehq/stagehand"; 12 | import type { ConstructorParams } from "@browserbasehq/stagehand"; 13 | 14 | import { sanitizeMessage } from "./utils.js"; 15 | import { 16 | log, 17 | logRequest, 18 | logResponse, 19 | operationLogs, 20 | setServerInstance, 21 | } from "./logging.js"; 22 | import { TOOLS, handleToolCall } from "./tools.js"; 23 | import { PROMPTS, getPrompt } from "./prompts.js"; 24 | import { 25 | listResources, 26 | listResourceTemplates, 27 | readResource, 28 | } from "./resources.js"; 29 | 30 | // Define Stagehand configuration 31 | export const stagehandConfig: ConstructorParams = { 32 | env: 33 | process.env.BROWSERBASE_API_KEY && process.env.BROWSERBASE_PROJECT_ID 34 | ? "BROWSERBASE" 35 | : "LOCAL", 36 | apiKey: process.env.BROWSERBASE_API_KEY /* API key for authentication */, 37 | projectId: process.env.BROWSERBASE_PROJECT_ID /* Project identifier */, 38 | logger: (message) => 39 | console.error( 40 | logLineToString(message) 41 | ) /* Custom logging function to stderr */, 42 | domSettleTimeoutMs: 30_000 /* Timeout for DOM to settle in milliseconds */, 43 | browserbaseSessionCreateParams: 44 | process.env.BROWSERBASE_API_KEY && process.env.BROWSERBASE_PROJECT_ID 45 | ? { 46 | projectId: process.env.BROWSERBASE_PROJECT_ID!, 47 | browserSettings: process.env.CONTEXT_ID 48 | ? { 49 | context: { 50 | id: process.env.CONTEXT_ID, 51 | persist: true, 52 | }, 53 | } 54 | : undefined, 55 | } 56 | : undefined, 57 | localBrowserLaunchOptions: process.env.LOCAL_CDP_URL 58 | ? { 59 | cdpUrl: process.env.LOCAL_CDP_URL, 60 | } 61 | : undefined, 62 | enableCaching: true /* Enable caching functionality */, 63 | browserbaseSessionID: 64 | undefined /* Session ID for resuming Browserbase sessions */, 65 | modelName: "gpt-4o" /* Name of the model to use */, 66 | modelClientOptions: { 67 | apiKey: process.env.OPENAI_API_KEY, 68 | } /* Configuration options for the model client */, 69 | useAPI: false, 70 | }; 71 | 72 | // Global state 73 | let stagehand: Stagehand | undefined; 74 | 75 | // Ensure Stagehand is initialized 76 | export async function ensureStagehand() { 77 | if ( 78 | stagehandConfig.env === "LOCAL" && 79 | !stagehandConfig.localBrowserLaunchOptions?.cdpUrl 80 | ) { 81 | throw new Error( 82 | 'Using a local browser without providing a CDP URL is not supported. Please provide a CDP URL using the LOCAL_CDP_URL environment variable.\n\nTo launch your browser in "debug", see our documentation.\n\nhttps://docs.stagehand.dev/examples/customize_browser#use-your-personal-browser' 83 | ); 84 | } 85 | 86 | try { 87 | if (!stagehand) { 88 | stagehand = new Stagehand(stagehandConfig); 89 | await stagehand.init(); 90 | return stagehand; 91 | } 92 | 93 | // Try to perform a simple operation to check if the session is still valid 94 | try { 95 | await stagehand.page.evaluate(() => document.title); 96 | return stagehand; 97 | } catch (error) { 98 | // If we get an error indicating the session is invalid, reinitialize 99 | if ( 100 | error instanceof Error && 101 | (error.message.includes( 102 | "Target page, context or browser has been closed" 103 | ) || 104 | error.message.includes("Session expired") || 105 | error.message.includes("context destroyed")) 106 | ) { 107 | log("Browser session expired, reinitializing Stagehand...", "info"); 108 | stagehand = new Stagehand(stagehandConfig); 109 | await stagehand.init(); 110 | return stagehand; 111 | } 112 | throw error; // Re-throw if it's a different type of error 113 | } 114 | } catch (error) { 115 | const errorMsg = error instanceof Error ? error.message : String(error); 116 | log(`Failed to initialize/reinitialize Stagehand: ${errorMsg}`, "error"); 117 | throw error; 118 | } 119 | } 120 | 121 | // Create the server 122 | export function createServer() { 123 | const server = new Server( 124 | { 125 | name: "stagehand", 126 | version: "0.1.0", 127 | }, 128 | { 129 | capabilities: { 130 | resources: {}, 131 | tools: {}, 132 | logging: {}, 133 | prompts: {}, 134 | }, 135 | } 136 | ); 137 | 138 | // Store server instance for logging 139 | setServerInstance(server); 140 | 141 | // Setup request handlers 142 | server.setRequestHandler(ListToolsRequestSchema, async (request) => { 143 | try { 144 | logRequest("ListTools", request.params); 145 | const response = { tools: TOOLS }; 146 | const sanitizedResponse = sanitizeMessage(response); 147 | logResponse("ListTools", JSON.parse(sanitizedResponse)); 148 | return JSON.parse(sanitizedResponse); 149 | } catch (error) { 150 | const errorMsg = error instanceof Error ? error.message : String(error); 151 | return { 152 | error: { 153 | code: -32603, 154 | message: `Internal error: ${errorMsg}`, 155 | }, 156 | }; 157 | } 158 | }); 159 | 160 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 161 | try { 162 | logRequest("CallTool", request.params); 163 | operationLogs.length = 0; // Clear logs for new operation 164 | 165 | if ( 166 | !request.params?.name || 167 | !TOOLS.find((t) => t.name === request.params.name) 168 | ) { 169 | throw new Error(`Invalid tool name: ${request.params?.name}`); 170 | } 171 | 172 | // Ensure Stagehand is initialized 173 | try { 174 | stagehand = await ensureStagehand(); 175 | } catch (error) { 176 | const errorMsg = error instanceof Error ? error.message : String(error); 177 | return { 178 | content: [ 179 | { 180 | type: "text", 181 | text: `Failed to initialize Stagehand: ${errorMsg}.\n\nConfig: ${JSON.stringify( 182 | stagehandConfig, 183 | null, 184 | 2 185 | )}`, 186 | }, 187 | { 188 | type: "text", 189 | text: `Operation logs:\n${operationLogs.join("\n")}`, 190 | }, 191 | ], 192 | isError: true, 193 | }; 194 | } 195 | 196 | const result = await handleToolCall( 197 | request.params.name, 198 | request.params.arguments ?? {}, 199 | stagehand 200 | ); 201 | 202 | const sanitizedResult = sanitizeMessage(result); 203 | logResponse("CallTool", JSON.parse(sanitizedResult)); 204 | return JSON.parse(sanitizedResult); 205 | } catch (error) { 206 | const errorMsg = error instanceof Error ? error.message : String(error); 207 | return { 208 | error: { 209 | code: -32603, 210 | message: `Internal error: ${errorMsg}`, 211 | }, 212 | }; 213 | } 214 | }); 215 | 216 | server.setRequestHandler(ListResourcesRequestSchema, async (request) => { 217 | try { 218 | logRequest("ListResources", request.params); 219 | const response = listResources(); 220 | const sanitizedResponse = sanitizeMessage(response); 221 | logResponse("ListResources", JSON.parse(sanitizedResponse)); 222 | return JSON.parse(sanitizedResponse); 223 | } catch (error) { 224 | const errorMsg = error instanceof Error ? error.message : String(error); 225 | return { 226 | error: { 227 | code: -32603, 228 | message: `Internal error: ${errorMsg}`, 229 | }, 230 | }; 231 | } 232 | }); 233 | 234 | server.setRequestHandler( 235 | ListResourceTemplatesRequestSchema, 236 | async (request) => { 237 | try { 238 | logRequest("ListResourceTemplates", request.params); 239 | const response = listResourceTemplates(); 240 | const sanitizedResponse = sanitizeMessage(response); 241 | logResponse("ListResourceTemplates", JSON.parse(sanitizedResponse)); 242 | return JSON.parse(sanitizedResponse); 243 | } catch (error) { 244 | const errorMsg = error instanceof Error ? error.message : String(error); 245 | return { 246 | error: { 247 | code: -32603, 248 | message: `Internal error: ${errorMsg}`, 249 | }, 250 | }; 251 | } 252 | } 253 | ); 254 | 255 | server.setRequestHandler(ReadResourceRequestSchema, async (request) => { 256 | try { 257 | logRequest("ReadResource", request.params); 258 | const uri = request.params.uri.toString(); 259 | const response = readResource(uri); 260 | const sanitizedResponse = sanitizeMessage(response); 261 | logResponse("ReadResource", JSON.parse(sanitizedResponse)); 262 | return JSON.parse(sanitizedResponse); 263 | } catch (error) { 264 | const errorMsg = error instanceof Error ? error.message : String(error); 265 | return { 266 | error: { 267 | code: -32603, 268 | message: `Internal error: ${errorMsg}`, 269 | }, 270 | }; 271 | } 272 | }); 273 | 274 | server.setRequestHandler(ListPromptsRequestSchema, async (request) => { 275 | try { 276 | logRequest("ListPrompts", request.params); 277 | const response = { prompts: PROMPTS }; 278 | const sanitizedResponse = sanitizeMessage(response); 279 | logResponse("ListPrompts", JSON.parse(sanitizedResponse)); 280 | return JSON.parse(sanitizedResponse); 281 | } catch (error) { 282 | const errorMsg = error instanceof Error ? error.message : String(error); 283 | return { 284 | error: { 285 | code: -32603, 286 | message: `Internal error: ${errorMsg}`, 287 | }, 288 | }; 289 | } 290 | }); 291 | 292 | server.setRequestHandler(GetPromptRequestSchema, async (request) => { 293 | try { 294 | logRequest("GetPrompt", request.params); 295 | 296 | // Check if prompt name is valid and get the prompt 297 | try { 298 | const prompt = getPrompt(request.params?.name || ""); 299 | const sanitizedResponse = sanitizeMessage(prompt); 300 | logResponse("GetPrompt", JSON.parse(sanitizedResponse)); 301 | return JSON.parse(sanitizedResponse); 302 | } catch (error) { 303 | throw new Error(`Invalid prompt name: ${request.params?.name}`); 304 | } 305 | } catch (error) { 306 | const errorMsg = error instanceof Error ? error.message : String(error); 307 | return { 308 | error: { 309 | code: -32603, 310 | message: `Internal error: ${errorMsg}`, 311 | }, 312 | }; 313 | } 314 | }); 315 | 316 | return server; 317 | } 318 | 319 | // Import missing function from logging 320 | import { formatLogResponse, logLineToString } from "./logging.js"; 321 | -------------------------------------------------------------------------------- /stagehand/src/tools.ts: -------------------------------------------------------------------------------- 1 | import { Stagehand } from "@browserbasehq/stagehand"; 2 | import { CallToolResult, Tool } from "@modelcontextprotocol/sdk/types.js"; 3 | import { getServerInstance, operationLogs } from "./logging.js"; 4 | import { screenshots } from "./resources.js"; 5 | 6 | // Define the Stagehand tools 7 | export const TOOLS: Tool[] = [ 8 | { 9 | name: "stagehand_navigate", 10 | description: 11 | "Navigate to a URL in the browser. Only use this tool with URLs you're confident will work and stay up to date. Otheriwse use https://google.com as the starting point", 12 | inputSchema: { 13 | type: "object", 14 | properties: { 15 | url: { type: "string", description: "The URL to navigate to" }, 16 | }, 17 | required: ["url"], 18 | }, 19 | }, 20 | { 21 | name: "stagehand_act", 22 | description: `Performs an action on a web page element. Act actions should be as atomic and 23 | specific as possible, i.e. "Click the sign in button" or "Type 'hello' into the search input". 24 | AVOID actions that are more than one step, i.e. "Order me pizza" or "Send an email to Paul 25 | asking him to call me". `, 26 | inputSchema: { 27 | type: "object", 28 | properties: { 29 | action: { 30 | type: "string", 31 | description: `The action to perform. Should be as atomic and specific as possible, 32 | i.e. 'Click the sign in button' or 'Type 'hello' into the search input'. AVOID actions that are more than one 33 | step, i.e. 'Order me pizza' or 'Send an email to Paul asking him to call me'. The instruction should be just as specific as possible, 34 | and have a strong correlation to the text on the page. If unsure, use observe before using act."`, 35 | }, 36 | variables: { 37 | type: "object", 38 | additionalProperties: true, 39 | description: `Variables used in the action template. ONLY use variables if you're dealing 40 | with sensitive data or dynamic content. For example, if you're logging in to a website, 41 | you can use a variable for the password. When using variables, you MUST have the variable 42 | key in the action template. For example: {"action": "Fill in the password", "variables": {"password": "123456"}}`, 43 | }, 44 | }, 45 | required: ["action"], 46 | }, 47 | }, 48 | { 49 | name: "stagehand_extract", 50 | description: `Extracts all of the text from the current page.`, 51 | inputSchema: { 52 | type: "object", 53 | properties: {}, 54 | }, 55 | }, 56 | { 57 | name: "stagehand_observe", 58 | description: 59 | "Observes elements on the web page. Use this tool to observe elements that you can later use in an action. Use observe instead of extract when dealing with actionable (interactable) elements rather than text. More often than not, you'll want to use extract instead of observe when dealing with scraping or extracting structured text.", 60 | inputSchema: { 61 | type: "object", 62 | properties: { 63 | instruction: { 64 | type: "string", 65 | description: 66 | "Instruction for observation (e.g., 'find the login button'). This instruction must be extremely specific.", 67 | }, 68 | }, 69 | required: ["instruction"], 70 | }, 71 | }, 72 | { 73 | name: "screenshot", 74 | description: 75 | "Takes a screenshot of the current page. Use this tool to learn where you are on the page when controlling the browser with Stagehand. Only use this tool when the other tools are not sufficient to get the information you need.", 76 | inputSchema: { 77 | type: "object", 78 | properties: {}, 79 | }, 80 | }, 81 | ]; 82 | 83 | // Handle tool calls 84 | export async function handleToolCall( 85 | name: string, 86 | args: any, 87 | stagehand: Stagehand 88 | ): Promise { 89 | switch (name) { 90 | case "stagehand_navigate": 91 | try { 92 | await stagehand.page.goto(args.url); 93 | return { 94 | content: [ 95 | { 96 | type: "text", 97 | text: `Navigated to: ${args.url}`, 98 | }, 99 | { 100 | type: "text", 101 | text: `View the live session here: https://browserbase.com/sessions/${stagehand.browserbaseSessionID}`, 102 | }, 103 | ], 104 | isError: false, 105 | }; 106 | } catch (error) { 107 | const errorMsg = error instanceof Error ? error.message : String(error); 108 | return { 109 | content: [ 110 | { 111 | type: "text", 112 | text: `Failed to navigate: ${errorMsg}`, 113 | }, 114 | { 115 | type: "text", 116 | text: `Operation logs:\n${operationLogs.join("\n")}`, 117 | }, 118 | ], 119 | isError: true, 120 | }; 121 | } 122 | 123 | case "stagehand_act": 124 | try { 125 | await stagehand.page.act({ 126 | action: args.action, 127 | variables: args.variables, 128 | }); 129 | return { 130 | content: [ 131 | { 132 | type: "text", 133 | text: `Action performed: ${args.action}`, 134 | }, 135 | ], 136 | isError: false, 137 | }; 138 | } catch (error) { 139 | const errorMsg = error instanceof Error ? error.message : String(error); 140 | return { 141 | content: [ 142 | { 143 | type: "text", 144 | text: `Failed to perform action: ${errorMsg}`, 145 | }, 146 | { 147 | type: "text", 148 | text: `Operation logs:\n${operationLogs.join("\n")}`, 149 | }, 150 | ], 151 | isError: true, 152 | }; 153 | } 154 | 155 | case "stagehand_extract": { 156 | try { 157 | const bodyText = await stagehand.page.evaluate( 158 | () => document.body.innerText 159 | ); 160 | const content = bodyText 161 | .split("\n") 162 | .map((line) => line.trim()) 163 | .filter((line) => { 164 | if (!line) return false; 165 | 166 | if ( 167 | (line.includes("{") && line.includes("}")) || 168 | line.includes("@keyframes") || // Remove CSS animations 169 | line.match(/^\.[a-zA-Z0-9_-]+\s*{/) || // Remove CSS lines starting with .className { 170 | line.match(/^[a-zA-Z-]+:[a-zA-Z0-9%\s\(\)\.,-]+;$/) // Remove lines like "color: blue;" or "margin: 10px;" 171 | ) { 172 | return false; 173 | } 174 | return true; 175 | }) 176 | .map((line) => { 177 | return line.replace(/\\u([0-9a-fA-F]{4})/g, (_, hex) => 178 | String.fromCharCode(parseInt(hex, 16)) 179 | ); 180 | }); 181 | 182 | return { 183 | content: [ 184 | { 185 | type: "text", 186 | text: `Extracted content:\n${content.join("\n")}`, 187 | }, 188 | ], 189 | isError: false, 190 | }; 191 | } catch (error) { 192 | return { 193 | content: [ 194 | { 195 | type: "text", 196 | text: `Failed to extract content: ${(error as Error).message}`, 197 | }, 198 | ], 199 | isError: true, 200 | }; 201 | } 202 | } 203 | 204 | case "stagehand_observe": 205 | try { 206 | const observations = await stagehand.page.observe({ 207 | instruction: args.instruction, 208 | returnAction: false, 209 | }); 210 | return { 211 | content: [ 212 | { 213 | type: "text", 214 | text: `Observations: ${JSON.stringify(observations)}`, 215 | }, 216 | ], 217 | isError: false, 218 | }; 219 | } catch (error) { 220 | const errorMsg = error instanceof Error ? error.message : String(error); 221 | return { 222 | content: [ 223 | { 224 | type: "text", 225 | text: `Failed to observe: ${errorMsg}`, 226 | }, 227 | { 228 | type: "text", 229 | text: `Operation logs:\n${operationLogs.join("\n")}`, 230 | }, 231 | ], 232 | isError: true, 233 | }; 234 | } 235 | 236 | case "screenshot": 237 | try { 238 | const screenshotBuffer = await stagehand.page.screenshot({ 239 | fullPage: false, 240 | }); 241 | 242 | // Convert buffer to base64 string and store in memory 243 | const screenshotBase64 = screenshotBuffer.toString("base64"); 244 | const name = `screenshot-${new Date() 245 | .toISOString() 246 | .replace(/:/g, "-")}`; 247 | screenshots.set(name, screenshotBase64); 248 | 249 | // Notify the client that the resources changed 250 | const serverInstance = getServerInstance(); 251 | if (serverInstance) { 252 | serverInstance.notification({ 253 | method: "notifications/resources/list_changed", 254 | }); 255 | } 256 | 257 | return { 258 | content: [ 259 | { 260 | type: "text", 261 | text: `Screenshot taken with name: ${name}`, 262 | }, 263 | { 264 | type: "image", 265 | data: screenshotBase64, 266 | mimeType: "image/png", 267 | }, 268 | ], 269 | isError: false, 270 | }; 271 | } catch (error) { 272 | const errorMsg = error instanceof Error ? error.message : String(error); 273 | return { 274 | content: [ 275 | { 276 | type: "text", 277 | text: `Failed to take screenshot: ${errorMsg}`, 278 | }, 279 | { 280 | type: "text", 281 | text: `Operation logs:\n${operationLogs.join("\n")}`, 282 | }, 283 | ], 284 | isError: true, 285 | }; 286 | } 287 | 288 | default: 289 | return { 290 | content: [ 291 | { 292 | type: "text", 293 | text: `Unknown tool: ${name}`, 294 | }, 295 | { 296 | type: "text", 297 | text: `Operation logs:\n${operationLogs.join("\n")}`, 298 | }, 299 | ], 300 | isError: true, 301 | }; 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /stagehand/src/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Sanitizes a message to ensure it's properly formatted JSON 3 | * @param message The message to sanitize 4 | * @returns A sanitized JSON string 5 | */ 6 | export function sanitizeMessage(message: any): string { 7 | try { 8 | // Ensure the message is properly stringified JSON 9 | if (typeof message === 'string') { 10 | JSON.parse(message); // Validate JSON structure 11 | return message; 12 | } 13 | return JSON.stringify(message); 14 | } catch (error) { 15 | return JSON.stringify({ 16 | jsonrpc: '2.0', 17 | error: { 18 | code: -32700, 19 | message: 'Parse error', 20 | }, 21 | id: null, 22 | }); 23 | } 24 | } -------------------------------------------------------------------------------- /stagehand/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "resolveJsonModule": true, 11 | "outDir": "dist", 12 | "rootDir": "src" 13 | }, 14 | "include": ["src/**/*.ts"], 15 | "exclude": ["node_modules"] 16 | } 17 | --------------------------------------------------------------------------------