diff --git a/.gitignore b/.gitignore index 404d9e2630..19f0b5a72c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,7 @@ node_modules .DS_Store -.npmrc \ No newline at end of file +.npmrc + +# Builds +bin \ No newline at end of file diff --git a/README.md b/README.md index 9c8c5287e7..a326f9c6e5 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ``` 2. Build the VSIX file: ```bash - npm run vsix + npm run build ``` 3. The new VSIX file will be created in the `bin/` directory 4. Commit the new VSIX file to git: diff --git a/docs/cline-updates.md b/docs/cline-updates.md new file mode 100644 index 0000000000..9e8257e623 --- /dev/null +++ b/docs/cline-updates.md @@ -0,0 +1,7 @@ +Remember to rebuild the extension and install it using the cli specified on the `Roo-Cline/README.md` file, also remember to change directory to the `Roo-Cline` folder before running the commands from the readme. + +Consider that any `export` or `install` command has already been run, so exclude those.ˆ + + +First, read the original 'Cline.ts' file to understand its full content +Then create a new file with the -updates suffix containing ONLY the changes \ No newline at end of file diff --git a/docs/cypress-cloud.md b/docs/cypress-cloud.md new file mode 100644 index 0000000000..0d2838a9f1 --- /dev/null +++ b/docs/cypress-cloud.md @@ -0,0 +1,2 @@ +Could you navigate to this URL in interactive mode (isInteractive = true), and keep it open while I chat with you, DO NOT DO ANYTHING UNTIL I TELL YOU TO CONTINUE. +https://cloud.cypress.io/projects/hkawvm/runs/22055/overview/b890f243-ce56-4047-9252-c99469dfbbea?roarHideRunsWithDiffGroupsAndTags=1&interactive=true \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index ad74e997ea..4e27547ad0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "roo-cline", - "version": "2.0.2", + "version": "2.0.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "roo-cline", - "version": "2.0.2", + "version": "2.0.4", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", "@anthropic-ai/sdk": "^0.26.0", @@ -37,6 +37,7 @@ "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" }, "devDependencies": { @@ -6519,6 +6520,15 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/azure-devops-node-api": { + "version": "11.2.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/b4a/-/b4a-1.6.7.tgz", @@ -6655,8 +6665,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bare-events": { "version": "2.5.0", @@ -6949,7 +6958,6 @@ "version": "1.0.7", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -7108,6 +7116,11 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "node_modules/chromium-bidi": { "version": "0.8.0", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/chromium-bidi/-/chromium-bidi-0.8.0.tgz", @@ -7302,8 +7315,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/convert-source-map": { "version": "2.0.0", @@ -7488,6 +7500,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/dedent/-/dedent-1.5.3.tgz", @@ -7502,6 +7528,14 @@ } } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/deep-is/-/deep-is-0.1.4.tgz", @@ -7532,7 +7566,6 @@ "version": "1.1.4", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -7603,6 +7636,14 @@ "node": ">=8" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/detect-newline/-/detect-newline-3.1.0.tgz", @@ -7942,7 +7983,6 @@ "version": "1.0.0", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -7954,7 +7994,6 @@ "version": "1.3.0", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -8334,6 +8373,14 @@ "node": ">= 0.8.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/expect/-/expect-29.7.0.tgz", @@ -8666,6 +8713,11 @@ "node": ">= 12.20" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/fs-extra/-/fs-extra-7.0.1.tgz", @@ -8682,8 +8734,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -8700,7 +8751,6 @@ "version": "1.1.2", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8780,7 +8830,6 @@ "version": "1.2.4", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -8879,6 +8928,11 @@ "node": ">= 10.0.0" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/glob/-/glob-10.4.5.tgz", @@ -8980,7 +9034,6 @@ "version": "1.0.1", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -9033,7 +9086,6 @@ "version": "1.0.2", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -9045,7 +9097,6 @@ "version": "1.0.3", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -9057,7 +9108,6 @@ "version": "1.0.3", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -9084,7 +9134,6 @@ "version": "2.0.2", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -9268,7 +9317,6 @@ "version": "1.0.6", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -9279,6 +9327,11 @@ "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "node_modules/internal-slot": { "version": "1.0.7", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/internal-slot/-/internal-slot-1.0.7.tgz", @@ -10633,6 +10686,16 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/keytar": { + "version": "7.9.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/keyv/-/keyv-4.5.4.tgz", @@ -10663,7 +10726,6 @@ "version": "3.1.0", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, "engines": { "node": ">=6" } @@ -10694,6 +10756,14 @@ "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/load-json-file/-/load-json-file-4.0.0.tgz", @@ -10876,6 +10946,34 @@ "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/memorystream/-/memorystream-0.3.1.tgz", @@ -10910,6 +11008,17 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/mime-db/-/mime-db-1.52.0.tgz", @@ -10938,6 +11047,17 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/minimatch/-/minimatch-9.0.5.tgz", @@ -10953,6 +11073,14 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/minipass/-/minipass-7.1.2.tgz", @@ -10967,6 +11095,11 @@ "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/mocha": { "version": "10.8.2", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/mocha/-/mocha-10.8.2.tgz", @@ -11179,6 +11312,16 @@ "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/natural-compare/-/natural-compare-1.4.0.tgz", @@ -11199,6 +11342,22 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node_modules/node-abi": { + "version": "3.71.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/node-domexception/-/node-domexception-1.0.0.tgz", @@ -11495,7 +11654,6 @@ "version": "1.13.2", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -11889,6 +12047,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-semver": { + "version": "1.1.1", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/parse5": { "version": "7.2.1", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/parse5/-/parse5-7.2.1.tgz", @@ -12131,6 +12305,103 @@ "node": ">= 0.4" } }, + "node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -12314,6 +12585,20 @@ } ] }, + "node_modules/qs": { + "version": "6.13.1", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -12347,12 +12632,45 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/read-pkg/-/read-pkg-3.0.0.tgz", @@ -12733,6 +13051,11 @@ "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/semver/-/semver-7.6.3.tgz", @@ -12782,7 +13105,6 @@ "version": "1.2.2", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -12858,7 +13180,6 @@ "version": "1.0.6", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -12883,6 +13204,49 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/sisteransi/-/sisteransi-1.0.5.tgz", @@ -13607,6 +13971,25 @@ "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/turndown/-/turndown-7.2.0.tgz", @@ -13726,6 +14109,16 @@ "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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.6.3", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/typescript/-/typescript-5.6.3.tgz", @@ -13739,6 +14132,11 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -13862,6 +14260,11 @@ "punycode": "^2.1.0" } }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, "node_modules/urlpattern-polyfill": { "version": "10.0.0", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", @@ -13908,6 +14311,194 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/vsce": { + "version": "2.15.0", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/walker/-/walker-1.0.8.tgz", @@ -14286,6 +14877,26 @@ } } }, + "node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/xmlbuilder/-/xmlbuilder-10.1.1.tgz", @@ -14406,6 +15017,14 @@ "fd-slicer": "~1.1.0" } }, + "node_modules/yazl": { + "version": "2.5.1", + "resolved": "https://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/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://roo-815250993495.d.codeartifact.us-east-1.amazonaws.com/npm/roo-dev/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index b3aa18356c..cb61541175 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "roo-cline", "displayName": "Roo Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "2.0.2", + "version": "2.0.4", "icon": "assets/icons/icon_Roo.png", "galleryBanner": { "color": "#617A91", @@ -114,6 +114,7 @@ } }, "scripts": { + "build": "npm run build:webview && npm run vsix", "build:webview": "cd webview-ui && npm run build", "changeset": "changeset", "check-types": "tsc --noEmit", @@ -186,6 +187,7 @@ "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" }, "files": [ diff --git a/scripts/codeartifact-login.sh b/scripts/codeartifact-login.sh old mode 100644 new mode 100755 diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 5b407f0ebf..2c550298c9 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -73,6 +73,7 @@ export class Cline { private urlContentFetcher: UrlContentFetcher private browserSession: BrowserSession private didEditFile: boolean = false + private isInteractiveMode: boolean = false customInstructions?: string alwaysAllowReadOnly: boolean alwaysAllowWrite: boolean @@ -1441,103 +1442,139 @@ export class Cline { if (action === "launch") { if (!url) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("browser_action", "url") - ) + 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 - - await this.browserSession.launchBrowser() - browserActionResult = await this.browserSession.navigateToUrl(url) - } else { - if (action === "click") { - if (!coordinate) { - this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("browser_action", "coordinate") - ) - await this.browserSession.closeBrowser() - break // can't be within an inner switch - } - } - if (action === "type") { - if (!text) { - this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("browser_action", "text") - ) - await this.browserSession.closeBrowser() + + // Check if this is an interactive mode request + const isInteractiveRequest = url.toLowerCase().includes("interactive=true") + const actualUrl = isInteractiveRequest ? url.replace(/[?&]interactive=true/i, '') : url + + if (isInteractiveRequest) { + this.isInteractiveMode = true + this.consecutiveMistakeCount = 0 + const didApprove = await askApproval("browser_action_launch", + `Launch browser in interactive mode for URL: ${actualUrl}`) + if (!didApprove) { break } - } - this.consecutiveMistakeCount = 0 - await this.say( - "browser_action", - JSON.stringify({ - action: action as BrowserAction, - coordinate, - text, - } satisfies ClineSayBrowserAction), - undefined, - false - ) - switch (action) { - case "click": - browserActionResult = await this.browserSession.click(coordinate!) - break - case "type": - browserActionResult = await this.browserSession.type(text!) - break - case "scroll_down": - browserActionResult = await this.browserSession.scrollDown() - break - case "scroll_up": - browserActionResult = await this.browserSession.scrollUp() - break - case "close": - browserActionResult = await this.browserSession.closeBrowser() - break - } - } - - switch (action) { - case "launch": - case "click": - case "type": - case "scroll_down": - case "scroll_up": + + await this.browserSession.launchBrowser(true) + browserActionResult = await this.browserSession.navigateToUrl(actualUrl) + await this.say("browser_action_result", JSON.stringify(browserActionResult)) pushToolResult( formatResponse.toolResult( - `The browser action has been executed. The console logs and screenshot 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.)`, + `Browser launched in interactive mode. The browser will remain open for manual interaction until explicitly closed. You can:\n` + + `1. Keep browsing\n` + + `2. Take another action\n` + + `3. Close the browser\n\n` + + `Console logs:\n${browserActionResult.logs || "(No new logs)"}`, browserActionResult.screenshot ? [browserActionResult.screenshot] : [] ) ) break - case "close": + } else { + this.isInteractiveMode = false + 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 + + await this.browserSession.launchBrowser() + browserActionResult = await this.browserSession.navigateToUrl(actualUrl) + } + + } else if (action === "close") { + // Handle close action for interactive mode + if (this.isInteractiveMode) { + browserActionResult = await this.browserSession.closeBrowser() + if (browserActionResult.logs?.includes("Would you like to:")) { + // Browser is asking for confirmation + await this.say("browser_action_result", JSON.stringify(browserActionResult)) + pushToolResult( + formatResponse.toolResult( + `The browser is in interactive mode. Please confirm if you want to:\n` + + `1. Keep browsing\n` + + `2. Take another action\n` + + `3. Close the browser`, + browserActionResult.screenshot ? [browserActionResult.screenshot] : [] + ) + ) + break + } + this.isInteractiveMode = false + } else { + browserActionResult = await this.browserSession.closeBrowser() + } + } else { + // Handle other actions (click, type, scroll) + if (this.isInteractiveMode) { pushToolResult( formatResponse.toolResult( - `The browser has been closed. You may now proceed to using other tools.` + `Cannot perform browser actions while in interactive mode. The user has manual control. You can:\n` + + `1. Keep browsing\n` + + `2. Take another action\n` + + `3. Close the browser` ) ) break + } + + if (action === "click") { + if (!coordinate) { + this.consecutiveMistakeCount++ + pushToolResult(await this.sayAndCreateMissingParamError("browser_action", "coordinate")) + await this.browserSession.closeBrowser() + break + } + browserActionResult = await this.browserSession.click(coordinate) + } else if (action === "type") { + if (!text) { + this.consecutiveMistakeCount++ + pushToolResult(await this.sayAndCreateMissingParamError("browser_action", "text")) + await this.browserSession.closeBrowser() + break + } + browserActionResult = await this.browserSession.type(text) + } else if (action === "scroll_down") { + browserActionResult = await this.browserSession.scrollDown() + } else if (action === "scroll_up") { + browserActionResult = await this.browserSession.scrollUp() + } else { + throw new Error(`Unsupported browser action: ${action}`) + } + } + + // Handle results for all actions except interactive mode close confirmation + if (action === "close" && !browserActionResult.logs?.includes("Would you like to:")) { + pushToolResult(formatResponse.toolResult("Browser has been closed.")) + } else if (action !== "close") { + await this.say("browser_action_result", JSON.stringify(browserActionResult)) + pushToolResult( + formatResponse.toolResult( + `The browser action has been executed. The console logs and screenshot have been captured for your analysis.\n\nConsole logs:\n${ + browserActionResult.logs || "(No new logs)" + }\n\n${ + this.isInteractiveMode ? + "The browser is in interactive mode. You can:\n1. Keep browsing\n2. Take another action\n3. Close the browser" : + "(REMEMBER: if you need to proceed to using non-`browser_action` tools or launch a new browser, you MUST first close this browser.)" + }`, + browserActionResult.screenshot ? [browserActionResult.screenshot] : [] + ) + ) } break } } catch (error) { - await this.browserSession.closeBrowser() // if any error occurs, the browser session is terminated + await this.browserSession.closeBrowser() await handleError("executing browser action", error) break } @@ -1681,15 +1718,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 @@ -1700,20 +1735,22 @@ 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) + // Only close browser if not in interactive mode + if (!this.browserSession.isInInteractiveMode) { + await this.browserSession.closeBrowser() + } + pushToolResult("") break } await this.say("user_feedback", text ?? "", images) - + const toolResults: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] = [] if (commandResult) { if (typeof commandResult === "string") { @@ -1732,11 +1769,11 @@ export class Cline { text: `${toolDescription()} Result:`, }) this.userMessageContent.push(...toolResults) - + break } } catch (error) { - await handleError("inspecting site", error) + await handleError("completing task", error) break } } diff --git a/src/services/browser/BrowserSession.ts b/src/services/browser/BrowserSession.ts index f84f2bda97..2f13f5a07a 100644 --- a/src/services/browser/BrowserSession.ts +++ b/src/services/browser/BrowserSession.ts @@ -12,50 +12,196 @@ export class BrowserSession { private browser?: Browser private page?: Page private currentMousePosition?: string + private isInteractive: boolean = false + private lastInteractionTime: number = 0 + private readonly TIMEOUT_MINUTES = 15 + private closeRequested: boolean = false + private timeoutCheckInterval?: NodeJS.Timeout constructor(context: vscode.ExtensionContext) { this.context = context } - async launchBrowser() { + async launchBrowser(interactive: boolean = false) { console.log("launch browser called") 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 } + this.isInteractive = interactive + 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", ], - defaultViewport: { + defaultViewport: this.isInteractive ? { width: 1300, height: 1000 } : { width: 900, height: 600, }, - // headless: false, + headless: false, // Always use non-headless mode }) - // (latest version of puppeteer does not add headless to user agent) this.page = await this.browser?.newPage() + + if (this.isInteractive && this.page) { + // Maximize the window to use full screen dimensions + const session = await this.page.target().createCDPSession() + const { windowId } = await session.send('Browser.getWindowForTarget') + await session.send('Browser.setWindowBounds', { windowId, bounds: { windowState: 'normal' } }) + + // Disable Puppeteer's automation features in interactive mode + await this.page.evaluate(() => { + // @ts-ignore + delete window.navigator.webdriver + }) + } + + // Reset flags + this.closeRequested = false + this.lastInteractionTime = Date.now() + + // Start timeout monitoring if not in interactive mode + if (!this.isInteractive) { + this.startTimeoutMonitoring() + } + + return { + screenshot: "", + logs: this.isInteractive ? + "Browser launched in interactive mode. Please confirm when you're done using the browser." : + "Browser launched successfully.", + currentUrl: this.page?.url(), + currentMousePosition: this.currentMousePosition, + } + } + + private startTimeoutMonitoring() { + // Clear any existing interval + if (this.timeoutCheckInterval) { + clearInterval(this.timeoutCheckInterval) + } + + // Only start monitoring if not in interactive mode + if (!this.isInteractive) { + this.timeoutCheckInterval = setInterval(async () => { + const timeSinceLastInteraction = Date.now() - this.lastInteractionTime + if (timeSinceLastInteraction > this.TIMEOUT_MINUTES * 60 * 1000) { + if (this.timeoutCheckInterval) { + clearInterval(this.timeoutCheckInterval) + } + console.log("Browser timeout reached, closing...") + await this.closeBrowser() + } + }, 30000) // Check every 30 seconds + } } async closeBrowser(): Promise { - if (this.browser || this.page) { + // If in interactive mode and close hasn't been requested yet, ask for confirmation + if (this.isInteractive && !this.closeRequested) { + console.log("Close requested but waiting for user confirmation...") + this.closeRequested = true + return { + logs: "Are you done using the browser? Please confirm to close it.", + screenshot: await this.getCurrentScreenshot(), + currentUrl: this.page?.url(), + currentMousePosition: this.currentMousePosition, + } + } + + // Only close if explicitly requested or not in interactive mode + if (!this.isInteractive || (this.isInteractive && this.closeRequested)) { console.log("closing browser...") await this.browser?.close().catch(() => {}) this.browser = undefined this.page = undefined this.currentMousePosition = undefined + this.isInteractive = false + this.closeRequested = false + + // Clear timeout monitoring + if (this.timeoutCheckInterval) { + clearInterval(this.timeoutCheckInterval) + this.timeoutCheckInterval = undefined + } } return {} } + private async getCurrentScreenshot(): Promise { + if (!this.page) return undefined + + let options: ScreenshotOptions = { + encoding: "base64", + } + + try { + let screenshotBase64 = await this.page.screenshot({ + ...options, + type: "webp", + }) + return `data:image/webp;base64,${screenshotBase64}` + } catch (err) { + try { + let screenshotBase64 = await this.page.screenshot({ + ...options, + type: "png", + }) + return `data:image/png;base64,${screenshotBase64}` + } catch (err) { + console.error("Failed to take screenshot:", err) + return undefined + } + } + } + + async handleNextStep(choice: string): Promise { + const normalizedChoice = choice.toLowerCase().trim() + + if (normalizedChoice === "yes" || normalizedChoice === "done" || normalizedChoice === "confirm") { + await this.browser?.close().catch(() => {}) + this.browser = undefined + this.page = undefined + this.currentMousePosition = undefined + this.isInteractive = false + this.closeRequested = false + + if (this.timeoutCheckInterval) { + clearInterval(this.timeoutCheckInterval) + this.timeoutCheckInterval = undefined + } + return {} + } + + if (normalizedChoice === "no" || normalizedChoice === "continue") { + this.closeRequested = false + this.lastInteractionTime = Date.now() + return { + logs: "Browser session continued. Please confirm when you're done.", + screenshot: await this.getCurrentScreenshot(), + currentUrl: this.page?.url(), + currentMousePosition: this.currentMousePosition, + } + } + + // Default response for unclear input + return { + logs: "Please confirm if you're done using the browser (yes/no).", + screenshot: await this.getCurrentScreenshot(), + currentUrl: this.page?.url(), + currentMousePosition: this.currentMousePosition, + } + } + async doAction(action: (page: Page) => Promise): Promise { 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." + "Browser is not launched. Please launch a browser session first." ) } + // Update last interaction time + this.lastInteractionTime = Date.now() + const logs: string[] = [] let lastLogTs = Date.now() @@ -78,7 +224,11 @@ export class BrowserSession { this.page.on("pageerror", errorListener) try { - await action(this.page) + if (!this.isInteractive) { + await action(this.page) + } else { + console.log("Browser actions cannot be performed in interactive mode. The user has manual control.") + } } catch (err) { if (!(err instanceof TimeoutError)) { logs.push(`[Error] ${err.toString()}`) @@ -91,37 +241,11 @@ export class BrowserSession { 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) @@ -135,17 +259,13 @@ 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 checkDurationMsecs = 500 const maxChecks = timeout / checkDurationMsecs let lastHTMLSize = 0 let checkCounts = 1 @@ -156,7 +276,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) { @@ -237,4 +356,8 @@ export class BrowserSession { await delay(300) }) } + + get isInInteractiveMode(): boolean { + return this.isInteractive + } }