diff --git a/.changeset/chatty-ravens-study.md b/.changeset/chatty-ravens-study.md
new file mode 100644
index 00000000000..3384061ac2b
--- /dev/null
+++ b/.changeset/chatty-ravens-study.md
@@ -0,0 +1,5 @@
+---
+"roo-cline": minor
+---
+
+Enabled Roo Cline to use puppeteer and connect to a current browser which is already authenticated to multiple sites.
\ No newline at end of file
diff --git a/.github/workflows/code-qa.yml b/.github/workflows/code-qa.yml
index de3f0540026..85b5208d524 100644
--- a/.github/workflows/code-qa.yml
+++ b/.github/workflows/code-qa.yml
@@ -7,6 +7,9 @@ on:
types: [opened, reopened, ready_for_review, synchronize]
branches: [main]
+env:
+ NODE_VERSION: '18'
+
jobs:
compile:
runs-on: ubuntu-latest
@@ -14,11 +17,23 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- - name: Setup Node.js
+ - name: Setup Node.js environment
uses: actions/setup-node@v4
with:
- node-version: '18'
- cache: 'npm'
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Cache node modules
+ id: cache-node-modules
+ uses: actions/cache@v4
+ env:
+ cache-name: cache-node-modules
+ with:
+ path: node_modules
+ key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-node-${{ env.NODE_VERSION }}-build-${{ env.cache-name }}-
+ ${{ runner.os }}-build-
+ ${{ runner.os }}-
- name: Install dependencies
run: npm run install:all
@@ -32,11 +47,23 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- - name: Setup Node.js
+ - name: Setup Node.js environment
uses: actions/setup-node@v4
with:
- node-version: '18'
- cache: 'npm'
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Cache node modules
+ id: cache-node-modules
+ uses: actions/cache@v4
+ env:
+ cache-name: cache-node-modules
+ with:
+ path: node_modules
+ key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-node-${{ env.NODE_VERSION }}-build-${{ env.cache-name }}-
+ ${{ runner.os }}-build-
+ ${{ runner.os }}-
- name: Install dependencies
run: npm run install:all
diff --git a/README.md b/README.md
index 63a500648dd..d16b88c3134 100644
--- a/README.md
+++ b/README.md
@@ -83,8 +83,6 @@ Subscribe to our [Github releases](https://github.com/RooVetGit/Roo-Cline/releas
---
-# Cline (prev. Claude Dev) – \#1 on OpenRouter
-
@@ -110,7 +108,7 @@ Subscribe to our [Github releases](https://github.com/RooVetGit/Roo-Cline/releas
Meet Cline, an AI assistant that can use your **CLI** a**N**d **E**ditor.
-Thanks to [Claude 3.5 Sonnet's agentic coding capabilities](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf), Cline can handle complex software development tasks step-by-step. With tools that let him create & edit files, explore large projects, use the browser, and execute terminal commands (after you grant permission), he can assist you in ways that go beyond code completion or tech support. Cline can even use the Model Context Protocol (MCP) to create new tools and extend his own capabilities. While autonomous AI scripts traditionally run in sandboxed environments, this extension provides a human-in-the-loop GUI to approve every file change and terminal command, providing a safe and accessible way to explore the potential of agentic AI.
+Thanks to [Claude 3.5 Sonnet's agentic coding capabilities](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf), Cline can handle complex software development tasks step-by-step. With tools that let him create & edit files, explore large projects, use the browser, and execute terminal commands (after you grant permission), he can assist you in ways that go beyond code completion or tech support. Cline can even use the Model Context Protocol (MCP) to create new tools and extend his own capabilities. While autonomous AI scripts traditionally run in sandboxed environments, this extension provides a human-in-the-loop GUI to approve every file change and terminal command, providing a safe and accessible way to explore the potential of agentic AI.
1. Enter your task and add images to convert mockups into functional apps or fix bugs with screenshots.
2. Cline starts by analyzing your file structure & source code ASTs, running regex searches, and reading relevant files to get up to speed in existing projects. By carefully managing what information is added to context, Cline can provide valuable assistance even for large, complex projects without overwhelming the context window.
@@ -143,7 +141,7 @@ The extension also keeps track of total tokens and API usage cost for the entire
Thanks to the new [shell integration updates in VSCode v1.93](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api), Cline can execute commands directly in your terminal and receive the output. This allows him to perform a wide range of tasks, from installing packages and running build scripts to deploying applications, managing databases, and executing tests, all while adapting to your dev environment & toolchain to get the job done right.
-For long running processes like dev servers, use the "Proceed While Running" button to let Cline continue in the task while the command runs in the background. As Cline works he’ll be notified of any new terminal output along the way, letting him react to issues that may come up, such as compile-time errors when editing files.
+For long running processes like dev servers, use the "Proceed While Running" button to let Cline continue in the task while the command runs in the background. As Cline works he'll be notified of any new terminal output along the way, letting him react to issues that may come up, such as compile-time errors when editing files.
@@ -191,13 +189,13 @@ Thanks to the [Model Context Protocol](https://github.com/modelcontextprotocol),
### Add Context
-**`@url`:** Paste in a URL for the extension to fetch and convert to markdown, useful when you want to give Cline the latest docs
+**`@url`:** Paste in a URL for the extension to fetch and convert to markdown, useful when you want to give Cline the latest docs
-**`@problems`:** Add workspace errors and warnings ('Problems' panel) for Cline to fix
+**`@problems`:** Add workspace errors and warnings ('Problems' panel) for Cline to fix
-**`@file`:** Adds a file's contents so you don't have to waste API requests approving read file (+ type to search files)
+**`@file`:** Adds a file's contents so you don't have to waste API requests approving read file (+ type to search files)
-**`@folder`:** Adds folder's files all at once to speed up your workflow even more
+**`@folder`:** Adds folder's files all at once to speed up your workflow even more
## Contributing
diff --git a/package-lock.json b/package-lock.json
index 30da4c04ccc..135389d8da9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -34,13 +34,14 @@
"os-name": "^6.0.0",
"p-wait-for": "^5.0.2",
"pdf-parse": "^1.1.1",
- "puppeteer-chromium-resolver": "^23.0.0",
- "puppeteer-core": "^23.4.0",
+ "play-sound": "^1.1.6",
+ "puppeteer": "^23.9.0",
"serialize-error": "^11.0.3",
"sound-play": "^1.1.0",
"strip-ansi": "^7.1.0",
"tree-sitter-wasms": "^0.1.11",
"turndown": "^7.2.0",
+ "vsce": "^2.15.0",
"web-tree-sitter": "^0.22.6",
"zod": "^3.23.8"
},
@@ -2213,7 +2214,7 @@
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
"integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.25.9",
"js-tokens": "^4.0.0",
@@ -2364,7 +2365,7 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@@ -4308,27 +4309,6 @@
"node": ">=14"
}
},
- "node_modules/@puppeteer/browsers": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.5.0.tgz",
- "integrity": "sha512-6TQAc/5uRILE6deixJ1CR8rXyTbzXIXNgO1D0Woi9Bqicz2FV5iKP3BHYEg6o4UATCMcbQQ0jbmeaOkn/HQk2w==",
- "dependencies": {
- "debug": "^4.3.7",
- "extract-zip": "^2.0.1",
- "progress": "^2.0.3",
- "proxy-agent": "^6.4.0",
- "semver": "^7.6.3",
- "tar-fs": "^3.0.6",
- "unbzip2-stream": "^1.4.3",
- "yargs": "^17.7.2"
- },
- "bin": {
- "browsers": "lib/cjs/main-cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/@sinclair/typebox": {
"version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
@@ -6625,16 +6605,11 @@
"node": ">= 8"
}
},
- "node_modules/aproba": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
- "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
- },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "license": "Python-2.0"
},
"node_modules/array-buffer-byte-length": {
"version": "1.0.1",
@@ -6735,6 +6710,15 @@
"proxy-from-env": "^1.1.0"
}
},
+ "node_modules/azure-devops-node-api": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.2.0.tgz",
+ "integrity": "sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA==",
+ "dependencies": {
+ "tunnel": "0.0.6",
+ "typed-rest-client": "^1.8.4"
+ }
+ },
"node_modules/b4a": {
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
@@ -6872,7 +6856,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
+ "license": "MIT"
},
"node_modules/bare-events": {
"version": "2.5.0",
@@ -7173,7 +7157,6 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
- "dev": true,
"dependencies": {
"call-bind-apply-helpers": "^1.0.0",
"es-define-property": "^1.0.0",
@@ -7191,7 +7174,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.0.tgz",
"integrity": "sha512-CCKAP2tkPau7D3GE8+V8R6sQubA9R5foIzGp+85EXCVSCivuxBNAWqcpn72PKYiIcqoViv/kcUDpaEIMBVi1lQ==",
- "dev": true,
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
@@ -7204,7 +7186,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -7335,6 +7317,11 @@
"url": "https://paulmillr.com/funding/"
}
},
+ "node_modules/chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+ },
"node_modules/chromium-bidi": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.8.0.tgz",
@@ -7546,14 +7533,6 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
- "node_modules/color-support": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
- "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
- "bin": {
- "color-support": "bin.js"
- }
- },
"node_modules/colorette": {
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
@@ -7583,12 +7562,7 @@
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
- },
- "node_modules/console-control-strings": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
+ "license": "MIT"
},
"node_modules/content-type": {
"version": "1.0.5",
@@ -7609,6 +7583,31 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
+ "node_modules/cosmiconfig": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
+ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
+ "dependencies": {
+ "env-paths": "^2.2.1",
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/create-jest": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz",
@@ -7756,6 +7755,20 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/dedent": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
@@ -7770,6 +7783,14 @@
}
}
},
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -7800,7 +7821,7 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
@@ -7879,6 +7900,14 @@
"node": ">=8"
}
},
+ "node_modules/detect-libc": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@@ -8035,11 +8064,6 @@
"safe-buffer": "^5.0.1"
}
},
- "node_modules/eight-colors": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/eight-colors/-/eight-colors-1.3.1.tgz",
- "integrity": "sha512-7nXPYDeKh6DgJDR/mpt2G7N/hCNSGwwoPVmoI3+4TEwOb07VFN1WMPG0DFf6nMEjrkgdj8Og7l7IaEEk3VE6Zg=="
- },
"node_modules/ejs": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
@@ -8157,6 +8181,14 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/environment": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
@@ -8173,7 +8205,7 @@
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
}
@@ -8239,10 +8271,13 @@
}
},
"node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "dev": true,
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+ "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4"
+ },
"engines": {
"node": ">= 0.4"
}
@@ -8251,7 +8286,7 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
}
@@ -8638,6 +8673,14 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/expect": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
@@ -8851,6 +8894,14 @@
"node": ">=8"
}
},
+ "node_modules/find-exec": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/find-exec/-/find-exec-1.0.3.tgz",
+ "integrity": "sha512-gnG38zW90mS8hm5smNcrBnakPEt+cGJoiMkJwCU0IYnEb0H2NQk0NIljhNW+48oniCriFek/PH6QXbwsJo/qug==",
+ "dependencies": {
+ "shell-quote": "^1.8.1"
+ }
+ },
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -8970,6 +9021,11 @@
"node": ">= 12.20"
}
},
+ "node_modules/fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+ },
"node_modules/fs-extra": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
@@ -8987,7 +9043,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
+ "license": "ISC"
},
"node_modules/fsevents": {
"version": "2.3.3",
@@ -9007,7 +9063,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
+ "license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -9039,62 +9095,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/gauge": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-5.0.2.tgz",
- "integrity": "sha512-pMaFftXPtiGIHCJHdcUUx9Rby/rFT/Kkt3fIIGCs+9PMDIljSyRiqraTlxNtBReJRDfUefpa263RQ3vnp5G/LQ==",
- "deprecated": "This package is no longer supported.",
- "dependencies": {
- "aproba": "^1.0.3 || ^2.0.0",
- "color-support": "^1.1.3",
- "console-control-strings": "^1.1.0",
- "has-unicode": "^2.0.1",
- "signal-exit": "^4.0.1",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "wide-align": "^1.1.5"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/gauge/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/gauge/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
- },
- "node_modules/gauge/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/gauge/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/gaxios": {
"version": "6.7.1",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz",
@@ -9155,7 +9155,7 @@
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
@@ -9221,6 +9221,11 @@
"node": ">= 14"
}
},
+ "node_modules/github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
+ },
"node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
@@ -9322,7 +9327,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "dev": true,
"engines": {
"node": ">= 0.4"
},
@@ -9375,7 +9379,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0"
},
@@ -9384,13 +9388,10 @@
}
},
"node_modules/has-proto": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
- "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
- "dev": true,
- "dependencies": {
- "dunder-proto": "^1.0.0"
- },
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+ "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -9399,10 +9400,10 @@
}
},
"node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "dev": true,
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -9425,16 +9426,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/has-unicode": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
- },
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
@@ -9605,7 +9601,7 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
@@ -9650,7 +9646,7 @@
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"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.",
- "dev": true,
+ "license": "ISC",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@@ -9661,6 +9657,11 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
"node_modules/internal-slot": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
@@ -9707,7 +9708,7 @@
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
+ "license": "MIT"
},
"node_modules/is-async-function": {
"version": "2.0.0",
@@ -11008,13 +11009,13 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true
+ "license": "MIT"
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
@@ -11063,7 +11064,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "dev": true
+ "license": "MIT"
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
@@ -11127,6 +11128,16 @@
"safe-buffer": "^5.0.1"
}
},
+ "node_modules/keytar": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
+ "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "node-addon-api": "^4.3.0",
+ "prebuild-install": "^7.0.1"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -11157,7 +11168,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
"integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -11199,7 +11210,15 @@
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true
+ "license": "MIT"
+ },
+ "node_modules/linkify-it": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
+ "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+ "dependencies": {
+ "uc.micro": "^1.0.1"
+ }
},
"node_modules/lint-staged": {
"version": "15.2.11",
@@ -11797,6 +11816,34 @@
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
},
+ "node_modules/markdown-it": {
+ "version": "12.3.2",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
+ "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "~2.1.0",
+ "linkify-it": "^3.0.1",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.js"
+ }
+ },
+ "node_modules/markdown-it/node_modules/entities": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g=="
+ },
"node_modules/memorystream": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
@@ -11831,6 +11878,17 @@
"node": ">=8.6"
}
},
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -11871,6 +11929,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@@ -11886,6 +11955,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
@@ -11900,6 +11977,11 @@
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
},
+ "node_modules/mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
+ },
"node_modules/mocha": {
"version": "10.8.2",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz",
@@ -12149,6 +12231,16 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
+ "node_modules/mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
+ },
+ "node_modules/napi-build-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
+ },
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -12169,6 +12261,22 @@
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
+ "node_modules/node-abi": {
+ "version": "3.71.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz",
+ "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-addon-api": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+ "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
+ },
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@@ -12465,7 +12573,7 @@
"version": "1.13.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -12835,7 +12943,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
},
@@ -12847,7 +12955,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
@@ -12861,6 +12969,22 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/parse-semver": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
+ "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==",
+ "dependencies": {
+ "semver": "^5.1.0"
+ }
+ },
+ "node_modules/parse-semver/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
"node_modules/parse5": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
@@ -12988,7 +13112,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "dev": true
+ "license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.1",
@@ -13095,6 +13219,14 @@
"node": ">=8"
}
},
+ "node_modules/play-sound": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/play-sound/-/play-sound-1.1.6.tgz",
+ "integrity": "sha512-09eO4QiXNFXJffJaOW5P6x6F5RLihpLUkXttvUZeWml0fU6x6Zp7AjG9zaeMpgH2ZNvq4GR1ytB22ddYcqJIZA==",
+ "dependencies": {
+ "find-exec": "1.0.3"
+ }
+ },
"node_modules/possible-typed-array-names": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
@@ -13104,19 +13236,116 @@
"node": ">= 0.4"
}
},
- "node_modules/prelude-ls": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
- "dev": true,
+ "node_modules/prebuild-install": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz",
+ "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==",
+ "dependencies": {
+ "detect-libc": "^2.0.0",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^3.3.0",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^4.0.0",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0"
+ },
+ "bin": {
+ "prebuild-install": "bin.js"
+ },
"engines": {
- "node": ">= 0.8.0"
+ "node": ">=10"
}
},
- "node_modules/prettier": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
- "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+ "node_modules/prebuild-install/node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/prebuild-install/node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/prebuild-install/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/prebuild-install/node_modules/tar-fs": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "dependencies": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
+ "node_modules/prebuild-install/node_modules/tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "dependencies": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+ "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
@@ -13229,24 +13458,53 @@
"node": ">=6"
}
},
- "node_modules/puppeteer-chromium-resolver": {
- "version": "23.0.0",
- "resolved": "https://registry.npmjs.org/puppeteer-chromium-resolver/-/puppeteer-chromium-resolver-23.0.0.tgz",
- "integrity": "sha512-PbSXK4ERPwp+eYm+SVY5vMWCxsdeJcddwz4avXvDx7kE9DLE+L86Xg027sypw2oan5yi6557brzVsbajcMmy2g==",
+ "node_modules/puppeteer": {
+ "version": "23.9.0",
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.9.0.tgz",
+ "integrity": "sha512-WfB8jGwFV+qrD9dcJJVvWPFJBU6kxeu2wxJz9WooDGfM3vIiKLgzImEDBxUQnCBK/2cXB3d4dV6gs/LLpgfLDg==",
"hasInstallScript": true,
"dependencies": {
- "@puppeteer/browsers": "^2.3.1",
- "eight-colors": "^1.3.0",
- "gauge": "^5.0.2",
- "puppeteer-core": "^23.1.0"
+ "@puppeteer/browsers": "2.4.1",
+ "chromium-bidi": "0.8.0",
+ "cosmiconfig": "^9.0.0",
+ "devtools-protocol": "0.0.1367902",
+ "puppeteer-core": "23.9.0",
+ "typed-query-selector": "^2.12.0"
+ },
+ "bin": {
+ "puppeteer": "lib/cjs/puppeteer/node/cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/puppeteer/node_modules/@puppeteer/browsers": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.1.tgz",
+ "integrity": "sha512-0kdAbmic3J09I6dT8e9vE2JOCSt13wHCW5x/ly8TSt2bDtuIWe2TgLZZDHdcziw9AVCzflMAXCrVyRIhIs44Ng==",
+ "dependencies": {
+ "debug": "^4.3.7",
+ "extract-zip": "^2.0.1",
+ "progress": "^2.0.3",
+ "proxy-agent": "^6.4.0",
+ "semver": "^7.6.3",
+ "tar-fs": "^3.0.6",
+ "unbzip2-stream": "^1.4.3",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "browsers": "lib/cjs/main-cli.js"
+ },
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/puppeteer-core": {
- "version": "23.10.1",
- "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.10.1.tgz",
- "integrity": "sha512-ey6NwixHYEUnhCA/uYi7uQQ4a0CZw4k+MatbHXGl5GEzaiRQziYUxc2HGpdQZ/gnh4KQWAKkocyIg1/dIm5d0g==",
+ "node_modules/puppeteer/node_modules/puppeteer-core": {
+ "version": "23.9.0",
+ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.9.0.tgz",
+ "integrity": "sha512-hLVrav2HYMVdK0YILtfJwtnkBAwNOztUdR4aJ5YKDvgsbtagNr6urUJk9HyjRA9e+PaLI3jzJ0wM7A4jSZ7Qxw==",
"dependencies": {
- "@puppeteer/browsers": "2.5.0",
+ "@puppeteer/browsers": "2.4.1",
"chromium-bidi": "0.8.0",
"debug": "^4.3.7",
"devtools-protocol": "0.0.1367902",
@@ -13273,6 +13531,20 @@
}
]
},
+ "node_modules/qs": {
+ "version": "6.13.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz",
+ "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==",
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -13320,12 +13592,45 @@
"node": ">= 0.8"
}
},
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/rc/node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
"dev": true
},
+ "node_modules/read": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+ "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==",
+ "dependencies": {
+ "mute-stream": "~0.0.4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -13540,7 +13845,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -13737,6 +14042,11 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
+ "node_modules/sax": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
+ "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
+ },
"node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@@ -13786,7 +14096,7 @@
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
@@ -13858,7 +14168,6 @@
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz",
"integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
- "dev": true,
"engines": {
"node": ">= 0.4"
},
@@ -13870,7 +14179,7 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
@@ -13895,6 +14204,49 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/simple-get": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+ "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "decompress-response": "^6.0.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
"node_modules/sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@@ -14627,6 +14979,25 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
+ "node_modules/tunnel": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+ "engines": {
+ "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
+ }
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/turndown": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz",
@@ -14747,11 +15118,22 @@
"resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz",
"integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg=="
},
+ "node_modules/typed-rest-client": {
+ "version": "1.8.11",
+ "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz",
+ "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==",
+ "dependencies": {
+ "qs": "^6.9.1",
+ "tunnel": "0.0.6",
+ "underscore": "^1.12.1"
+ }
+ },
"node_modules/typescript": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
- "dev": true,
+ "devOptional": true,
+ "license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -14760,6 +15142,11 @@
"node": ">=14.17"
}
},
+ "node_modules/uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
+ },
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
@@ -14891,6 +15278,11 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA=="
+ },
"node_modules/urlpattern-polyfill": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz",
@@ -14937,6 +15329,195 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "node_modules/vsce": {
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.15.0.tgz",
+ "integrity": "sha512-P8E9LAZvBCQnoGoizw65JfGvyMqNGlHdlUXD1VAuxtvYAaHBKLBdKPnpy60XKVDAkQCfmMu53g+gq9FM+ydepw==",
+ "deprecated": "vsce has been renamed to @vscode/vsce. Install using @vscode/vsce instead.",
+ "dependencies": {
+ "azure-devops-node-api": "^11.0.1",
+ "chalk": "^2.4.2",
+ "cheerio": "^1.0.0-rc.9",
+ "commander": "^6.1.0",
+ "glob": "^7.0.6",
+ "hosted-git-info": "^4.0.2",
+ "keytar": "^7.7.0",
+ "leven": "^3.1.0",
+ "markdown-it": "^12.3.2",
+ "mime": "^1.3.4",
+ "minimatch": "^3.0.3",
+ "parse-semver": "^1.1.1",
+ "read": "^1.0.7",
+ "semver": "^5.1.0",
+ "tmp": "^0.2.1",
+ "typed-rest-client": "^1.8.4",
+ "url-join": "^4.0.1",
+ "xml2js": "^0.4.23",
+ "yauzl": "^2.3.1",
+ "yazl": "^2.2.2"
+ },
+ "bin": {
+ "vsce": "vsce"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/vsce/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/vsce/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/vsce/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/vsce/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/vsce/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "node_modules/vsce/node_modules/commander": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/vsce/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/vsce/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/vsce/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/vsce/node_modules/hosted-git-info": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+ "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/vsce/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/vsce/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/vsce/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/vsce/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/vsce/node_modules/tmp": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
+ "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==",
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/vsce/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
"node_modules/walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
@@ -15095,51 +15676,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/wide-align": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
- "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
- "dependencies": {
- "string-width": "^1.0.2 || 2 || 3 || 4"
- }
- },
- "node_modules/wide-align/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wide-align/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
- },
- "node_modules/wide-align/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wide-align/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/windows-release": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/windows-release/-/windows-release-6.0.1.tgz",
@@ -15414,6 +15950,26 @@
}
}
},
+ "node_modules/xml2js": {
+ "version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
+ "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/xml2js/node_modules/xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
"node_modules/xmlbuilder": {
"version": "10.1.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.1.tgz",
@@ -15546,6 +16102,14 @@
"fd-slicer": "~1.1.0"
}
},
+ "node_modules/yazl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
+ "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
+ "dependencies": {
+ "buffer-crc32": "~0.2.3"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/package.json b/package.json
index 83bd01c22de..fb02761ec25 100644
--- a/package.json
+++ b/package.json
@@ -159,9 +159,9 @@
"start:webview": "cd webview-ui && npm run start",
"test": "jest && npm run test:webview",
"test:webview": "cd webview-ui && npm run test",
- "prepare": "husky",
"publish:marketplace": "vsce publish",
"publish": "npm run build && changeset publish && npm install --package-lock-only",
+ "prepare": "husky",
"version-packages": "changeset version && npm install --package-lock-only",
"vscode:prepublish": "npm run package",
"vsix": "mkdir -p bin && npx vsce package --out bin",
@@ -217,13 +217,14 @@
"os-name": "^6.0.0",
"p-wait-for": "^5.0.2",
"pdf-parse": "^1.1.1",
- "puppeteer-chromium-resolver": "^23.0.0",
- "puppeteer-core": "^23.4.0",
+ "puppeteer": "^23.9.0",
+ "play-sound": "^1.1.6",
"serialize-error": "^11.0.3",
"sound-play": "^1.1.0",
"strip-ansi": "^7.1.0",
"tree-sitter-wasms": "^0.1.11",
"turndown": "^7.2.0",
+ "vsce": "^2.15.0",
"web-tree-sitter": "^0.22.6",
"zod": "^3.23.8"
},
diff --git a/src/core/Cline.ts b/src/core/Cline.ts
index e98be5e94ba..f32105f4043 100644
--- a/src/core/Cline.ts
+++ b/src/core/Cline.ts
@@ -65,6 +65,8 @@ export class Cline {
private urlContentFetcher: UrlContentFetcher
private browserSession: BrowserSession
private didEditFile: boolean = false
+ private isInteractiveMode: boolean = false
+ private browserPort: string = '7333'
customInstructions?: string
diffStrategy?: DiffStrategy
@@ -98,6 +100,8 @@ export class Cline {
customInstructions?: string,
diffEnabled?: boolean,
debugDiffEnabled?: boolean,
+ isInteractiveMode?: boolean,
+ browserPort?: string,
task?: string,
images?: string[],
historyItem?: HistoryItem,
@@ -106,8 +110,10 @@ export class Cline {
this.api = buildApiHandler(apiConfiguration)
this.terminalManager = new TerminalManager()
this.urlContentFetcher = new UrlContentFetcher(provider.context)
- this.browserSession = new BrowserSession(provider.context)
+ this.browserSession = new BrowserSession(provider.context, provider)
this.diffViewProvider = new DiffViewProvider(cwd)
+ this.isInteractiveMode = isInteractiveMode ?? false
+ this.browserPort = browserPort ?? "7333"
this.customInstructions = customInstructions
if (diffEnabled && this.api.getModel().id) {
this.diffStrategy = getDiffStrategy(this.api.getModel().id, debugDiffEnabled)
@@ -633,22 +639,42 @@ export class Cline {
if (responseImages && responseImages.length > 0) {
newUserContent.push(...formatResponse.imageBlocks(responseImages))
}
-
+ const state = await this.providerRef.deref()?.getState()
+ const wasInteractiveBrowser = state?.isInteractiveMode
+ let hadBrowserPort = '';
+ if ( wasInteractiveBrowser ) {
+ hadBrowserPort = state?.browserPort;
+ this.providerRef.deref()?.outputChannel.appendLine(`resumeTaskFromHistory :: browserPort :: ${hadBrowserPort}`)
+ }
await this.overwriteApiConversationHistory(modifiedApiConversationHistory)
- await this.initiateTaskLoop(newUserContent)
+ await this.initiateTaskLoop(newUserContent, wasInteractiveBrowser, hadBrowserPort)
}
- private async initiateTaskLoop(userContent: UserContent): Promise {
- let nextUserContent = userContent
- let includeFileDetails = true
- while (!this.abort) {
- const didEndLoop = await this.recursivelyMakeClineRequests(nextUserContent, includeFileDetails)
- includeFileDetails = false // we only need file details the first time
+ private async initiateTaskLoop(userContent: UserContent, wasInteractiveBrowser: boolean = false, hadBrowserPort: string = ''): Promise {
+ const state = await this.providerRef.deref()?.getState()
+ const hasInteractiveMode = state?.isInteractiveMode ?? wasInteractiveBrowser
- // The way this agentic loop works is that cline will be given a task that he then calls tools to complete. unless there's an attempt_completion call, we keep responding back to him with his tool's responses until he either attempt_completion or does not use anymore tools. If he does not use anymore tools, we ask him to consider if he's completed the task and then call attempt_completion, otherwise proceed with completing the task.
- // There is a MAX_REQUESTS_PER_TASK limit to prevent infinite requests, but Cline is prompted to finish the task as efficiently as he can.
- //const totalCost = this.calculateApiCost(totalInputTokens, totalOutputTokens)
+ this.providerRef.deref()?.outputChannel.appendLine(`initiateTaskLoop :: hasInteractiveMode :: ${hasInteractiveMode}`)
+
+ // Set interactive mode flag if found in text
+ if (hasInteractiveMode) {
+ this.isInteractiveMode = true;
+ this.browserPort = state?.browserPort ?? hadBrowserPort
+ this.providerRef.deref()?.outputChannel.appendLine(`initiateTaskLoop :: browserPort :: ${this.browserPort}`)
+ }
+
+ let nextUserContent = userContent;
+ let includeFileDetails = true;
+ while (!this.abort) {
+ const didEndLoop = await this.recursivelyMakeClineRequests(
+ nextUserContent,
+ includeFileDetails,
+ this.isInteractiveMode, // Pass the flag to recursivelyMakeClineRequests
+ this.browserPort // Pass the browserPort to recursivelyMakeClineRequests
+ )
+ includeFileDetails = false
+
if (didEndLoop) {
// For now a task never 'completes'. This will only happen if the user hits max requests and denies resetting the count.
//this.say("task_completed", `Task completed. Total API usage cost: ${totalCost}`)
@@ -662,7 +688,7 @@ export class Cline {
{
type: "text",
text: formatResponse.noToolsUsed(),
- },
+ }
]
this.consecutiveMistakeCount++
}
@@ -1498,7 +1524,15 @@ export class Cline {
try {
if (block.partial) {
- if (action === "launch") {
+ if (action === "snapshot") {
+ // For snapshot, we just show the streaming UI update
+ await this.say(
+ "browser_action",
+ JSON.stringify({
+ action: "snapshot"
+ } satisfies ClineSayBrowserAction),
+ )
+ } else if (action === "launch") {
await this.ask(
"browser_action_launch",
removeClosingTag("url", url),
@@ -1519,27 +1553,32 @@ export class Cline {
break
} else {
let browserActionResult: BrowserActionResult
- if (action === "launch") {
+ if (action === "snapshot") {
+ await this.say("browser_action",JSON.stringify({action: "snapshot"} satisfies ClineSayBrowserAction))
+ browserActionResult = await this.browserSession.takeScreenshot(this.isInteractiveMode, this.browserPort)
+ } else if (action === "launch") {
if (!url) {
- this.consecutiveMistakeCount++
- pushToolResult(
- await this.sayAndCreateMissingParamError("browser_action", "url"),
- )
- await this.browserSession.closeBrowser()
- break
- }
- this.consecutiveMistakeCount = 0
- const didApprove = await askApproval("browser_action_launch", url)
- if (!didApprove) {
- break
- }
-
- // NOTE: it's okay that we call this message since the partial inspect_site is finished streaming. The only scenario we have to avoid is sending messages WHILE a partial message exists at the end of the messages array. For example the api_req_finished message would interfere with the partial message, so we needed to remove that.
- // await this.say("inspect_site_result", "") // no result, starts the loading spinner waiting for result
- await this.say("browser_action_result", "") // starts loading spinner
+ if (this.isInteractiveMode) {
+ browserActionResult = await this.browserSession.takeScreenshot()
+ } else {
+ this.consecutiveMistakeCount++
+ pushToolResult(await this.sayAndCreateMissingParamError("browser_action", "url"))
+ await this.browserSession.closeBrowser()
+ break
+ }
+ } else {
+ this.consecutiveMistakeCount = 0
+ const didApprove = await askApproval("browser_action_launch", url)
+ if (!didApprove) {
+ break
+ }
- await this.browserSession.launchBrowser()
- browserActionResult = await this.browserSession.navigateToUrl(url)
+ // NOTE: it's okay that we call this message since the partial inspect_site is finished streaming. The only scenario we have to avoid is sending messages WHILE a partial message exists at the end of the messages array. For example the api_req_finished message would interfere with the partial message, so we needed to remove that.
+ // await this.say("inspect_site_result", "") // no result, starts the loading spinner waiting for result
+ await this.say("browser_action_result", "") // starts loading spinner
+ await this.browserSession.launchBrowser(this.isInteractiveMode, this.browserPort)
+ browserActionResult = await this.browserSession.navigateToUrl(url)
+ }
} else {
if (action === "click") {
if (!coordinate) {
@@ -1593,8 +1632,20 @@ export class Cline {
break
}
}
-
switch (action) {
+ case "snapshot": {
+ const { screenshot, ...snapshotResult } = browserActionResult
+ await this.say("browser_action_result", JSON.stringify(snapshotResult))
+ pushToolResult(
+ formatResponse.toolResult(
+ `The browser action has been executed. The console logs have been captured for your analysis.\n\nConsole logs:\n${
+ browserActionResult.logs || "(No new logs)"
+ }\n\n(REMEMBER: if you need to proceed to using non-\`browser_action\` tools or launch a new browser, you MUST first close this browser. For example, if after analyzing the logs and screenshot you need to edit a file, you must first close the browser before you can use the write_to_file tool.)`,
+ browserActionResult.screenshot ? [browserActionResult.screenshot] : [],
+ ),
+ )
+ break
+ }
case "launch":
case "click":
case "type":
@@ -1915,15 +1966,13 @@ export class Cline {
break
}
this.consecutiveMistakeCount = 0
-
+
let commandResult: ToolResponse | undefined
if (command) {
if (lastMessage && lastMessage.ask !== "command") {
- // havent sent a command message yet so first send completion_result then command
await this.say("completion_result", result, undefined, false)
}
-
- // complete command message
+
const didApprove = await askApproval("command", command)
if (!didApprove) {
break
@@ -1934,20 +1983,18 @@ export class Cline {
pushToolResult(execCommandResult)
break
}
- // user didn't reject, but the command may have output
commandResult = execCommandResult
} else {
await this.say("completion_result", result, undefined, false)
}
-
- // we already sent completion_result says, an empty string asks relinquishes control over button and field
+
const { response, text, images } = await this.ask("completion_result", "", false)
if (response === "yesButtonClicked") {
pushToolResult("") // signals to recursive loop to stop (for now this never happens since yesButtonClicked will trigger a new task)
break
}
await this.say("user_feedback", text ?? "", images)
-
+
const toolResults: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] = []
if (commandResult) {
if (typeof commandResult === "string") {
@@ -1966,7 +2013,7 @@ export class Cline {
text: `${toolDescription()} Result:`,
})
this.userMessageContent.push(...toolResults)
-
+
break
}
} catch (error) {
@@ -2012,10 +2059,28 @@ export class Cline {
async recursivelyMakeClineRequests(
userContent: UserContent,
includeFileDetails: boolean = false,
+ isInteractiveMode: boolean = false,
+ browserPort?: string
): Promise {
+ if (this.presentAssistantMessageHasPendingUpdates) {
+ this.presentAssistantMessage()
+ }
+
+ const state = await this.providerRef.deref()?.getState()
+ // Use optional chaining and provide defaults
+ this.isInteractiveMode = isInteractiveMode ?? state?.isInteractiveMode ?? false
+ this.browserPort = browserPort ?? state?.browserPort ?? "7333"
+
+ // Store interactive mode state
+ if (state?.isInteractiveMode !== undefined) {
+ this.isInteractiveMode = state.isInteractiveMode
+ }
+
if (this.abort) {
throw new Error("Cline instance aborted")
}
+ // Store interactive mode state
+ this.isInteractiveMode = isInteractiveMode;
if (this.consecutiveMistakeCount >= 3) {
const { response, text, images } = await this.ask(
@@ -2265,7 +2330,7 @@ export class Cline {
this.consecutiveMistakeCount++
}
- const recDidEndLoop = await this.recursivelyMakeClineRequests(this.userMessageContent)
+ const recDidEndLoop = await this.recursivelyMakeClineRequests(this.userMessageContent, false, this.isInteractiveMode, browserPort)
didEndLoop = recDidEndLoop
} else {
// if there's no assistant_responses, that means we got no text or tool_use content blocks from API which we should assume is an error
diff --git a/src/core/__tests__/Cline.test.ts b/src/core/__tests__/Cline.test.ts
index 041298fa4aa..f26fe9058e3 100644
--- a/src/core/__tests__/Cline.test.ts
+++ b/src/core/__tests__/Cline.test.ts
@@ -278,8 +278,10 @@ describe('Cline', () => {
mockProvider,
mockApiConfig,
'custom instructions',
- false, // diffEnabled
- false, // debugDiffEnabled
+ false,
+ false,
+ true, // isInteractiveMode
+ '7333', // browserPort
'test task'
);
diff --git a/src/core/assistant-message/parse-assistant-message.ts b/src/core/assistant-message/parse-assistant-message.ts
index e38e8f6458e..9a7c31a5bc5 100644
--- a/src/core/assistant-message/parse-assistant-message.ts
+++ b/src/core/assistant-message/parse-assistant-message.ts
@@ -8,6 +8,7 @@ import {
ToolUseName,
} from "."
+// In case of debugging, you may pass 'provider: ClineProvider' as a second argument, and use 'providerRef.deref()?.outputChannel.appendLine'
export function parseAssistantMessage(assistantMessage: string) {
let contentBlocks: AssistantMessageContent[] = []
let currentTextContent: TextContent | undefined = undefined
diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts
index b4973681636..361b05add51 100644
--- a/src/core/prompts/system.ts
+++ b/src/core/prompts/system.ts
@@ -109,12 +109,15 @@ Usage:
## browser_action
Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action.
-- The sequence of actions **must always start with** launching the browser at a URL, and **must always end with** closing the browser. If you need to visit a new URL that is not possible to navigate to from the current webpage, you must first close the browser, then launch again at the new URL.
-- While the browser is active, only the \`browser_action\` tool can be used. No other tools should be called during this time. You may proceed to use other tools only after closing the browser. For example if you run into an error and need to fix a file, you must close the browser, then use other tools to make the necessary changes, then re-launch the browser to verify the result.
-- The browser window has a resolution of **900x600** pixels. When performing any click actions, ensure the coordinates are within this resolution range.
+- Whenever the user requests for a snapshot, or to interact or view **his browser**, use 'browser_action' with 'snapshot' as the action.
+- If the action is \'snapshot\', and \'Interactive Browser Mode\' is enabled, a browser will already be running and you only need to connect to it, respond with a screenshot of the browser's current state and logs.
+- For all other actions, the sequence of actions **must always start with** launching the browser at a URL, and **must always end with** closing the browser. If you need to visit a new URL that is not possible to navigate to from the current webpage, you must first close the browser, then launch again at the new URL.
+- While the browser is active and \'Interactive Browser Mode\' is disabled, only the \`browser_action\` tool can be used. No other tools should be called during this time. You may proceed to use other tools only after closing the browser. For example if you run into an error and need to fix a file, you must close the browser, then use other tools to make the necessary changes, then re-launch the browser to verify the result.
+- The browser window has a resolution of **1440x900** pixels. When performing any click actions, ensure the coordinates are within this resolution range.
- Before clicking on any elements such as icons, links, or buttons, you must consult the provided screenshot of the page to determine the coordinates of the element. The click should be targeted at the **center of the element**, not on its edges.
Parameters:
- action: (required) The action to perform. The available actions are:
+ * snapshot: Take a screenshot of the current browser state
* launch: Launch a new Puppeteer-controlled browser instance at the specified URL. This **must always be the first action**.
- Use with the \`url\` parameter to provide the URL.
- Ensure the URL is valid and includes the appropriate protocol (e.g. http://localhost:3000/page, file:///path/to/file.html, etc.)
@@ -686,7 +689,7 @@ CAPABILITIES
- For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file ${diffStrategy ? "or apply_diff " : ""}tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
- You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.${
supportsComputerUse
- ? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser."
+ ? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to connect or launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser."
: ""
}
- You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively.
diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts
index 861046ee1d5..b0530f6932d 100644
--- a/src/core/webview/ClineProvider.ts
+++ b/src/core/webview/ClineProvider.ts
@@ -68,6 +68,8 @@ type GlobalStateKey =
| "soundEnabled"
| "soundVolume"
| "diffEnabled"
+ | "isInteractiveMode"
+ | "browserPort"
| "debugDiffEnabled"
| "alwaysAllowMcp"
@@ -91,7 +93,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
constructor(
readonly context: vscode.ExtensionContext,
- private readonly outputChannel: vscode.OutputChannel,
+ readonly outputChannel: vscode.OutputChannel,
) {
this.outputChannel.appendLine("ClineProvider instantiated")
ClineProvider.activeInstances.add(this)
@@ -214,31 +216,37 @@ export class ClineProvider implements vscode.WebviewViewProvider {
async initClineWithTask(task?: string, images?: string[]) {
await this.clearTask()
- const {
- apiConfiguration,
- customInstructions,
+ const {
+ apiConfiguration,
+ customInstructions,
diffEnabled,
+ isInteractiveMode,
+ browserPort,
debugDiffEnabled,
} = await this.getState()
-
+
this.cline = new Cline(
- this,
- apiConfiguration,
- customInstructions,
+ this,
+ apiConfiguration,
+ customInstructions,
diffEnabled,
debugDiffEnabled,
- task,
+ isInteractiveMode,
+ browserPort,
+ task,
images
)
}
async initClineWithHistoryItem(historyItem: HistoryItem) {
await this.clearTask()
- const {
- apiConfiguration,
- customInstructions,
+ const {
+ apiConfiguration,
+ customInstructions,
diffEnabled,
debugDiffEnabled,
+ isInteractiveMode,
+ browserPort
} = await this.getState()
this.cline = new Cline(
@@ -247,6 +255,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
customInstructions,
diffEnabled,
debugDiffEnabled,
+ isInteractiveMode,
+ browserPort,
undefined,
undefined,
historyItem,
@@ -614,6 +624,14 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await this.updateGlobalState("diffEnabled", diffEnabled)
await this.postStateToWebview()
break
+ case "isInteractiveMode":
+ await this.updateGlobalState("isInteractiveMode", message.bool ?? false)
+ await this.postStateToWebview()
+ break
+ case "browserPort":
+ await this.updateGlobalState("browserPort", message.text ?? "7333")
+ await this.postStateToWebview()
+ break
case "debugDiffEnabled":
const debugDiffEnabled = message.bool ?? false
await this.updateGlobalState("debugDiffEnabled", debugDiffEnabled)
@@ -947,6 +965,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
diffEnabled,
debugDiffEnabled,
taskHistory,
+ isInteractiveMode,
+ browserPort,
soundVolume,
} = await this.getState()
@@ -973,6 +993,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
debugDiffEnabled: debugDiffEnabled ?? false,
shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
allowedCommands,
+ isInteractiveMode: isInteractiveMode ?? false,
+ browserPort: browserPort ?? "7333",
soundVolume: soundVolume ?? 0.5,
}
}
@@ -1066,6 +1088,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
allowedCommands,
soundEnabled,
diffEnabled,
+ isInteractiveMode,
+ browserPort,
debugDiffEnabled,
soundVolume,
] = await Promise.all([
@@ -1105,6 +1129,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.getGlobalState("allowedCommands") as Promise,
this.getGlobalState("soundEnabled") as Promise,
this.getGlobalState("diffEnabled") as Promise,
+ this.getGlobalState("isInteractiveMode") as Promise,
+ this.getGlobalState("browserPort") as Promise,
this.getGlobalState("debugDiffEnabled") as Promise,
this.getGlobalState("soundVolume") as Promise,
])
@@ -1160,6 +1186,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
alwaysAllowMcp: alwaysAllowMcp ?? false,
taskHistory,
allowedCommands,
+ isInteractiveMode: isInteractiveMode ?? false,
+ browserPort: browserPort ?? "7333",
soundEnabled: soundEnabled ?? false,
diffEnabled: diffEnabled ?? false,
debugDiffEnabled: debugDiffEnabled ?? false,
diff --git a/src/extension.ts b/src/extension.ts
index 5b94fad54a7..01a97c1db73 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -21,10 +21,10 @@ let outputChannel: vscode.OutputChannel
// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
- outputChannel = vscode.window.createOutputChannel("Cline")
+ outputChannel = vscode.window.createOutputChannel("Roo-Cline")
context.subscriptions.push(outputChannel)
- outputChannel.appendLine("Cline extension activated")
+ outputChannel.appendLine("Roo-Cline extension activated")
// Get default commands from configuration
const defaultCommands = vscode.workspace
@@ -60,7 +60,7 @@ export function activate(context: vscode.ExtensionContext) {
)
const openClineInNewTab = async () => {
- outputChannel.appendLine("Opening Cline in new tab")
+ outputChannel.appendLine("Opening Roo-Cline in new tab")
// (this example uses webviewProvider activation event which is necessary to deserialize cached webview, but since we use retainContextWhenHidden, we don't need to use that event)
// https://github.com/microsoft/vscode-extension-samples/blob/main/webview-sample/src/extension.ts
const tabProvider = new ClineProvider(context, outputChannel)
@@ -74,7 +74,7 @@ export function activate(context: vscode.ExtensionContext) {
}
const targetCol = hasVisibleEditors ? Math.max(lastCol + 1, 1) : vscode.ViewColumn.Two
- const panel = vscode.window.createWebviewPanel(ClineProvider.tabPanelId, "Cline", targetCol, {
+ const panel = vscode.window.createWebviewPanel(ClineProvider.tabPanelId, "Roo-Cline", targetCol, {
enableScripts: true,
retainContextWhenHidden: true,
localResourceRoots: [context.extensionUri],
@@ -151,5 +151,5 @@ export function activate(context: vscode.ExtensionContext) {
// This method is called when your extension is deactivated
export function deactivate() {
- outputChannel.appendLine("Cline extension deactivated")
+ outputChannel.appendLine("Roo-Cline extension deactivated")
}
diff --git a/src/services/browser/BrowserSession.ts b/src/services/browser/BrowserSession.ts
index b45265c77ba..82eae95cf36 100644
--- a/src/services/browser/BrowserSession.ts
+++ b/src/services/browser/BrowserSession.ts
@@ -1,89 +1,173 @@
import * as vscode from "vscode"
-import * as fs from "fs/promises"
-import * as path from "path"
-import { Browser, Page, ScreenshotOptions, TimeoutError, launch } from "puppeteer-core"
-// @ts-ignore
-import PCR from "puppeteer-chromium-resolver"
+import { Browser, Page, ScreenshotOptions, TimeoutError, launch, connect } from "puppeteer"
import pWaitFor from "p-wait-for"
import delay from "delay"
-import { fileExistsAtPath } from "../../utils/fs"
+import { ClineProvider } from "../../core/webview/ClineProvider"
import { BrowserActionResult } from "../../shared/ExtensionMessage"
-
-interface PCRStats {
- puppeteer: { launch: typeof launch }
- executablePath: string
-}
+import axios from 'axios'
export class BrowserSession {
private context: vscode.ExtensionContext
private browser?: Browser
private page?: Page
private currentMousePosition?: string
+ private isInteractive: boolean = false
+ private browserPort: string = '7333'
+ private providerRef: WeakRef
- constructor(context: vscode.ExtensionContext) {
+ constructor(context: vscode.ExtensionContext, provider: ClineProvider,) {
this.context = context
+ this.providerRef = new WeakRef(provider)
}
- private async ensureChromiumExists(): Promise {
- const globalStoragePath = this.context?.globalStorageUri?.fsPath
- if (!globalStoragePath) {
- throw new Error("Global storage uri is invalid")
- }
-
- const puppeteerDir = path.join(globalStoragePath, "puppeteer")
- const dirExists = await fileExistsAtPath(puppeteerDir)
- if (!dirExists) {
- await fs.mkdir(puppeteerDir, { recursive: true })
- }
-
- // if chromium doesn't exist, this will download it to path.join(puppeteerDir, ".chromium-browser-snapshots")
- // if it does exist it will return the path to existing chromium
- const stats: PCRStats = await PCR({
- downloadPath: puppeteerDir,
+ private async puppeteerLaunch() {
+ return launch({
+ args: [
+ "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
+ ],
+ defaultViewport: {
+ width: 1440,
+ height: 900
+ },
+ headless: false, // Always use non-headless mode
})
-
- return stats
}
- async launchBrowser() {
+ // New method to handle browser connection
+ private async puppeteerConnect(port: string): Promise {
+ try {
+ this.providerRef.deref()?.outputChannel.appendLine(`BrowserSession.ts :: puppeteerConnect :: ${port}`)
+ const response = await axios.get(`http://127.0.0.1:${port}/json/version`)
+ const browserWSEndpoint = response.data.webSocketDebuggerUrl
+
+ if (!browserWSEndpoint) {
+ this.providerRef.deref()?.outputChannel.appendLine(`BrowserSession.ts :: puppeteerConnect :: No webSocketDebuggerUrl found`)
+ console.log("BrowserSession.ts :: puppeteerConnect :: No webSocketDebuggerUrl found")
+ return undefined
+ }
+
+ return await connect({
+ browserWSEndpoint,
+ })
+ } catch (error) {
+ this.providerRef.deref()?.outputChannel.appendLine(`BrowserSession.ts :: puppeteerConnect :: Failed to connect: ${error}`)
+ console.log("BrowserSession.ts :: puppeteerConnect :: Failed to connect:", error)
+ return undefined
+ }
+ }
+
+ async launchBrowser(interactive: boolean = false, port?: string) {
console.log("launch browser called")
+ this.isInteractive = interactive
+ this.browserPort = port ?? this.browserPort
+
if (this.browser) {
- // throw new Error("Browser already launched")
await this.closeBrowser() // this may happen when the model launches a browser again after having used it already before
}
- const stats = await this.ensureChromiumExists()
- this.browser = await stats.puppeteer.launch({
- args: [
- "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
- ],
- executablePath: stats.executablePath,
- defaultViewport: {
- width: 900,
- height: 600,
- },
- // headless: false,
- })
- // (latest version of puppeteer does not add headless to user agent)
- this.page = await this.browser?.newPage()
+ if (this.isInteractive) {
+ this.browser = await this.puppeteerConnect(this.browserPort)
+ // If interactive mode failed, fall back to regular launch mode
+ if (!this.browser) {
+ this.browser = await this.puppeteerLaunch()
+ }
+ } else {
+ this.browser = await this.puppeteerLaunch()
+ }
+
+ // TO DO: Might no longer be needed and this.page = await this.browser?.newPage() could be enough
+ // Get existing pages or create new one
+ const pages = await this.browser.pages()
+ this.page = pages[0] || await this.browser.newPage()
+ await this.page?.setViewport({
+ width: 1440,
+ height: 900,
+ deviceScaleFactor: 1,
+ isMobile: false
+ });
+
+ return {
+ screenshot: this.isInteractive ? await this.getCurrentScreenshot() : "",
+ logs: this.isInteractive ?
+ "Connected to browser in remote debugging mode." :
+ "Browser launched successfully.",
+ currentUrl: this.page?.url(),
+ currentMousePosition: this.currentMousePosition,
+ }
}
async closeBrowser(): Promise {
- if (this.browser || this.page) {
+
+ if(this.isInteractive) {
+ console.log("disconnecting browser...")
+ await this.browser?.disconnect().catch(() => {})
+ } else {
console.log("closing browser...")
await this.browser?.close().catch(() => {})
- this.browser = undefined
- this.page = undefined
- this.currentMousePosition = undefined
}
return {}
}
- async doAction(action: (page: Page) => Promise): Promise {
+ private async getCurrentScreenshot(): Promise {
+ if (this.isInteractive) {
+ this.browser = await this.puppeteerConnect(this.browserPort)
+
+ if (this.browser) {
+ const pages = await this.browser.pages()
+ this.page = pages[0] || await this.browser.newPage()
+ } else {
+ this.providerRef.deref()?.outputChannel.appendLine(`BrowserSession.ts :: getCurrentScreenshot :: Failed to connect to browser for screenshot`)
+ throw new Error("Failed to connect to browser for screenshot")
+ }
+ }
+
if (!this.page) {
- throw new Error(
- "Browser is not launched. This may occur if the browser was automatically closed by a non-`browser_action` tool.",
- )
+ this.providerRef.deref()?.outputChannel.appendLine(`BrowserSession.ts :: getCurrentScreenshot :: Failed to take over a page to screenshot`)
+ throw new Error("Failed to get page for screenshot")
+ }
+
+ const screenshotType ="webp"
+ try {
+ let screenshotBase64 = await this.page.screenshot({
+ encoding: "base64",
+ type: screenshotType,
+ })
+ return `data:image/${screenshotType};base64,${screenshotBase64}`
+ } catch (err) {
+ try {
+ let screenshotBase64 = await this.page.screenshot({
+ encoding: "base64",
+ type: "png",
+ })
+ return `data:image/png;base64,${screenshotBase64}`
+ } catch (err) {
+ this.providerRef.deref()?.outputChannel.appendLine(`BrowserSession.ts :: getCurrentScreenshot :: Failed to take ${screenshotType} screenshot`)
+ console.error(`Failed to take ${screenshotType} screenshot:`, err)
+ return undefined
+ }
+ }
+ }
+
+ async doAction(action: (page: Page) => Promise): Promise {
+ try {
+ if (this.isInteractive && !this.browser) {
+ this.browser = await this.puppeteerConnect(this.browserPort)
+
+ if (this.browser) {
+ const pages = await this.browser.pages()
+ this.page = pages[0] || await this.browser.newPage()
+ }
+ }
+ // Ensure we have a browser and page
+ if (!this.browser || !this.page) {
+ throw new Error("Browser is not launched or connected. This may occur if the browser was automatically closed by a non-`browser_action` tool.")
+ }
+
+ }// For interactive mode and snapshot, try to connect first
+ catch(err) {
+ this.providerRef.deref()?.outputChannel.appendLine(`BrowserSession.ts :: doAction :: Browser action failed`)
+ console.error("Browser action failed:", err)
+ throw err
}
const logs: string[] = []
@@ -114,47 +198,21 @@ export class BrowserSession {
logs.push(`[Error] ${err.toString()}`)
}
}
-
+
// Wait for console inactivity, with a timeout
await pWaitFor(() => Date.now() - lastLogTs >= 500, {
timeout: 3_000,
interval: 100,
}).catch(() => {})
-
- let options: ScreenshotOptions = {
- encoding: "base64",
-
- // clip: {
- // x: 0,
- // y: 0,
- // width: 900,
- // height: 600,
- // },
- }
-
- let screenshotBase64 = await this.page.screenshot({
- ...options,
- type: "webp",
- })
- let screenshot = `data:image/webp;base64,${screenshotBase64}`
-
- if (!screenshotBase64) {
- console.log("webp screenshot failed, trying png")
- screenshotBase64 = await this.page.screenshot({
- ...options,
- type: "png",
- })
- screenshot = `data:image/png;base64,${screenshotBase64}`
- }
-
- if (!screenshotBase64) {
+
+ let screenshot = await this.getCurrentScreenshot()
+ if (!screenshot) {
throw new Error("Failed to take screenshot.")
}
-
- // this.page.removeAllListeners() <- causes the page to crash!
+
this.page.off("console", consoleListener)
this.page.off("pageerror", errorListener)
-
+
return {
screenshot,
logs: logs.join("\n"),
@@ -165,15 +223,11 @@ export class BrowserSession {
async navigateToUrl(url: string): Promise {
return this.doAction(async (page) => {
- // networkidle2 isn't good enough since page may take some time to load. we can assume locally running dev sites will reach networkidle0 in a reasonable amount of time
await page.goto(url, { timeout: 7_000, waitUntil: ["domcontentloaded", "networkidle2"] })
- // await page.goto(url, { timeout: 10_000, waitUntil: "load" })
await this.waitTillHTMLStable(page) // in case the page is loading more resources
})
}
- // page.goto { waitUntil: "networkidle0" } may not ever resolve, and not waiting could return page content too early before js has loaded
- // https://stackoverflow.com/questions/52497252/puppeteer-wait-until-page-is-completely-loaded/61304202#61304202
private async waitTillHTMLStable(page: Page, timeout = 5_000) {
const checkDurationMsecs = 500 // 1000
const maxChecks = timeout / checkDurationMsecs
@@ -186,7 +240,6 @@ export class BrowserSession {
let html = await page.content()
let currentHTMLSize = html.length
- // let bodyHTMLSize = await page.evaluate(() => document.body.innerHTML.length)
console.log("last: ", lastHTMLSize, " <> curr: ", currentHTMLSize)
if (lastHTMLSize !== 0 && currentHTMLSize === lastHTMLSize) {
@@ -267,4 +320,28 @@ export class BrowserSession {
await delay(300)
})
}
+
+ async takeScreenshot(interactive: boolean = false, port?: string): Promise {
+ this.isInteractive = interactive
+ this.browserPort = port ?? this.browserPort
+
+ // If no browser session exists or we're in interactive mode, try to connect
+ if ((!this.page || !this.browser) && this.isInteractive) {
+ this.browser = await this.puppeteerConnect(this.browserPort)
+
+ if (this.browser) {
+ const pages = await this.browser.pages()
+ this.page = pages[0] || await this.browser.newPage()
+ } else {
+ this.providerRef.deref()?.outputChannel.appendLine(`BrowserSession.ts :: takeScreenshot :: Failed to connect to browser for screenshot`)
+ throw new Error("Failed to connect to browser for screenshot")
+ }
+ }
+
+ return this.doAction(async (page) => {
+ // doAction will handle actually taking the screenshot
+ })
+ }
}
+
+
diff --git a/src/services/browser/UrlContentFetcher.ts b/src/services/browser/UrlContentFetcher.ts
index caf19ee83b1..59a770345ad 100644
--- a/src/services/browser/UrlContentFetcher.ts
+++ b/src/services/browser/UrlContentFetcher.ts
@@ -1,17 +1,9 @@
import * as vscode from "vscode"
import * as fs from "fs/promises"
import * as path from "path"
-import { Browser, Page, launch } from "puppeteer-core"
+import { Browser, Page, launch } from "puppeteer"
import * as cheerio from "cheerio"
import TurndownService from "turndown"
-// @ts-ignore
-import PCR from "puppeteer-chromium-resolver"
-import { fileExistsAtPath } from "../../utils/fs"
-
-interface PCRStats {
- puppeteer: { launch: typeof launch }
- executablePath: string
-}
export class UrlContentFetcher {
private context: vscode.ExtensionContext
@@ -22,34 +14,14 @@ export class UrlContentFetcher {
this.context = context
}
- private async ensureChromiumExists(): Promise {
- const globalStoragePath = this.context?.globalStorageUri?.fsPath
- if (!globalStoragePath) {
- throw new Error("Global storage uri is invalid")
- }
- const puppeteerDir = path.join(globalStoragePath, "puppeteer")
- const dirExists = await fileExistsAtPath(puppeteerDir)
- if (!dirExists) {
- await fs.mkdir(puppeteerDir, { recursive: true })
- }
- // if chromium doesn't exist, this will download it to path.join(puppeteerDir, ".chromium-browser-snapshots")
- // if it does exist it will return the path to existing chromium
- const stats: PCRStats = await PCR({
- downloadPath: puppeteerDir,
- })
- return stats
- }
-
async launchBrowser(): Promise {
if (this.browser) {
return
}
- const stats = await this.ensureChromiumExists()
- this.browser = await stats.puppeteer.launch({
+ this.browser = await launch({
args: [
"--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
],
- executablePath: stats.executablePath,
})
// (latest version of puppeteer does not add headless to user agent)
this.page = await this.browser?.newPage()
diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts
index e95bb80e03a..3040bb3e136 100644
--- a/src/shared/ExtensionMessage.ts
+++ b/src/shared/ExtensionMessage.ts
@@ -53,6 +53,8 @@ export interface ExtensionState {
soundEnabled?: boolean
soundVolume?: number
diffEnabled?: boolean
+ isInteractiveMode?: boolean
+ browserPort?: string
debugDiffEnabled?: boolean
}
@@ -113,10 +115,12 @@ export interface ClineSayTool {
content?: string
regex?: string
filePattern?: string
+ isInteractiveMode?: boolean
+ browserPort?: string
}
// must keep in sync with system prompt
-export const browserActions = ["launch", "click", "type", "scroll_down", "scroll_up", "close"] as const
+export const browserActions = ["launch", "click", "type", "scroll_down", "scroll_up", "close", "snapshot"] as const
export type BrowserAction = (typeof browserActions)[number]
export interface ClineSayBrowserAction {
diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts
index aca93e1569d..aee267d43ab 100644
--- a/src/shared/WebviewMessage.ts
+++ b/src/shared/WebviewMessage.ts
@@ -34,6 +34,8 @@ export interface WebviewMessage {
| "soundEnabled"
| "soundVolume"
| "diffEnabled"
+ | "isInteractiveMode"
+ | "browserPort"
| "debugDiffEnabled"
| "openMcpSettings"
| "restartMcpServer"
diff --git a/webview-ui/package-lock.json b/webview-ui/package-lock.json
index ade601f9a5c..7e301820c3b 100644
--- a/webview-ui/package-lock.json
+++ b/webview-ui/package-lock.json
@@ -76,7 +76,7 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.26.3",
+ "version": "7.26.2",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -110,6 +110,13 @@
"url": "https://opencollective.com/babel"
}
},
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/eslint-parser": {
"version": "7.25.9",
"license": "MIT",
@@ -133,12 +140,19 @@
"node": ">=10"
}
},
+ "node_modules/@babel/eslint-parser/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/generator": {
- "version": "7.26.3",
+ "version": "7.26.2",
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.26.3",
- "@babel/types": "^7.26.3",
+ "@babel/parser": "^7.26.2",
+ "@babel/types": "^7.26.0",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2"
@@ -157,6 +171,17 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.25.9",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helper-compilation-targets": {
"version": "7.25.9",
"license": "MIT",
@@ -171,6 +196,13 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/helper-create-class-features-plugin": {
"version": "7.25.9",
"license": "MIT",
@@ -190,12 +222,19 @@
"@babel/core": "^7.0.0"
}
},
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.26.3",
+ "version": "7.25.9",
"license": "MIT",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.25.9",
- "regexpu-core": "^6.2.0",
+ "regexpu-core": "^6.1.1",
"semver": "^6.3.1"
},
"engines": {
@@ -205,6 +244,13 @@
"@babel/core": "^7.0.0"
}
},
+ "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/helper-define-polyfill-provider": {
"version": "0.6.3",
"license": "MIT",
@@ -303,6 +349,17 @@
"@babel/core": "^7.0.0"
}
},
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.25.9",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
"version": "7.25.9",
"license": "MIT",
@@ -359,10 +416,10 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.26.3",
+ "version": "7.26.2",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.26.3"
+ "@babel/types": "^7.26.0"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -981,9 +1038,10 @@
}
},
"node_modules/@babel/plugin-transform-exponentiation-operator": {
- "version": "7.26.3",
+ "version": "7.25.9",
"license": "MIT",
"dependencies": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
@@ -1116,11 +1174,12 @@
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.26.3",
+ "version": "7.25.9",
"license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.26.0",
- "@babel/helper-plugin-utils": "^7.25.9"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-simple-access": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1452,6 +1511,13 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/plugin-transform-shorthand-properties": {
"version": "7.25.9",
"license": "MIT",
@@ -1519,7 +1585,7 @@
}
},
"node_modules/@babel/plugin-transform-typescript": {
- "version": "7.26.3",
+ "version": "7.25.9",
"license": "MIT",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.25.9",
@@ -1681,6 +1747,13 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/preset-env/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/preset-modules": {
"version": "0.1.6-no-external-plugins",
"license": "MIT",
@@ -1694,7 +1767,7 @@
}
},
"node_modules/@babel/preset-react": {
- "version": "7.26.3",
+ "version": "7.25.9",
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9",
@@ -1751,14 +1824,14 @@
}
},
"node_modules/@babel/traverse": {
- "version": "7.26.4",
+ "version": "7.25.9",
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.26.2",
- "@babel/generator": "^7.26.3",
- "@babel/parser": "^7.26.3",
+ "@babel/code-frame": "^7.25.9",
+ "@babel/generator": "^7.25.9",
+ "@babel/parser": "^7.25.9",
"@babel/template": "^7.25.9",
- "@babel/types": "^7.26.3",
+ "@babel/types": "^7.25.9",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -1767,7 +1840,7 @@
}
},
"node_modules/@babel/types": {
- "version": "7.26.3",
+ "version": "7.26.0",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.25.9",
@@ -3361,7 +3434,7 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "16.18.121",
+ "version": "16.18.120",
"license": "MIT"
},
"node_modules/@types/node-forge": {
@@ -3380,7 +3453,7 @@
"license": "MIT"
},
"node_modules/@types/prop-types": {
- "version": "15.7.14",
+ "version": "15.7.13",
"license": "MIT"
},
"node_modules/@types/q": {
@@ -3396,7 +3469,7 @@
"license": "MIT"
},
"node_modules/@types/react": {
- "version": "18.3.14",
+ "version": "18.3.12",
"license": "MIT",
"dependencies": {
"@types/prop-types": "*",
@@ -3404,10 +3477,10 @@
}
},
"node_modules/@types/react-dom": {
- "version": "18.3.2",
+ "version": "18.3.1",
"license": "MIT",
"dependencies": {
- "@types/react": "^18"
+ "@types/react": "*"
}
},
"node_modules/@types/resolve": {
@@ -3534,16 +3607,6 @@
}
}
},
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
- "version": "7.6.3",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@typescript-eslint/experimental-utils": {
"version": "5.62.0",
"license": "MIT",
@@ -3662,16 +3725,6 @@
}
}
},
- "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
- "version": "7.6.3",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@typescript-eslint/utils": {
"version": "5.62.0",
"license": "MIT",
@@ -3714,16 +3767,6 @@
"node": ">=4.0"
}
},
- "node_modules/@typescript-eslint/utils/node_modules/semver": {
- "version": "7.6.3",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.62.0",
"license": "MIT",
@@ -4477,6 +4520,13 @@
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
+ "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/babel-plugin-polyfill-corejs3": {
"version": "0.10.6",
"license": "MIT",
@@ -4749,13 +4799,14 @@
}
},
"node_modules/call-bind": {
- "version": "1.0.8",
+ "version": "1.0.7",
"license": "MIT",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.0",
"es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
- "set-function-length": "^1.2.2"
+ "set-function-length": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
@@ -4764,17 +4815,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.0",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
"node_modules/callsites": {
"version": "3.1.0",
"license": "MIT",
@@ -4825,7 +4865,7 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001687",
+ "version": "1.0.30001684",
"funding": [
{
"type": "opencollective",
@@ -5365,16 +5405,6 @@
}
}
},
- "node_modules/css-loader/node_modules/semver": {
- "version": "7.6.3",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/css-minimizer-webpack-plugin": {
"version": "3.4.1",
"license": "MIT",
@@ -5688,7 +5718,7 @@
}
},
"node_modules/debug": {
- "version": "4.4.0",
+ "version": "4.3.7",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -6014,18 +6044,6 @@
"version": "5.1.0",
"license": "BSD-2-Clause"
},
- "node_modules/dunder-proto": {
- "version": "1.0.0",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.0",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
"node_modules/duplexer": {
"version": "0.1.2",
"license": "MIT"
@@ -6052,7 +6070,7 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.71",
+ "version": "1.5.66",
"license": "ISC"
},
"node_modules/emittery": {
@@ -6178,8 +6196,11 @@
"license": "MIT"
},
"node_modules/es-define-property": {
- "version": "1.0.1",
+ "version": "1.0.0",
"license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4"
+ },
"engines": {
"node": ">= 0.4"
}
@@ -6510,6 +6531,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/eslint-plugin-import/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/eslint-plugin-jest": {
"version": "25.7.0",
"license": "MIT",
@@ -6631,6 +6659,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/eslint-plugin-react/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/eslint-plugin-testing-library": {
"version": "5.11.1",
"license": "MIT",
@@ -6933,7 +6968,7 @@
}
},
"node_modules/express": {
- "version": "4.21.2",
+ "version": "4.21.1",
"license": "MIT",
"dependencies": {
"accepts": "~1.3.8",
@@ -6955,7 +6990,7 @@
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
- "path-to-regexp": "0.1.12",
+ "path-to-regexp": "0.1.10",
"proxy-addr": "~2.0.7",
"qs": "6.13.0",
"range-parser": "~1.2.1",
@@ -6970,10 +7005,6 @@
},
"engines": {
"node": ">= 0.10.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
}
},
"node_modules/express/node_modules/debug": {
@@ -7345,16 +7376,6 @@
"url": "https://opencollective.com/webpack"
}
},
- "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": {
- "version": "7.6.3",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": {
"version": "1.1.3",
"license": "MIT",
@@ -7638,10 +7659,10 @@
}
},
"node_modules/gopd": {
- "version": "1.2.0",
+ "version": "1.0.1",
"license": "MIT",
- "engines": {
- "node": ">= 0.4"
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -7701,11 +7722,8 @@
}
},
"node_modules/has-proto": {
- "version": "1.2.0",
+ "version": "1.0.3",
"license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.0"
- },
"engines": {
"node": ">= 0.4"
},
@@ -7714,7 +7732,7 @@
}
},
"node_modules/has-symbols": {
- "version": "1.1.0",
+ "version": "1.0.3",
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -8258,13 +8276,10 @@
}
},
"node_modules/is-bigint": {
- "version": "1.1.0",
+ "version": "1.0.4",
"license": "MIT",
"dependencies": {
- "has-bigints": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
+ "has-bigints": "^1.0.1"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -8281,11 +8296,11 @@
}
},
"node_modules/is-boolean-object": {
- "version": "1.2.0",
+ "version": "1.1.2",
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
- "has-tostringtag": "^1.0.2"
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -8482,11 +8497,10 @@
}
},
"node_modules/is-number-object": {
- "version": "1.1.0",
+ "version": "1.0.7",
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
- "has-tostringtag": "^1.0.2"
+ "has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -8521,13 +8535,11 @@
"license": "MIT"
},
"node_modules/is-regex": {
- "version": "1.2.0",
+ "version": "1.1.4",
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
- "gopd": "^1.1.0",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -8584,11 +8596,10 @@
}
},
"node_modules/is-string": {
- "version": "1.1.0",
+ "version": "1.0.7",
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
- "has-tostringtag": "^1.0.2"
+ "has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -8598,12 +8609,10 @@
}
},
"node_modules/is-symbol": {
- "version": "1.1.0",
+ "version": "1.0.4",
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
- "has-symbols": "^1.0.3",
- "safe-regex-test": "^1.0.3"
+ "has-symbols": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -8702,6 +8711,13 @@
"node": ">=8"
}
},
+ "node_modules/istanbul-lib-instrument/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/istanbul-lib-report": {
"version": "3.0.1",
"license": "BSD-3-Clause",
@@ -8727,16 +8743,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/istanbul-lib-report/node_modules/semver": {
- "version": "7.6.3",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/istanbul-lib-source-maps": {
"version": "4.0.1",
"license": "BSD-3-Clause",
@@ -9280,16 +9286,6 @@
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
- "node_modules/jest-snapshot/node_modules/semver": {
- "version": "7.6.3",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/jest-util": {
"version": "27.5.1",
"license": "MIT",
@@ -9968,6 +9964,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "6.3.1",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/makeerror": {
"version": "1.0.12",
"license": "BSD-3-Clause",
@@ -10406,7 +10409,7 @@
}
},
"node_modules/nwsapi": {
- "version": "2.2.16",
+ "version": "2.2.13",
"license": "MIT"
},
"node_modules/object-assign": {
@@ -10773,7 +10776,7 @@
"license": "ISC"
},
"node_modules/path-to-regexp": {
- "version": "0.1.12",
+ "version": "0.1.10",
"license": "MIT"
},
"node_modules/path-type": {
@@ -11340,7 +11343,7 @@
}
},
"node_modules/postcss-load-config/node_modules/lilconfig": {
- "version": "3.1.3",
+ "version": "3.1.2",
"license": "MIT",
"engines": {
"node": ">=14"
@@ -11379,16 +11382,6 @@
"webpack": "^5.0.0"
}
},
- "node_modules/postcss-loader/node_modules/semver": {
- "version": "7.6.3",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/postcss-logical": {
"version": "5.0.4",
"license": "CC0-1.0",
@@ -12129,13 +12122,10 @@
}
},
"node_modules/psl": {
- "version": "1.15.0",
+ "version": "1.13.0",
"license": "MIT",
"dependencies": {
"punycode": "^2.3.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/lupomontero"
}
},
"node_modules/punycode": {
@@ -12471,16 +12461,6 @@
}
}
},
- "node_modules/react-scripts/node_modules/semver": {
- "version": "7.6.3",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/react-textarea-autosize": {
"version": "8.5.5",
"license": "MIT",
@@ -12528,7 +12508,7 @@
}
},
"node_modules/react-virtuoso": {
- "version": "4.12.3",
+ "version": "4.12.2",
"license": "MIT",
"engines": {
"node": ">=10"
@@ -12589,17 +12569,16 @@
}
},
"node_modules/reflect.getprototypeof": {
- "version": "1.0.8",
+ "version": "1.0.7",
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.8",
+ "call-bind": "^1.0.7",
"define-properties": "^1.2.1",
- "dunder-proto": "^1.0.0",
"es-abstract": "^1.23.5",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
- "gopd": "^1.2.0",
- "which-builtin-type": "^1.2.0"
+ "gopd": "^1.0.1",
+ "which-builtin-type": "^1.1.4"
},
"engines": {
"node": ">= 0.4"
@@ -13159,10 +13138,13 @@
}
},
"node_modules/semver": {
- "version": "6.3.1",
+ "version": "7.6.3",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/send": {
@@ -14223,7 +14205,7 @@
"license": "MIT"
},
"node_modules/tailwindcss": {
- "version": "3.4.16",
+ "version": "3.4.15",
"license": "MIT",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
@@ -14235,7 +14217,7 @@
"glob-parent": "^6.0.2",
"is-glob": "^4.0.3",
"jiti": "^1.21.6",
- "lilconfig": "^3.1.3",
+ "lilconfig": "^2.1.0",
"micromatch": "^4.0.8",
"normalize-path": "^3.0.0",
"object-hash": "^3.0.0",
@@ -14257,16 +14239,6 @@
"node": ">=14.0.0"
}
},
- "node_modules/tailwindcss/node_modules/lilconfig": {
- "version": "3.1.3",
- "license": "MIT",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antonk52"
- }
- },
"node_modules/tapable": {
"version": "2.2.1",
"license": "MIT",
@@ -14322,7 +14294,7 @@
}
},
"node_modules/terser": {
- "version": "5.37.0",
+ "version": "5.36.0",
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
@@ -14981,10 +14953,10 @@
}
},
"node_modules/use-isomorphic-layout-effect": {
- "version": "1.2.0",
+ "version": "1.1.2",
"license": "MIT",
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -15162,14 +15134,14 @@
}
},
"node_modules/webpack": {
- "version": "5.97.1",
+ "version": "5.96.1",
"license": "MIT",
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.6",
- "@webassemblyjs/ast": "^1.14.1",
- "@webassemblyjs/wasm-edit": "^1.14.1",
- "@webassemblyjs/wasm-parser": "^1.14.1",
+ "@webassemblyjs/ast": "^1.12.1",
+ "@webassemblyjs/wasm-edit": "^1.12.1",
+ "@webassemblyjs/wasm-parser": "^1.12.1",
"acorn": "^8.14.0",
"browserslist": "^4.24.0",
"chrome-trace-event": "^1.0.2",
@@ -15445,17 +15417,14 @@
}
},
"node_modules/which-boxed-primitive": {
- "version": "1.1.0",
+ "version": "1.0.2",
"license": "MIT",
"dependencies": {
- "is-bigint": "^1.1.0",
- "is-boolean-object": "^1.2.0",
- "is-number-object": "^1.1.0",
- "is-string": "^1.1.0",
- "is-symbol": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx
index e1c9701596f..d005ef6ee91 100644
--- a/webview-ui/src/components/settings/SettingsView.tsx
+++ b/webview-ui/src/components/settings/SettingsView.tsx
@@ -38,6 +38,10 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
openRouterModels,
setAllowedCommands,
allowedCommands,
+ isInteractiveMode,
+ setInteractiveBrowserMode,
+ browserPort,
+ setBrowserPort,
} = useExtensionState()
const [apiErrorMessage, setApiErrorMessage] = useState(undefined)
const [modelIdErrorMessage, setModelIdErrorMessage] = useState(undefined)
@@ -64,6 +68,8 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
vscode.postMessage({ type: "soundEnabled", bool: soundEnabled })
vscode.postMessage({ type: "soundVolume", value: soundVolume })
vscode.postMessage({ type: "diffEnabled", bool: diffEnabled })
+ vscode.postMessage({ type: "isInteractiveMode", bool: isInteractiveMode })
+ vscode.postMessage({ type: "browserPort", text: browserPort })
vscode.postMessage({ type: "debugDiffEnabled", bool: debugDiffEnabled })
onDone()
}
@@ -374,6 +380,45 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
+
+
Browser Settings
+
+
+
setInteractiveBrowserMode(e.target.checked)}
+ >
+ Interactive Browser Mode
+
+
+ When enabled, connects to an existing Chrome instance instead of launching a new browser.
+
+
+
+ {isInteractiveMode && (
+
+
setBrowserPort(e.target.value)}
+ placeholder="Browser debugging port (default: 7333)"
+ >
+ Browser Port
+
+
+ Port number for Chrome's remote debugging. Launch Chrome with --remote-debugging-port=PORT
+
+
+ )}
+
+
{IS_DEV && (
<>
Debug
diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx
index f4fdaa3e0f4..19af3517b3d 100644
--- a/webview-ui/src/context/ExtensionStateContext.tsx
+++ b/webview-ui/src/context/ExtensionStateContext.tsx
@@ -31,6 +31,8 @@ export interface ExtensionStateContextType extends ExtensionState {
setSoundEnabled: (value: boolean) => void
setSoundVolume: (value: number) => void
setDiffEnabled: (value: boolean) => void
+ setInteractiveBrowserMode: (value: boolean) => void
+ setBrowserPort: (value: string) => void
setDebugDiffEnabled: (value: boolean) => void
}
@@ -46,6 +48,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
soundEnabled: false,
soundVolume: 0.5,
diffEnabled: false,
+ isInteractiveMode: false,
+ browserPort: "7333",
debugDiffEnabled: false,
})
const [didHydrateState, setDidHydrateState] = useState(false)
@@ -149,6 +153,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
setSoundEnabled: (value) => setState((prevState) => ({ ...prevState, soundEnabled: value })),
setSoundVolume: (value) => setState((prevState) => ({ ...prevState, soundVolume: value })),
setDiffEnabled: (value) => setState((prevState) => ({ ...prevState, diffEnabled: value })),
+ setInteractiveBrowserMode: (value) => setState((prevState) => ({ ...prevState, isInteractiveMode: value })),
+ setBrowserPort: (value) => setState((prevState) => ({ ...prevState, browserPort: value })),
setDebugDiffEnabled: (value) => setState((prevState) => ({
...prevState,
debugDiffEnabled: value