From b5d03dd523cd8a802825c724a61853dacf009e2f Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 29 Nov 2024 00:23:55 -0800 Subject: [PATCH 01/29] Add link to careers page --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6fa1a76990..9740b9123a 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,10 @@ Join the Discord -Docs +Feature Requests -Feature Requests +We're Hiring! @@ -99,7 +99,7 @@ Try asking Cline to "test the app", and watch as he runs a command like `npm run ## Contributing -To contribute to the project, start by exploring [open issues](https://github.com/cline/cline/issues) or checking our [feature request board](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop). We'd also love to have you join our [Discord](https://discord.gg/cline) to share ideas and connect with other contributors. +To contribute to the project, start by exploring [open issues](https://github.com/cline/cline/issues) or checking our [feature request board](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop). We'd also love to have you join our [Discord](https://discord.gg/cline) to share ideas and connect with other contributors. If you're interested in joining the team, check out our [careers page](https://cline.bot/join-us)!
Local Development Instructions From 84c808a6202ae9a8c74aab152d683f8e05fc47c0 Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 13:33:35 -0800 Subject: [PATCH 02/29] Adding husky hooks --- .gitignore | 2 + .husky/pre-commit | 8 + .husky/pre-push | 17 ++ package-lock.json | 756 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- 5 files changed, 787 insertions(+), 1 deletion(-) create mode 100644 .husky/pre-commit create mode 100644 .husky/pre-push diff --git a/.gitignore b/.gitignore index 98e1843e1b..288eb8ece6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ node_modules .npmrc roo-cline-*.vsix + +prompts \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000000..a040d1c301 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,8 @@ +branch="$(git rev-parse --abbrev-ref HEAD)" + +if [ "$branch" = "main" ]; then + echo "You can't commit directly to main - please check out a branch." + exit 1 +fi + +# TO DO: npx lint-staged diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100644 index 0000000000..fc1f203ade --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,17 @@ +branch="$(git rev-parse --abbrev-ref HEAD)" + +if [ "$branch" = "main" ]; then + echo "You can't push directly to main - please check out a branch." + exit 1 +fi + +# TO DO: npx tsc-silent -p tsconfig.json --suppressConfig tsc-silent.config.js + +# Check for new changesets +NEW_CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') +echo "Changeset files: $NEW_CHANGESETS" +if [ "$NEW_CHANGESETS" == "0" ]; then + echo "-------------------------------------------------------------------------------------" + echo "Changes detected. Please run 'npm run changeset' to create a changeset if applicable." + echo "-------------------------------------------------------------------------------------" +fi \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e1825d788e..891174c0d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,6 +42,7 @@ "web-tree-sitter": "^0.22.6" }, "devDependencies": { + "@changesets/cli": "^2.27.1", "@types/diff": "^5.2.1", "@types/jest": "^29.5.14", "@types/mocha": "^10.0.7", @@ -52,6 +53,7 @@ "@vscode/test-electron": "^2.4.0", "esbuild": "^0.24.0", "eslint": "^8.57.0", + "husky": "^9.1.7", "jest": "^29.7.0", "npm-run-all": "^4.1.5", "ts-jest": "^29.2.5", @@ -2621,6 +2623,18 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", @@ -2681,6 +2695,293 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@changesets/apply-release-plan": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.6.tgz", + "integrity": "sha512-TKhVLtiwtQOgMAC0fCJfmv93faiViKSDqr8oMEqrnNs99gtSC1sZh/aEMS9a+dseU1ESZRCK+ofLgGY7o0fw/Q==", + "dev": true, + "dependencies": { + "@changesets/config": "^3.0.4", + "@changesets/get-version-range-type": "^0.4.0", + "@changesets/git": "^3.0.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "detect-indent": "^6.0.0", + "fs-extra": "^7.0.1", + "lodash.startcase": "^4.4.0", + "outdent": "^0.5.0", + "prettier": "^2.7.1", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/apply-release-plan/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@changesets/assemble-release-plan": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.5.tgz", + "integrity": "sha512-IgvBWLNKZd6k4t72MBTBK3nkygi0j3t3zdC1zrfusYo0KpdsvnDjrMM9vPnTCLCMlfNs55jRL4gIMybxa64FCQ==", + "dev": true, + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.0.tgz", + "integrity": "sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==", + "dev": true, + "dependencies": { + "@changesets/types": "^6.0.0" + } + }, + "node_modules/@changesets/cli": { + "version": "2.27.10", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.27.10.tgz", + "integrity": "sha512-PfeXjvs9OfQJV8QSFFHjwHX3QnUL9elPEQ47SgkiwzLgtKGyuikWjrdM+lO9MXzOE22FO9jEGkcs4b+B6D6X0Q==", + "dev": true, + "dependencies": { + "@changesets/apply-release-plan": "^7.0.6", + "@changesets/assemble-release-plan": "^6.0.5", + "@changesets/changelog-git": "^0.2.0", + "@changesets/config": "^3.0.4", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/get-release-plan": "^4.0.5", + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@changesets/write": "^0.3.2", + "@manypkg/get-packages": "^1.1.3", + "ansi-colors": "^4.1.3", + "ci-info": "^3.7.0", + "enquirer": "^2.3.0", + "external-editor": "^3.1.0", + "fs-extra": "^7.0.1", + "mri": "^1.2.0", + "p-limit": "^2.2.0", + "package-manager-detector": "^0.2.0", + "picocolors": "^1.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.3", + "spawndamnit": "^3.0.1", + "term-size": "^2.1.0" + }, + "bin": { + "changeset": "bin.js" + } + }, + "node_modules/@changesets/cli/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@changesets/cli/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@changesets/config": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.0.4.tgz", + "integrity": "sha512-+DiIwtEBpvvv1z30f8bbOsUQGuccnZl9KRKMM/LxUHuDu5oEjmN+bJQ1RIBKNJjfYMQn8RZzoPiX0UgPaLQyXw==", + "dev": true, + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/logger": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1", + "micromatch": "^4.0.8" + } + }, + "node_modules/@changesets/errors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", + "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", + "dev": true, + "dependencies": { + "extendable-error": "^0.1.5" + } + }, + "node_modules/@changesets/get-dependents-graph": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.2.tgz", + "integrity": "sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==", + "dev": true, + "dependencies": { + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "picocolors": "^1.1.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/get-release-plan": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.5.tgz", + "integrity": "sha512-E6wW7JoSMcctdVakut0UB76FrrN3KIeJSXvB+DHMFo99CnC3ZVnNYDCVNClMlqAhYGmLmAj77QfApaI3ca4Fkw==", + "dev": true, + "dependencies": { + "@changesets/assemble-release-plan": "^6.0.5", + "@changesets/config": "^3.0.4", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/get-version-range-type": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", + "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", + "dev": true + }, + "node_modules/@changesets/git": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.2.tgz", + "integrity": "sha512-r1/Kju9Y8OxRRdvna+nxpQIsMsRQn9dhhAZt94FLDeu0Hij2hnOozW8iqnHBgvu+KdnJppCveQwK4odwfw/aWQ==", + "dev": true, + "dependencies": { + "@changesets/errors": "^0.2.0", + "@manypkg/get-packages": "^1.1.3", + "is-subdir": "^1.1.1", + "micromatch": "^4.0.8", + "spawndamnit": "^3.0.1" + } + }, + "node_modules/@changesets/logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", + "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", + "dev": true, + "dependencies": { + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/parse": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz", + "integrity": "sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==", + "dev": true, + "dependencies": { + "@changesets/types": "^6.0.0", + "js-yaml": "^3.13.1" + } + }, + "node_modules/@changesets/parse/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@changesets/parse/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@changesets/parse/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/@changesets/pre": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.1.tgz", + "integrity": "sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==", + "dev": true, + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1" + } + }, + "node_modules/@changesets/read": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.2.tgz", + "integrity": "sha512-wjfQpJvryY3zD61p8jR87mJdyx2FIhEcdXhKUqkja87toMrP/3jtg/Yg29upN+N4Ckf525/uvV7a4tzBlpk6gg==", + "dev": true, + "dependencies": { + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", + "@changesets/parse": "^0.4.0", + "@changesets/types": "^6.0.0", + "fs-extra": "^7.0.1", + "p-filter": "^2.1.0", + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.1.tgz", + "integrity": "sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==", + "dev": true, + "dependencies": { + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/types": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz", + "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==", + "dev": true + }, + "node_modules/@changesets/write": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.3.2.tgz", + "integrity": "sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==", + "dev": true, + "dependencies": { + "@changesets/types": "^6.0.0", + "fs-extra": "^7.0.1", + "human-id": "^1.0.2", + "prettier": "^2.7.1" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.24.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", @@ -3798,6 +4099,153 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@manypkg/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "@types/node": "^12.7.1", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" + } + }, + "node_modules/@manypkg/find-root/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true + }, + "node_modules/@manypkg/find-root/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@manypkg/find-root/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/get-packages": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", + "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "@changesets/types": "^4.0.1", + "@manypkg/find-root": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "^11.0.0", + "read-yaml-file": "^1.1.0" + } + }, + "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", + "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", + "dev": true + }, + "node_modules/@manypkg/get-packages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/get-packages/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@manypkg/get-packages/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/@mixmark-io/domino": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", @@ -6443,6 +6891,18 @@ "node": ">=10.0.0" } }, + "node_modules/better-path-resolve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", + "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", + "dev": true, + "dependencies": { + "is-windows": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -6756,6 +7216,12 @@ "node": ">=10" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "node_modules/cheerio": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", @@ -7294,6 +7760,15 @@ "node": ">=0.4.0" } }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -7527,6 +8002,40 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/enquirer/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/enquirer/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -8022,6 +8531,38 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "node_modules/extendable-error": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", + "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -8832,6 +9373,12 @@ "node": ">= 14" } }, + "node_modules/human-id": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", + "integrity": "sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==", + "dev": true + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -8849,6 +9396,21 @@ "ms": "^2.0.0" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -9342,6 +9904,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-subdir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", + "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", + "dev": true, + "dependencies": { + "better-path-resolve": "1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/is-symbol": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.0.tgz", @@ -9426,6 +10000,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -10523,6 +11106,12 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -10925,6 +11514,15 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -11465,6 +12063,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outdent": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", + "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", + "dev": true + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -11495,6 +12120,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/p-timeout": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.3.tgz", @@ -11565,6 +12199,12 @@ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true }, + "node_modules/package-manager-detector": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.7.tgz", + "integrity": "sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==", + "dev": true + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -11860,6 +12500,21 @@ "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" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -12070,6 +12725,67 @@ "node": ">=4" } }, + "node_modules/read-yaml-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", + "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.6.1", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-yaml-file/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/read-yaml-file/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/read-yaml-file/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-yaml-file/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/read-yaml-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -12123,6 +12839,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, "node_modules/regexp.prototype.flags": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", @@ -12605,6 +13327,16 @@ "source-map": "^0.6.0" } }, + "node_modules/spawndamnit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", + "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.5", + "signal-exit": "^4.0.1" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -12991,6 +13723,18 @@ "streamx": "^2.15.0" } }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -13067,6 +13811,18 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", diff --git a/package.json b/package.json index 12b9696d8e..dd776a452e 100644 --- a/package.json +++ b/package.json @@ -152,9 +152,11 @@ "start:webview": "cd webview-ui && npm run start", "build:webview": "cd webview-ui && npm run build", "test:webview": "cd webview-ui && npm run test", - "publish:marketplace": "vsce publish" + "publish:marketplace": "vsce publish", + "prepare": "husky" }, "devDependencies": { + "@changesets/cli": "^2.27.1", "@types/diff": "^5.2.1", "@types/jest": "^29.5.14", "@types/mocha": "^10.0.7", @@ -165,6 +167,7 @@ "@vscode/test-electron": "^2.4.0", "esbuild": "^0.24.0", "eslint": "^8.57.0", + "husky": "^9.1.7", "jest": "^29.7.0", "npm-run-all": "^4.1.5", "ts-jest": "^29.2.5", From 0d00bc18a001c2da1441d2b9c769d7f8a39fb092 Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 13:53:45 -0800 Subject: [PATCH 03/29] Adding changeset config --- .changeset/README.md | 8 ++++++++ .changeset/config.json | 11 +++++++++++ package-lock.json | 2 +- package.json | 2 +- 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000000..e5b6d8d6a6 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000000..c8fca743d8 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.4/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/package-lock.json b/package-lock.json index 891174c0d4..ab56352157 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "web-tree-sitter": "^0.22.6" }, "devDependencies": { - "@changesets/cli": "^2.27.1", + "@changesets/cli": "^2.27.10", "@types/diff": "^5.2.1", "@types/jest": "^29.5.14", "@types/mocha": "^10.0.7", diff --git a/package.json b/package.json index dd776a452e..23659102e9 100644 --- a/package.json +++ b/package.json @@ -156,7 +156,7 @@ "prepare": "husky" }, "devDependencies": { - "@changesets/cli": "^2.27.1", + "@changesets/cli": "^2.27.10", "@types/diff": "^5.2.1", "@types/jest": "^29.5.14", "@types/mocha": "^10.0.7", From e77e39b4b5cf65626dcc0a8541aa9812162a5f1f Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 13:55:42 -0800 Subject: [PATCH 04/29] Adding basic npmrc file to avoid code artifact issues --- .gitignore | 4 ++-- .npmrc | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 .npmrc diff --git a/.gitignore b/.gitignore index 288eb8ece6..72a772d867 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,8 @@ node_modules .DS_Store -.npmrc - +# Builds roo-cline-*.vsix +# Local prompts prompts \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..5660f81af2 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.npmjs.org/ \ No newline at end of file From e9d83dbded2feffbd85ab19fe983f09e3084863a Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 13:58:15 -0800 Subject: [PATCH 05/29] Updating readme and ellipsis yaml --- README.md | 31 ++++++++++++++++++++++++------- ellipsis.yaml | 2 +- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 99eb5614ba..d4e32925da 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,24 @@ Here's an example of Roo-Cline autonomously creating a snake game with "Always a https://github.com/user-attachments/assets/c2bb31dc-e9b2-4d73-885d-17f1471a4987 +### Publishing +We use [changesets](https://github.com/changesets/changesets) for versioning and publishing this package. To make changes: +1. Create a PR with your changes +2. Create a new changeset by running `npm run changeset` + - Select the appropriate kind of change - `patch` for bug fixes, `minor` for new features, or `major` for breaking changes + - Write a clear description of your changes that will be included in the changelog +3. Get the PR approved and pass all checks +4. Merge it + +Once your merge is successful: +- The release workflow will automatically create a new "Changeset version bump" PR +- This PR will: + - Update the version based on your changeset + - Update the CHANGELOG.md file + - Create a git tag +- The PR will be automatically approved and merged +- A new version and git release will be published --- # Cline (prev. Claude Dev) – \#1 on OpenRouter @@ -45,7 +62,7 @@ https://github.com/user-attachments/assets/c2bb31dc-e9b2-4d73-885d-17f1471a4987 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. 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. 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. @@ -53,10 +70,10 @@ Thanks to [Claude 3.5 Sonnet's agentic coding capabilities](https://www-cdn.ant - Create and edit files + monitor linter/compiler errors along the way, letting him proactively fix issues like missing imports and syntax errors on his own. - Execute commands directly in your terminal and monitor their output as he works, letting him e.g., react to dev server issues after editing a file. - For web development tasks, Cline can launch the site in a headless browser, click, type, scroll, and capture screenshots + console logs, allowing him to fix runtime errors and visual bugs. -4. When a task is completed, Cline will present the result to you with a terminal command like `open -a "Google Chrome" index.html`, which you run with a click of a button. +4. When a task is completed, Cline will present the result to you with a terminal command like `open -a "Google Chrome" index.html`, which you run with a click of a button. > [!TIP] -> Use the `CMD/CTRL + Shift + P` shortcut to open the command palette and type "Cline: Open In New Tab" to open the extension as a tab in your editor. This lets you use Cline side-by-side with your file explorer, and see how he changes your workspace more clearly. +> Use the `CMD/CTRL + Shift + P` shortcut to open the command palette and type "Cline: Open In New Tab" to open the extension as a tab in your editor. This lets you use Cline side-by-side with your file explorer, and see how he changes your workspace more clearly. --- @@ -112,10 +129,10 @@ Try asking Cline to "test the app", and watch as he runs a command like `npm run ### 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 -- **`@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) -- **`@folder`:** Adds folder's files all at once to speed up your workflow even more +- **`@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 +- **`@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 ## Contributing diff --git a/ellipsis.yaml b/ellipsis.yaml index e72886cf32..1044b94fdc 100644 --- a/ellipsis.yaml +++ b/ellipsis.yaml @@ -7,7 +7,7 @@ pr_review: # If quiet mode is enabled, Ellipsis will only leave reviews when it has comments, so “Looks good to me” reviews # will be skipped. This can reduce clutter. - quiet: false + quiet: true # You can disable automatic code review using auto_review_enabled. This will override any global settings you # have configured via the web UI. From 51e034c399a9e8b91036bf3e96134314e4096642 Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 14:22:30 -0800 Subject: [PATCH 06/29] Adding openai generated releases working along changesets --- .../scripts/overwrite_changeset_changelog.py | 30 +++ .github/scripts/parse_changeset_changelog.py | 38 ++++ .github/workflows/changeset-ai-releases.yml | 191 ++++++++++++++++++ .github/workflows/code-qa.yml | 2 +- .github/workflows/marketplace-publish.yml | 1 + 5 files changed, 261 insertions(+), 1 deletion(-) create mode 100755 .github/scripts/overwrite_changeset_changelog.py create mode 100755 .github/scripts/parse_changeset_changelog.py create mode 100644 .github/workflows/changeset-ai-releases.yml diff --git a/.github/scripts/overwrite_changeset_changelog.py b/.github/scripts/overwrite_changeset_changelog.py new file mode 100755 index 0000000000..507b2982e8 --- /dev/null +++ b/.github/scripts/overwrite_changeset_changelog.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +import os + +GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT") +CHANGELOG_PATH = os.environ.get("CHANGELOG_PATH", "CHANGELOG.md") +VERSION = os.environ['VERSION'] +PREV_VERSION = os.environ.get("PREV_VERSION", "") +NEW_CONTENT = os.environ['NEW_CONTENT'] + +def overwrite_changelog_section(content: str): + # Find the section for the specified version + version_pattern = f"## {VERSION}\n" + print(f"latest version: {VERSION}") + notes_start_index = content.find(version_pattern) + len(version_pattern) + print(f"prev_version: {PREV_VERSION}") + prev_version_pattern = f"## {PREV_VERSION}\n" + notes_end_index = content.find(prev_version_pattern, notes_start_index) if PREV_VERSION and prev_version_pattern in content else len(content) + return content[:notes_start_index] + f"{NEW_CONTENT}\n" + content[notes_end_index:] + +with open(CHANGELOG_PATH, 'r') as f: + content = f.read() + +new_changelog = overwrite_changelog_section(content) + +print(new_changelog) + +# Write back to CHANGELOG.md +with open(CHANGELOG_PATH, 'w') as f: + f.write(new_changelog) diff --git a/.github/scripts/parse_changeset_changelog.py b/.github/scripts/parse_changeset_changelog.py new file mode 100755 index 0000000000..a5564ab0f6 --- /dev/null +++ b/.github/scripts/parse_changeset_changelog.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 + +import sys +import os +import subprocess + +GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT") +CHANGELOG_PATH = os.environ.get("CHANGELOG_PATH", "CHANGELOG.md") +VERSION = os.environ['VERSION'] + +def parse_changelog_section(content: str): + """Parse a specific version section from the changelog content. + + Returns: The formatted content for this version, or None if version not found + """ + # Find the section for the specified version + version_pattern = f"## {VERSION}\n" + print(f"latest version: {VERSION}") + notes_start_index = content.find(version_pattern) + len(version_pattern) + prev_version = subprocess.getoutput("git show origin/main:package.json | grep '\"version\":' | cut -d'\"' -f4") + print(f"prev_version: {prev_version}") + prev_version_pattern = f"## {prev_version}\n" + notes_end_index = content.find(prev_version_pattern, notes_start_index) if prev_version_pattern in content else len(content) + + return content[notes_start_index:notes_end_index] + +with open(CHANGELOG_PATH, 'r') as f: + content = f.read() + +formatted_content = parse_changelog_section(content) +if not formatted_content: + print(f"Version {VERSION} not found in changelog", file=sys.stderr) + sys.exit(1) + +print(formatted_content) + +with open(GITHUB_OUTPUT, "a") as gha_output: + gha_output.write(f"release-notes< + github.event_name == 'pull_request' && + github.event.pull_request.merged == true && + github.event.pull_request.base.ref == 'main' && + github.actor != 'R00-B0T' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Git Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ env.GIT_REF }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + + - name: Install Dependencies + run: npm install + + - name: Check for changesets + id: check-changesets + run: | + NEW_CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') + echo "Changesets diff with previous version: $NEW_CHANGESETS" + echo "new_changesets=$NEW_CHANGESETS" >> $GITHUB_OUTPUT + + - name: Changeset Pull Request + if: steps.check-changesets.outputs.new_changesets != '0' + id: changesets + uses: changesets/action@v1 + with: + commit: "changeset version bump" + title: "Changeset version bump" + version: npm run version-packages # This performs the changeset version bump + env: + GITHUB_TOKEN: ${{ secrets.ROO_GITHUB_TOKEN }} + + changeset-pr-approve-merge: + name: Auto approve and merge Bump version PRs + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + if: > + github.event_name == 'pull_request' && + github.event.pull_request.base.ref == 'main' && + github.actor == 'R00-B0T' && + contains(github.event.pull_request.title, 'Changeset version bump') + + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + with: + token: ${{ secrets.ROO_GITHUB_TOKEN }} + fetch-depth: 0 + ref: ${{ env.GIT_REF }} + + - name: Get version + id: get_version + run: | + VERSION=$(git show HEAD:package.json | jq -r '.version') + echo "version=$VERSION" >> $GITHUB_OUTPUT + PREV_VERSION=$(git show origin/main:package.json | jq -r '.version') + echo "prev_version=$PREV_VERSION" >> $GITHUB_OUTPUT + + echo "version=$VERSION" + echo "prev_version=$PREV_VERSION" + + # Github outputs: 'RELEASE_NOTES' and 'OPENAI_PROMPT' + - name: AI Release Notes + if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} + uses: RooVetGit/Roo-GHA/.github/actions/ai-release-notes@main + id: ai_release_notes + with: + GHA_PAT: ${{ secrets.ROO_GITHUB_TOKEN }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + model_name: gpt-4o-mini + repo_path: ${{ env.REPO_PATH }} + git_ref: ${{ env.GIT_REF }} + + - name: Update Changeset Changelog + if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} + env: + VERSION: ${{ steps.get_version.outputs.version }} + PREV_VERSION: ${{ steps.get_version.outputs.prev_version }} + NEW_CONTENT: ${{ steps.ai_release_notes.outputs.RELEASE_NOTES }} + run: python .github/scripts/overwrite_changeset_changelog.py + + - name: Push Changelog updates + if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} + run: | + git config user.name "R00-B0T" + git config user.email github-actions@github.com + git status + + echo "Updating changelog.md..." + git add CHANGELOG.md + git commit -m "Updating changeset changelog" + + echo "--------------------------------------------------------------------------------" + echo "Pushing to remote..." + echo "--------------------------------------------------------------------------------" + git push + + - name: Add openai-edited label + if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels: ['openai-edited'] + }); + + - name: Auto approve PR + if: contains(github.event.pull_request.labels.*.name, 'openai-edited') + uses: hmarr/auto-approve-action@v4 + with: + review-message: "I'm approving since it's a bump version PR" + + - name: Enable automerge on PR + if: contains(github.event.pull_request.labels.*.name, 'openai-edited') + run: gh pr merge --squash --auto ${{ github.event.pull_request.number }} + env: + GH_TOKEN: ${{ secrets.ROO_GITHUB_TOKEN }} + + github-release: + runs-on: ubuntu-latest + if: > + github.event_name == 'pull_request' && + github.event.pull_request.merged == true && + github.event.pull_request.base.ref == 'main' && + github.actor == 'R00-B0T' && + contains(github.event.pull_request.title, 'Changeset version bump') + permissions: + contents: write + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Get version + id: get_version + run: | + VERSION=$(git show HEAD:package.json | jq -r '.version') + echo "version=$VERSION" >> $GITHUB_OUTPUT + + # Outputs: 'release-notes' + - name: Parse CHANGELOG.md + id: changelog + env: + CHANGELOG_PATH: CHANGELOG.md + VERSION: ${{ steps.get_version.outputs.version }} + run: python .github/scripts/parse_changeset_changelog.py + + - name: Create or Update Release + uses: softprops/action-gh-release@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: v${{ steps.get_version.outputs.version }} + name: Release v${{ steps.get_version.outputs.version }} + draft: false + prerelease: false + append_body: false + make_latest: true + body: ${{ steps.changelog.outputs.release-notes }} diff --git a/.github/workflows/code-qa.yml b/.github/workflows/code-qa.yml index 44a70106a2..0a5f3c1d24 100644 --- a/.github/workflows/code-qa.yml +++ b/.github/workflows/code-qa.yml @@ -8,7 +8,7 @@ on: branches: [main] jobs: - code-qa: + compile: runs-on: ubuntu-latest steps: - name: Checkout code diff --git a/.github/workflows/marketplace-publish.yml b/.github/workflows/marketplace-publish.yml index fdc35cc801..5f99b44ca6 100644 --- a/.github/workflows/marketplace-publish.yml +++ b/.github/workflows/marketplace-publish.yml @@ -7,6 +7,7 @@ on: jobs: publish-extension: runs-on: ubuntu-latest + if: ${{ github.actor == 'R00-B0T'}} steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 From 3ec7bbc5d3d9796172cd7c4d82536fd5b135d05b Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 14:27:28 -0800 Subject: [PATCH 07/29] Updating husky hook and adding lint-staged --- .husky/pre-commit | 3 +- .husky/pre-push | 2 +- package-lock.json | 581 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 6 + 4 files changed, 590 insertions(+), 2 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index a040d1c301..2f3977a2da 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -5,4 +5,5 @@ if [ "$branch" = "main" ]; then exit 1 fi -# TO DO: npx lint-staged +npx lint-staged +npm run compile diff --git a/.husky/pre-push b/.husky/pre-push index fc1f203ade..ab7d11b507 100644 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -5,7 +5,7 @@ if [ "$branch" = "main" ]; then exit 1 fi -# TO DO: npx tsc-silent -p tsconfig.json --suppressConfig tsc-silent.config.js +npm run compile # Check for new changesets NEW_CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') diff --git a/package-lock.json b/package-lock.json index ab56352157..8decaf171c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,6 +55,7 @@ "eslint": "^8.57.0", "husky": "^9.1.7", "jest": "^29.7.0", + "lint-staged": "^15.2.11", "npm-run-all": "^4.1.5", "ts-jest": "^29.2.5", "typescript": "^5.4.5" @@ -7347,6 +7348,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -7466,6 +7506,12 @@ "color-support": "bin.js" } }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -8047,6 +8093,18 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -8472,6 +8530,12 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -9019,6 +9083,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -11036,12 +11112,275 @@ "immediate": "~3.0.5" } }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, "node_modules/lines-and-columns": { "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 }, + "node_modules/lint-staged": { + "version": "15.2.11", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.11.tgz", + "integrity": "sha512-Ev6ivCTYRTGs9ychvpVw35m/bcNDuBN+mnTeObCL5h+boS5WzBEC6LHI4I9F/++sZm1m+J2LEiy0gxL/R9TBqQ==", + "dev": true, + "dependencies": { + "chalk": "~5.3.0", + "commander": "~12.1.0", + "debug": "~4.4.0", + "execa": "~8.0.1", + "lilconfig": "~3.1.3", + "listr2": "~8.2.5", + "micromatch": "~4.0.8", + "pidtree": "~0.6.0", + "string-argv": "~0.3.2", + "yaml": "~2.6.1" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/lint-staged/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -11128,6 +11467,169 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/lop": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.2.tgz", @@ -11286,6 +11788,18 @@ "node": ">=6" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "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", @@ -12958,6 +13472,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -13273,6 +13793,46 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -13436,6 +13996,15 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -14719,6 +15288,18 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index 23659102e9..b7e09dd7a2 100644 --- a/package.json +++ b/package.json @@ -169,6 +169,7 @@ "eslint": "^8.57.0", "husky": "^9.1.7", "jest": "^29.7.0", + "lint-staged": "^15.2.11", "npm-run-all": "^4.1.5", "ts-jest": "^29.2.5", "typescript": "^5.4.5" @@ -206,5 +207,10 @@ "tree-sitter-wasms": "^0.1.11", "turndown": "^7.2.0", "web-tree-sitter": "^0.22.6" + }, + "lint-staged": { + "src/**/*.{ts,tsx}": [ + "npx eslint -c .eslintrc.json" + ] } } From a63a739a90c0658758f024738f3564a7a5ca3367 Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 14:30:16 -0800 Subject: [PATCH 08/29] Adding PR template --- .github/pull_request_template.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000000..a689eb9ab3 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,28 @@ + +## Description + +## Type of change + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +## How Has This Been Tested? + + +## Checklist: + +- [ ] My code follows the patterns of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation + +## Additional context + + +## Related Issues + + +## Reviewers + \ No newline at end of file From eb1c18cc6597042839e432fb0799be407e0436ba Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 14:33:12 -0800 Subject: [PATCH 09/29] Ordering package.json in alphabetic order --- package.json | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index b7e09dd7a2..41d30ee944 100644 --- a/package.json +++ b/package.json @@ -135,25 +135,29 @@ } }, "scripts": { - "vscode:prepublish": "npm run package", - "vsix": "vsce package", + "build": "npm run build:webview && npm run vsix", + "build:webview": "cd webview-ui && npm run build", + "changeset": "changeset", + "check-types": "tsc --noEmit", "compile": "npm run check-types && npm run lint && node esbuild.js", + "compile-tests": "tsc -p . --outDir out", + "install:all": "npm install && cd webview-ui && npm install", + "lint": "eslint src --ext ts", + "package": "npm run build:webview && npm run check-types && npm run lint && node esbuild.js --production", + "pretest": "npm run compile-tests && npm run compile && npm run lint", + "start:webview": "cd webview-ui && npm run start", + "test": "vscode-test", + "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", + "version-packages": "changeset version && npm install --package-lock-only", + "vscode:prepublish": "npm run package", + "vsix": "npx vsce package --out bin", "watch": "npm-run-all -p watch:*", "watch:esbuild": "node esbuild.js --watch", "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", - "package": "npm run build:webview && npm run check-types && npm run lint && node esbuild.js --production", - "compile-tests": "tsc -p . --outDir out", - "watch-tests": "tsc -p . -w --outDir out", - "pretest": "npm run compile-tests && npm run compile && npm run lint", - "check-types": "tsc --noEmit", - "lint": "eslint src --ext ts", - "test": "jest", - "install:all": "npm install && cd webview-ui && npm install", - "start:webview": "cd webview-ui && npm run start", - "build:webview": "cd webview-ui && npm run build", - "test:webview": "cd webview-ui && npm run test", - "publish:marketplace": "vsce publish", - "prepare": "husky" + "watch-tests": "tsc -p . -w --outDir out" }, "devDependencies": { "@changesets/cli": "^2.27.10", From 2b8e85ab52fed99df2a9afb5aa545eb19e1fc72b Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 15:04:56 -0800 Subject: [PATCH 10/29] Making base prompt visible --- .github/scripts/release-notes-prompt.py | 17 +++++++++++++++++ .github/workflows/changeset-ai-releases.yml | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 .github/scripts/release-notes-prompt.py diff --git a/.github/scripts/release-notes-prompt.py b/.github/scripts/release-notes-prompt.py new file mode 100644 index 0000000000..a1fb4f9626 --- /dev/null +++ b/.github/scripts/release-notes-prompt.py @@ -0,0 +1,17 @@ +import os +from datetime import datetime; +from pytz import timezone + +GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT") + +TODAY = datetime.now(timezone('US/Eastern')).isoformat(sep=' ', timespec='seconds') + +BASE_PROMPT = f"""Based on the following 'PR Information', please generate a concise and informative release notes to be read by developers. +Format the release notes with markdown, and always use this structure: a descriptive and very short title (no more than 8 words) with heading level 2, a paragraph with a summary of changes (no header), and sections for '🚀 New Features & Improvements', '🐛 Bugs Fixed' and '🔧 Other Updates', with heading level 3, skip respectively the sections if not applicable. +Finally include the following markdown comment with the PR merged date: . +Avoid being repetitive and focus on the most important changes and their impact, don't mention version bumps, nor changeset files, nor environment variables, nor syntax updates. +PR Information:""" + +# Write the prompt to GITHUB_OUTPUT +with open(GITHUB_OUTPUT, "a") as outputs_file: + outputs_file.write(f"BASE_PROMPT<> $GITHUB_OUTPUT + echo "Based on the following 'PR Information', please generate concise and informative release notes to be read by developers. + + Format the release notes with markdown, and always use this structure: a descriptive and very short title (no more than 8 words) with heading level 2, a paragraph with a summary of changes (no header), and sections for '🚀 New Features & Improvements', '🐛 Bugs Fixed' and '🔧 Other Updates', with heading level 3, skip respectively the sections if not applicable, + finally include the following markdown comment with the PR merged date: . + + Avoid being repetitive and focus on the most important changes and their impact, don't mention version bumps, nor changeset files, nor environment variables, nor syntax updates. + + PR Information:" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + # Github outputs: 'RELEASE_NOTES' and 'OPENAI_PROMPT' - name: AI Release Notes if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} @@ -96,6 +113,7 @@ jobs: model_name: gpt-4o-mini repo_path: ${{ env.REPO_PATH }} git_ref: ${{ env.GIT_REF }} + custom_prompt: ${{ steps.ai_prompt.outputs.BASE_PROMPT }} - name: Update Changeset Changelog if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} From 9c2634b6621fd23ead1bd36759795feb6d0af4c9 Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 15:23:02 -0800 Subject: [PATCH 11/29] Adding doc comments generated by cline --- .../scripts/overwrite_changeset_changelog.py | 32 +++++++++++++++- .github/scripts/parse_changeset_changelog.py | 30 ++++++++++++++- .github/scripts/release-notes-prompt.py | 6 +++ .github/workflows/changeset-ai-releases.yml | 38 +++++++++++-------- 4 files changed, 87 insertions(+), 19 deletions(-) diff --git a/.github/scripts/overwrite_changeset_changelog.py b/.github/scripts/overwrite_changeset_changelog.py index 507b2982e8..d9ce3001ec 100755 --- a/.github/scripts/overwrite_changeset_changelog.py +++ b/.github/scripts/overwrite_changeset_changelog.py @@ -1,14 +1,44 @@ +""" +This script updates a specific version's release notes section in CHANGELOG.md with new content. + +The script: +1. Takes a version number, changelog path, and new content as input from environment variables +2. Finds the section in the changelog for the specified version +3. Replaces the content between the current version header and the next version header + (or end of file if it's the latest version) with the new content +4. Writes the updated changelog back to the file + +Environment Variables: + CHANGELOG_PATH: Path to the changelog file (defaults to 'CHANGELOG.md') + VERSION: The version number to update notes for + PREV_VERSION: The previous version number (optional) + NEW_CONTENT: The new content to insert for this version +""" + #!/usr/bin/env python3 import os -GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT") CHANGELOG_PATH = os.environ.get("CHANGELOG_PATH", "CHANGELOG.md") VERSION = os.environ['VERSION'] PREV_VERSION = os.environ.get("PREV_VERSION", "") NEW_CONTENT = os.environ['NEW_CONTENT'] def overwrite_changelog_section(content: str): + """Replace a specific version section in the changelog content. + + Args: + content: The full changelog content as a string + + Returns: + The updated changelog content with the new section + + Example: + >>> content = "## 1.2.0\\nOld changes\\n## 1.1.0\\nOld changes" + >>> NEW_CONTENT = "New changes" + >>> overwrite_changelog_section(content) + '## 1.2.0\\nNew changes\\n## 1.1.0\\nOld changes' + """ # Find the section for the specified version version_pattern = f"## {VERSION}\n" print(f"latest version: {VERSION}") diff --git a/.github/scripts/parse_changeset_changelog.py b/.github/scripts/parse_changeset_changelog.py index a5564ab0f6..b21c444dd1 100755 --- a/.github/scripts/parse_changeset_changelog.py +++ b/.github/scripts/parse_changeset_changelog.py @@ -1,3 +1,19 @@ +""" +This script extracts the release notes section for a specific version from CHANGELOG.md. + +The script: +1. Takes a version number and changelog path as input from environment variables +2. Finds the section in the changelog for the specified version +3. Extracts the content between the current version header and the next version header + (or end of file if it's the latest version) +4. Outputs the extracted release notes to GITHUB_OUTPUT for use in creating GitHub releases + +Environment Variables: + GITHUB_OUTPUT: Path to GitHub Actions output file + CHANGELOG_PATH: Path to the changelog file (defaults to 'CHANGELOG.md') + VERSION: The version number to extract notes for +""" + #!/usr/bin/env python3 import sys @@ -10,8 +26,17 @@ VERSION = os.environ['VERSION'] def parse_changelog_section(content: str): """Parse a specific version section from the changelog content. + + Args: + content: The full changelog content as a string - Returns: The formatted content for this version, or None if version not found + Returns: + The formatted content for this version, or None if version not found + + Example: + >>> content = "## 1.2.0\\nChanges\\n## 1.1.0\\nOld changes" + >>> parse_changelog_section(content) + 'Changes\\n' """ # Find the section for the specified version version_pattern = f"## {VERSION}\n" @@ -34,5 +59,6 @@ if not formatted_content: print(formatted_content) +# Write the extracted release notes to GITHUB_OUTPUT with open(GITHUB_OUTPUT, "a") as gha_output: - gha_output.write(f"release-notes< github.event_name == 'pull_request' && @@ -36,6 +43,7 @@ jobs: - name: Install Dependencies run: npm install + # Check if there are any new changesets to process - name: Check for changesets id: check-changesets run: | @@ -43,6 +51,7 @@ jobs: echo "Changesets diff with previous version: $NEW_CHANGESETS" echo "new_changesets=$NEW_CHANGESETS" >> $GITHUB_OUTPUT + # Create version bump PR using changesets/action if there are new changesets - name: Changeset Pull Request if: steps.check-changesets.outputs.new_changesets != '0' id: changesets @@ -54,6 +63,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.ROO_GITHUB_TOKEN }} + # Job 2: Process version bump PR created by R00-B0T changeset-pr-approve-merge: name: Auto approve and merge Bump version PRs runs-on: ubuntu-latest @@ -74,6 +84,7 @@ jobs: fetch-depth: 0 ref: ${{ env.GIT_REF }} + # Get current and previous versions for changelog processing - name: Get version id: get_version run: | @@ -85,24 +96,12 @@ jobs: echo "version=$VERSION" echo "prev_version=$PREV_VERSION" + # Generate base prompt for OpenAI, GITHUB_OUTPUT: 'BASE_PROMPT' - name: Release Notes Prompt id: ai_prompt - run: | - # Get today's date in YYYY-MM-DD format - TODAY=$(date +'%Y-%m-%d %H:%M') + run: python .github/scripts/release-notes-prompt.py - echo "BASE_PROMPT<> $GITHUB_OUTPUT - echo "Based on the following 'PR Information', please generate concise and informative release notes to be read by developers. - - Format the release notes with markdown, and always use this structure: a descriptive and very short title (no more than 8 words) with heading level 2, a paragraph with a summary of changes (no header), and sections for '🚀 New Features & Improvements', '🐛 Bugs Fixed' and '🔧 Other Updates', with heading level 3, skip respectively the sections if not applicable, - finally include the following markdown comment with the PR merged date: . - - Avoid being repetitive and focus on the most important changes and their impact, don't mention version bumps, nor changeset files, nor environment variables, nor syntax updates. - - PR Information:" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - # Github outputs: 'RELEASE_NOTES' and 'OPENAI_PROMPT' + # Generate release notes using OpenAI if not already edited, GITHUB_OUTPUT: 'RELEASE_NOTES' and 'OPENAI_PROMPT' - name: AI Release Notes if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} uses: RooVetGit/Roo-GHA/.github/actions/ai-release-notes@main @@ -115,6 +114,7 @@ jobs: git_ref: ${{ env.GIT_REF }} custom_prompt: ${{ steps.ai_prompt.outputs.BASE_PROMPT }} + # Update CHANGELOG.md with AI-generated notes - name: Update Changeset Changelog if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} env: @@ -123,6 +123,7 @@ jobs: NEW_CONTENT: ${{ steps.ai_release_notes.outputs.RELEASE_NOTES }} run: python .github/scripts/overwrite_changeset_changelog.py + # Commit and push changelog updates - name: Push Changelog updates if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} run: | @@ -139,6 +140,7 @@ jobs: echo "--------------------------------------------------------------------------------" git push + # Add label to indicate OpenAI has processed this PR - name: Add openai-edited label if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} uses: actions/github-script@v7 @@ -152,18 +154,21 @@ jobs: labels: ['openai-edited'] }); + # Auto-approve PR once OpenAI has processed it - name: Auto approve PR if: contains(github.event.pull_request.labels.*.name, 'openai-edited') uses: hmarr/auto-approve-action@v4 with: review-message: "I'm approving since it's a bump version PR" + # Enable auto-merge for the PR - name: Enable automerge on PR if: contains(github.event.pull_request.labels.*.name, 'openai-edited') run: gh pr merge --squash --auto ${{ github.event.pull_request.number }} env: GH_TOKEN: ${{ secrets.ROO_GITHUB_TOKEN }} + # Job 3: Create GitHub release after version bump PR is merged github-release: runs-on: ubuntu-latest if: > @@ -187,7 +192,7 @@ jobs: VERSION=$(git show HEAD:package.json | jq -r '.version') echo "version=$VERSION" >> $GITHUB_OUTPUT - # Outputs: 'release-notes' + # Extract release notes from CHANGELOG.md, GITHUB_OUTPUT: 'release-notes' - name: Parse CHANGELOG.md id: changelog env: @@ -195,6 +200,7 @@ jobs: VERSION: ${{ steps.get_version.outputs.version }} run: python .github/scripts/parse_changeset_changelog.py + # Create GitHub release with extracted notes - name: Create or Update Release uses: softprops/action-gh-release@v2 env: From c0941d4b99c44d7730f2ce10c435af10926a29b9 Mon Sep 17 00:00:00 2001 From: a8trejo Date: Tue, 10 Dec 2024 16:32:46 -0800 Subject: [PATCH 12/29] Minor updates --- .github/scripts/release-notes-prompt.py | 8 ++++---- .github/workflows/changeset-ai-releases.yml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/scripts/release-notes-prompt.py b/.github/scripts/release-notes-prompt.py index 5b5c0e9fd7..3471065742 100644 --- a/.github/scripts/release-notes-prompt.py +++ b/.github/scripts/release-notes-prompt.py @@ -12,12 +12,12 @@ GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT") TODAY = datetime.now(timezone('US/Eastern')).isoformat(sep=' ', timespec='seconds') -BASE_PROMPT = f"""Based on the following 'PR Information', please generate a concise and informative release notes to be read by developers. -Format the release notes with markdown, and always use this structure: a descriptive and very short title (no more than 8 words) with heading level 2, a paragraph with a summary of changes (no header), and sections for '🚀 New Features & Improvements', '🐛 Bugs Fixed' and '🔧 Other Updates', with heading level 3, skip respectively the sections if not applicable. +BASE_PROMPT = f"""Based on the following 'PR Information', please generate concise and informative release notes to be read by developers. +Format the release notes with markdown, and always use this structure: a descriptive and very short title (no more than 8 words) with heading level 2, a paragraph with a summary of changes (no header), and if applicable, sections for '🚀 New Features & Improvements', '🐛 Bugs Fixed' and '🔧 Other Updates', with heading level 3, skip respectively the sections if not applicable. Finally include the following markdown comment with the PR merged date: . -Avoid being repetitive and focus on the most important changes and their impact, don't mention version bumps, nor changeset files, nor environment variables, nor syntax updates. +Avoid being repetitive and focus on the most important changes and their impact, discard any mention of version bumps/updates, changeset files, environment variables or syntax updates. PR Information:""" # Write the prompt to GITHUB_OUTPUT with open(GITHUB_OUTPUT, "a") as outputs_file: - outputs_file.write(f"BASE_PROMPT< Date: Tue, 10 Dec 2024 16:53:48 -0800 Subject: [PATCH 13/29] Updated readme file --- README.md | 69 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index d4e32925da..e9b0071b1c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,39 @@ Here's an example of Roo-Cline autonomously creating a snake game with "Always a https://github.com/user-attachments/assets/c2bb31dc-e9b2-4d73-885d-17f1471a4987 -### Publishing +## Contributing +To contribute to the project, start by exploring [open issues](https://github.com/RooVetGit/Roo-Cline/issues) or checking our [feature request board](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop). We'd also love to have you join our [Discord](https://discord.gg/cline) to share ideas and connect with other contributors. + +
+Local Setup + +1. Install dependencies: + ```bash + npm run install:all + ``` + +2. Build the VSIX file: + ```bash + npm run build + ``` +3. The new VSIX file will be created in the `bin/` directory +4. Install the extension from the VSIX file as described below: + + - **Option 1:** Drag and drop the `.vsix` file into your VSCode-compatible editor's Extensions panel (Cmd/Ctrl+Shift+X). + + - **Option 2:** Install the plugin using the CLI, make sure you have your VSCode-compatible CLI installed and in your `PATH` variable. Cursor example: `export PATH="$PATH:/Applications/Cursor.app/Contents/MacOS"` + + ```bash + # Ex: cursor --install-extension bin/roo-cline-2.0.1.vsix + # Ex: code --install-extension bin/roo-cline-2.0.1.vsix + ``` + +5. Launch by pressing `F5` (or `Run`->`Start Debugging`) to open a new VSCode window with the extension loaded. (You may need to install the [esbuild problem matchers extension](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers) if you run into issues building the project.) + +
+ +
+Publishing We use [changesets](https://github.com/changesets/changesets) for versioning and publishing this package. To make changes: 1. Create a PR with your changes @@ -29,10 +61,16 @@ Once your merge is successful: - The release workflow will automatically create a new "Changeset version bump" PR - This PR will: - Update the version based on your changeset - - Update the CHANGELOG.md file + - Update the `CHANGELOG.md` file - Create a git tag - The PR will be automatically approved and merged - A new version and git release will be published + +
+ +## Stay Updated! +Subscribe to our [Github releases](https://github.com/RooVetGit/Roo-Cline/releases) to keep up with the latest updates! You can also view our [CHANGELOG.md](Roo-Cline/CHANGELOG.md) for more details. + --- # Cline (prev. Claude Dev) – \#1 on OpenRouter @@ -133,30 +171,3 @@ Try asking Cline to "test the app", and watch as he runs a command like `npm run - **`@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) - **`@folder`:** Adds folder's files all at once to speed up your workflow even more - -## Contributing - -To contribute to the project, start by exploring [open issues](https://github.com/cline/cline/issues) or checking our [feature request board](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop). We'd also love to have you join our [Discord](https://discord.gg/cline) to share ideas and connect with other contributors. If you're interested in joining the team, check out our [careers page](https://cline.bot/join-us)! - -
-Local Development Instructions - -1. Clone the repository _(Requires [git-lfs](https://git-lfs.com/))_: - ```bash - git clone https://github.com/cline/cline.git - ``` -2. Open the project in VSCode: - ```bash - code cline - ``` -3. Install the necessary dependencies for the extension and webview-gui: - ```bash - npm run install:all - ``` -4. Launch by pressing `F5` (or `Run`->`Start Debugging`) to open a new VSCode window with the extension loaded. (You may need to install the [esbuild problem matchers extension](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers) if you run into issues building the project.) - -
- -## License - -[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) From 00b14d6dfcdcc2dbecff193a49442dd7623a3c5f Mon Sep 17 00:00:00 2001 From: lloydchang Date: Tue, 10 Dec 2024 20:48:36 -0800 Subject: [PATCH 14/29] feat: add dependabot.yml (#58) --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..5f0889ce91 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "npm" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" From 7c870733a10497bf14f0789b362578446e99f3b3 Mon Sep 17 00:00:00 2001 From: lloydchang Date: Wed, 11 Dec 2024 02:18:04 -0800 Subject: [PATCH 15/29] Fix code scanning alert no. 1: Incomplete URL substring sanitization Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- src/api/providers/openai.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index 57cab17e68..3912fa485d 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -17,7 +17,8 @@ export class OpenAiHandler implements ApiHandler { constructor(options: ApiHandlerOptions) { this.options = options // Azure API shape slightly differs from the core API shape: https://github.com/openai/openai-node?tab=readme-ov-file#microsoft-azure-openai - if (this.options.openAiBaseUrl?.toLowerCase().includes("azure.com")) { + const urlHost = new URL(this.options.openAiBaseUrl).host; + if (urlHost === "azure.com" || urlHost.endsWith(".azure.com")) { this.client = new AzureOpenAI({ baseURL: this.options.openAiBaseUrl, apiKey: this.options.openAiApiKey, From b2f0aaec8a85d9ed7ef3274194371163b9e5b778 Mon Sep 17 00:00:00 2001 From: lloydchang Date: Wed, 11 Dec 2024 02:18:49 -0800 Subject: [PATCH 16/29] Fix code scanning alert no. 2: Prototype-polluting function Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- webview-ui/src/components/history/HistoryView.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/webview-ui/src/components/history/HistoryView.tsx b/webview-ui/src/components/history/HistoryView.tsx index 76a0e190fa..bec38af56f 100644 --- a/webview-ui/src/components/history/HistoryView.tsx +++ b/webview-ui/src/components/history/HistoryView.tsx @@ -462,10 +462,13 @@ export const highlight = ( let i: number for (i = 0; i < pathValue.length - 1; i++) { + if (pathValue[i] === "__proto__" || pathValue[i] === "constructor") return obj = obj[pathValue[i]] as Record } - obj[pathValue[i]] = value + if (pathValue[i] !== "__proto__" && pathValue[i] !== "constructor") { + obj[pathValue[i]] = value + } } // Function to merge overlapping regions From 9abe3f69165ca5d3dc5749f0f2cf0b1fa402a23c Mon Sep 17 00:00:00 2001 From: lloydchang Date: Wed, 11 Dec 2024 02:37:26 -0800 Subject: [PATCH 17/29] fix(openai.ts): default to an empty string if undefined Change: const urlHost = new URL(this.options.openAiBaseUrl).host; To: const urlHost = new URL(this.options.openAiBaseUrl ?? "").host; because the nullish coalescing operator (??) to default to an empty string if this.options.openAiBaseUrl is undefined. It ensures that the URL constructor always receives a valid string. --- src/api/providers/openai.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index 3912fa485d..f1c576bd26 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -17,7 +17,7 @@ export class OpenAiHandler implements ApiHandler { constructor(options: ApiHandlerOptions) { this.options = options // Azure API shape slightly differs from the core API shape: https://github.com/openai/openai-node?tab=readme-ov-file#microsoft-azure-openai - const urlHost = new URL(this.options.openAiBaseUrl).host; + const urlHost = new URL(this.options.openAiBaseUrl ?? "").host; if (urlHost === "azure.com" || urlHost.endsWith(".azure.com")) { this.client = new AzureOpenAI({ baseURL: this.options.openAiBaseUrl, From 8e36c555cb91a62911d48e445fab90d658bda78f Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Wed, 11 Dec 2024 10:38:25 -0500 Subject: [PATCH 18/29] Delete .github/ISSUE_TEMPLATE/config.yml (#69) --- .github/ISSUE_TEMPLATE/config.yml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index cad57bdc0e..0000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,11 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Feature Request - url: https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop - about: Share and vote on feature requests for Cline - - name: Cline Discord - url: https://discord.gg/cline - about: Join our Discord community for discussions and support - - name: Other Questions? - url: https://x.com/sdrzn - about: Contact the developer on X @sdrzn for other inquiries From f0259aecad14d8ea6617fdb7b4762762cc9d3bde Mon Sep 17 00:00:00 2001 From: lloydchang Date: Wed, 11 Dec 2024 08:08:55 -0800 Subject: [PATCH 19/29] merge cline:main to RooVetGit:main (#63) Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> From 355dc822dd7dec7c5c188edb8112b24bacf25f67 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Wed, 11 Dec 2024 11:20:01 -0500 Subject: [PATCH 20/29] Better error handling when unable to apply diffs (#71) --- CHANGELOG.md | 4 ++++ package-lock.json | 4 ++-- package.json | 2 +- src/core/Cline.ts | 9 ++++++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05177c310d..ea562d63f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Roo Cline Changelog +## [2.1.19] + +- Better error handling for diff editing + ## [2.1.18] - Diff editing bugfix to handle Windows line endings diff --git a/package-lock.json b/package-lock.json index ac4846b3c6..b7d756e0d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "roo-cline", - "version": "2.1.18", + "version": "2.1.19", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "roo-cline", - "version": "2.1.18", + "version": "2.1.19", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", "@anthropic-ai/sdk": "^0.26.0", diff --git a/package.json b/package.json index 9fc47baecc..dc5a92b8e6 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Roo Cline", "description": "A fork of Cline, an autonomous coding agent, with some added experimental configuration and automation features.", "publisher": "RooVeterinaryInc", - "version": "2.1.18", + "version": "2.1.19", "icon": "assets/icons/rocket.png", "galleryBanner": { "color": "#617A91", diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 4e747d9055..d45d1513b7 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1208,12 +1208,12 @@ export class Cline { pushToolResult(await this.sayAndCreateMissingParamError("apply_diff", "diff")) break } - this.consecutiveMistakeCount = 0 const absolutePath = path.resolve(cwd, relPath) const fileExists = await fileExistsAtPath(absolutePath) if (!fileExists) { + this.consecutiveMistakeCount++ await this.say("error", `File does not exist at path: ${absolutePath}`) pushToolResult(`Error: File does not exist at path: ${absolutePath}`) break @@ -1224,11 +1224,14 @@ export class Cline { // Apply the diff to the original content let newContent = this.diffStrategy?.applyDiff(originalContent, diffContent) ?? false if (newContent === false) { - await this.say("error", `Error applying diff to file: ${absolutePath}`) - pushToolResult(`Error applying diff to file: ${absolutePath}`) + this.consecutiveMistakeCount++ + await this.say("error", `Unable to apply diff to file - contents are out of sync: ${absolutePath}`) + pushToolResult(`Error applying diff to file: ${absolutePath} - contents are out of sync. Try re-reading the relevant lines of the file and applying the diff again.`) break } + this.consecutiveMistakeCount = 0 + // Show diff view before asking for approval this.diffViewProvider.editType = "modify" await this.diffViewProvider.open(relPath); From 413f10650f4c5ee74ed522156bf3008c5fabc22c Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Wed, 11 Dec 2024 12:34:53 -0500 Subject: [PATCH 21/29] Stop appending newlines to files when applying diffs --- src/integrations/editor/DiffViewProvider.ts | 21 ++-- .../editor/__tests__/DiffViewProvider.test.ts | 100 ++++++++++++++++++ 2 files changed, 111 insertions(+), 10 deletions(-) create mode 100644 src/integrations/editor/__tests__/DiffViewProvider.test.ts diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts index c4dced015c..797bb90f37 100644 --- a/src/integrations/editor/DiffViewProvider.ts +++ b/src/integrations/editor/DiffViewProvider.ts @@ -124,17 +124,18 @@ export class DiffViewProvider { edit.delete(document.uri, new vscode.Range(this.streamedLines.length, 0, document.lineCount, 0)) await vscode.workspace.applyEdit(edit) } - // Add empty last line if original content had one + // Preserve empty last line if original content had one const hasEmptyLastLine = this.originalContent?.endsWith("\n") - if (hasEmptyLastLine) { - const accumulatedLines = accumulatedContent.split("\n") - if (accumulatedLines[accumulatedLines.length - 1] !== "") { - accumulatedContent += "\n" - } + if (hasEmptyLastLine && !accumulatedContent.endsWith("\n")) { + accumulatedContent += "\n" } - // Clear all decorations at the end (before applying final edit) - this.fadedOverlayController.clear() - this.activeLineController.clear() + // Apply the final content + const finalEdit = new vscode.WorkspaceEdit() + finalEdit.replace(document.uri, new vscode.Range(0, 0, document.lineCount, 0), accumulatedContent) + await vscode.workspace.applyEdit(finalEdit) + // Clear all decorations at the end (after applying final edit) + this.fadedOverlayController.clear() + this.activeLineController.clear() } } @@ -351,4 +352,4 @@ export class DiffViewProvider { this.streamedLines = [] this.preDiagnostics = [] } -} +} \ No newline at end of file diff --git a/src/integrations/editor/__tests__/DiffViewProvider.test.ts b/src/integrations/editor/__tests__/DiffViewProvider.test.ts new file mode 100644 index 0000000000..debc408fed --- /dev/null +++ b/src/integrations/editor/__tests__/DiffViewProvider.test.ts @@ -0,0 +1,100 @@ +import { DiffViewProvider } from '../DiffViewProvider'; +import * as vscode from 'vscode'; + +// Mock vscode +jest.mock('vscode', () => ({ + workspace: { + applyEdit: jest.fn(), + }, + window: { + createTextEditorDecorationType: jest.fn(), + }, + WorkspaceEdit: jest.fn().mockImplementation(() => ({ + replace: jest.fn(), + delete: jest.fn(), + })), + Range: jest.fn(), + Position: jest.fn(), + Selection: jest.fn(), + TextEditorRevealType: { + InCenter: 2, + }, +})); + +// Mock DecorationController +jest.mock('../DecorationController', () => ({ + DecorationController: jest.fn().mockImplementation(() => ({ + setActiveLine: jest.fn(), + updateOverlayAfterLine: jest.fn(), + clear: jest.fn(), + })), +})); + +describe('DiffViewProvider', () => { + let diffViewProvider: DiffViewProvider; + const mockCwd = '/mock/cwd'; + let mockWorkspaceEdit: { replace: jest.Mock; delete: jest.Mock }; + + beforeEach(() => { + jest.clearAllMocks(); + mockWorkspaceEdit = { + replace: jest.fn(), + delete: jest.fn(), + }; + (vscode.WorkspaceEdit as jest.Mock).mockImplementation(() => mockWorkspaceEdit); + + diffViewProvider = new DiffViewProvider(mockCwd); + // Mock the necessary properties and methods + (diffViewProvider as any).relPath = 'test.txt'; + (diffViewProvider as any).activeDiffEditor = { + document: { + uri: { fsPath: `${mockCwd}/test.txt` }, + getText: jest.fn(), + lineCount: 10, + }, + selection: { + active: { line: 0, character: 0 }, + anchor: { line: 0, character: 0 }, + }, + edit: jest.fn().mockResolvedValue(true), + revealRange: jest.fn(), + }; + (diffViewProvider as any).activeLineController = { setActiveLine: jest.fn(), clear: jest.fn() }; + (diffViewProvider as any).fadedOverlayController = { updateOverlayAfterLine: jest.fn(), clear: jest.fn() }; + }); + + describe('update method', () => { + it('should preserve empty last line when original content has one', async () => { + (diffViewProvider as any).originalContent = 'Original content\n'; + await diffViewProvider.update('New content', true); + + expect(mockWorkspaceEdit.replace).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + 'New content\n' + ); + }); + + it('should not add extra newline when accumulated content already ends with one', async () => { + (diffViewProvider as any).originalContent = 'Original content\n'; + await diffViewProvider.update('New content\n', true); + + expect(mockWorkspaceEdit.replace).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + 'New content\n' + ); + }); + + it('should not add newline when original content does not end with one', async () => { + (diffViewProvider as any).originalContent = 'Original content'; + await diffViewProvider.update('New content', true); + + expect(mockWorkspaceEdit.replace).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + 'New content' + ); + }); + }); +}); \ No newline at end of file From 65bbefed555bb0aa15ce274650708ee7de93e6ed Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Wed, 11 Dec 2024 13:35:08 -0500 Subject: [PATCH 22/29] Add Gemini 2.0 --- CHANGELOG.md | 4 ++++ package-lock.json | 4 ++-- package.json | 2 +- src/shared/api.ts | 8 ++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea562d63f4..f74ef92480 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Roo Cline Changelog +## [2.1.20] + +- Add Gemini 2.0 + ## [2.1.19] - Better error handling for diff editing diff --git a/package-lock.json b/package-lock.json index b7d756e0d4..fccff2d2f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "roo-cline", - "version": "2.1.19", + "version": "2.1.20", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "roo-cline", - "version": "2.1.19", + "version": "2.1.20", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", "@anthropic-ai/sdk": "^0.26.0", diff --git a/package.json b/package.json index dc5a92b8e6..4be1009ccd 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Roo Cline", "description": "A fork of Cline, an autonomous coding agent, with some added experimental configuration and automation features.", "publisher": "RooVeterinaryInc", - "version": "2.1.19", + "version": "2.1.20", "icon": "assets/icons/rocket.png", "galleryBanner": { "color": "#617A91", diff --git a/src/shared/api.ts b/src/shared/api.ts index 0ea4622d99..38cd02a723 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -286,6 +286,14 @@ export const geminiModels = { inputPrice: 0, outputPrice: 0, }, + "gemini-2.0-flash-exp": { + maxTokens: 8192, + contextWindow: 2_097_152, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, } as const satisfies Record // OpenAI Native From 0e0c848a9605726eb2fd4057e406200f03b54eca Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Wed, 11 Dec 2024 14:02:54 -0500 Subject: [PATCH 23/29] Fix Gemini 2.0 context window --- src/shared/api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/api.ts b/src/shared/api.ts index 38cd02a723..94d0b1843a 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -288,7 +288,7 @@ export const geminiModels = { }, "gemini-2.0-flash-exp": { maxTokens: 8192, - contextWindow: 2_097_152, + contextWindow: 1_048_576, supportsImages: true, supportsPromptCache: false, inputPrice: 0, From 5eafdbcc57048dc0290686fb4fbe4052d0946d7c Mon Sep 17 00:00:00 2001 From: a8trejo Date: Wed, 11 Dec 2024 12:04:42 -0800 Subject: [PATCH 24/29] release fixes --- .github/scripts/get_prev_version_refs.py | 57 +++++++++++++++++++++ .github/workflows/changeset-ai-releases.yml | 10 +++- .gitignore | 3 +- 3 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 .github/scripts/get_prev_version_refs.py diff --git a/.github/scripts/get_prev_version_refs.py b/.github/scripts/get_prev_version_refs.py new file mode 100644 index 0000000000..5ac6086047 --- /dev/null +++ b/.github/scripts/get_prev_version_refs.py @@ -0,0 +1,57 @@ +import os +import re +import subprocess + +def run_git_command(command): + try: + result = subprocess.getoutput(command) + print(f"Git Command: {command}") + print(f"Git Output: {result}") + return result + except subprocess.CalledProcessError as e: + print(f"Error running command: {e}") + print(f"stderr: {e.stderr}") + return None + +def parse_merge_commit(line): + # Parse merge commit messages like: + # "355dc82 Merge pull request #71 from RooVetGit/better-error-handling" + pattern = r"([a-f0-9]+)\s+Merge pull request #(\d+) from (.+)" + match = re.match(pattern, line) + if match: + sha, pr_number, branch = match.groups() + return { + 'sha': sha, + 'pr_number': pr_number, + 'branch': branch + } + return None + +def get_version_refs(): + # Get the merge commits with full message + command = 'git log --merges --pretty=oneline -n 3' + result = run_git_command(command) + + if result: + commits = result.split('\n') + if len(commits) >= 3: + # Parse HEAD~1 (PR to generate notes for) + head_info = parse_merge_commit(commits[1]) + # Parse HEAD~2 (previous PR to compare against) + base_info = parse_merge_commit(commits[2]) + + if head_info and base_info: + # Set output for GitHub Actions + with open(os.environ['GITHUB_OUTPUT'], 'a') as gha_outputs: + gha_outputs.write(f"head_ref={head_info['sha']}\n") + gha_outputs.write(f"base_ref={base_info['sha']}") + + print(f"Head ref (PR #{head_info['pr_number']}): {head_info['sha']}") + print(f"Base ref (PR #{base_info['pr_number']}): {base_info['sha']}") + return head_info, base_info + + print("Could not find or parse sufficient merge history") + return None, None + +if __name__ == "__main__": + head_info, base_info = get_version_refs() \ No newline at end of file diff --git a/.github/workflows/changeset-ai-releases.yml b/.github/workflows/changeset-ai-releases.yml index e234419cfa..fe48b6cd77 100644 --- a/.github/workflows/changeset-ai-releases.yml +++ b/.github/workflows/changeset-ai-releases.yml @@ -13,7 +13,7 @@ on: env: REPO_PATH: ${{ github.repository }} - GIT_REF: ${{ github.head_ref }} + GIT_REF: ${{ github.event.pull_request.head.sha }} jobs: # Job 1: Create version bump PR when changesets are merged to main @@ -101,6 +101,11 @@ jobs: id: ai_prompt run: python .github/scripts/release-notes-prompt.py + # Get previous version refs, GITHUB_OUTPUT: 'BASE_REF' and 'HEAD_REF' + - name: Get Previous Version Refs + id: version_refs + run: python .github/scripts/get_prev_version_refs.py + # Generate release notes using OpenAI if not already edited, GITHUB_OUTPUT: 'RELEASE_NOTES' and 'OPENAI_PROMPT' - name: AI Release Notes if: ${{ !contains(github.event.pull_request.labels.*.name, 'openai-edited') }} @@ -111,7 +116,8 @@ jobs: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} model_name: gpt-4o-mini repo_path: ${{ env.REPO_PATH }} - git_ref: ${{ env.GIT_REF }} + base_ref: ${{ steps.version_refs.outputs.base_ref }} + head_ref: ${{ steps.version_refs.outputs.head_ref }} custom_prompt: ${{ steps.ai_prompt.outputs.BASE_PROMPT }} # Update CHANGELOG.md with AI-generated notes diff --git a/.gitignore b/.gitignore index 72a772d867..8c9d9cf5db 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ node_modules roo-cline-*.vsix # Local prompts -prompts \ No newline at end of file +prompts +.clinerules From 21f83f64d87124a7bfd6679c6cc1c3090bc2bd58 Mon Sep 17 00:00:00 2001 From: a8trejo Date: Wed, 11 Dec 2024 12:10:55 -0800 Subject: [PATCH 25/29] Minor script fix --- .github/scripts/get_prev_version_refs.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/scripts/get_prev_version_refs.py b/.github/scripts/get_prev_version_refs.py index 5ac6086047..09d7d4cd0b 100644 --- a/.github/scripts/get_prev_version_refs.py +++ b/.github/scripts/get_prev_version_refs.py @@ -3,15 +3,10 @@ import re import subprocess def run_git_command(command): - try: - result = subprocess.getoutput(command) - print(f"Git Command: {command}") - print(f"Git Output: {result}") - return result - except subprocess.CalledProcessError as e: - print(f"Error running command: {e}") - print(f"stderr: {e.stderr}") - return None + result = subprocess.getoutput(command) + print(f"Git Command: {command}") + print(f"Git Output: {result}") + return result def parse_merge_commit(line): # Parse merge commit messages like: From d7e35d08340fd56db200e2eb95f4c9d7624bfe4c Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Wed, 11 Dec 2024 15:51:06 -0500 Subject: [PATCH 26/29] Larger text area with support for dragging in images --- .../src/components/chat/ChatTextArea.tsx | 69 +++++++++++++++++-- webview-ui/src/components/chat/ChatView.tsx | 2 +- 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index f465942f36..f48380b95f 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -13,6 +13,8 @@ import { MAX_IMAGES_PER_MESSAGE } from "./ChatView" import ContextMenu from "./ContextMenu" import Thumbnails from "../common/Thumbnails" +declare const vscode: any; + interface ChatTextAreaProps { inputValue: string setInputValue: (value: string) => void @@ -427,7 +429,62 @@ const ChatTextArea = forwardRef( opacity: textAreaDisabled ? 0.5 : 1, position: "relative", display: "flex", - }}> + }} + onDrop={async (e) => { + console.log("onDrop called") + e.preventDefault() + const files = Array.from(e.dataTransfer.files) + const text = e.dataTransfer.getData("text") + if (text) { + const newValue = + inputValue.slice(0, cursorPosition) + text + inputValue.slice(cursorPosition) + setInputValue(newValue) + const newCursorPosition = cursorPosition + text.length + setCursorPosition(newCursorPosition) + setIntendedCursorPosition(newCursorPosition) + return + } + const acceptedTypes = ["png", "jpeg", "webp"] + const imageFiles = files.filter((file) => { + const [type, subtype] = file.type.split("/") + return type === "image" && acceptedTypes.includes(subtype) + }) + if (!shouldDisableImages && imageFiles.length > 0) { + const imagePromises = imageFiles.map((file) => { + return new Promise((resolve) => { + const reader = new FileReader() + reader.onloadend = () => { + if (reader.error) { + console.error("Error reading file:", reader.error) + resolve(null) + } else { + const result = reader.result + console.log("File read successfully", result) + resolve(typeof result === "string" ? result : null) + } + } + reader.readAsDataURL(file) + }) + }) + const imageDataArray = await Promise.all(imagePromises) + const dataUrls = imageDataArray.filter((dataUrl): dataUrl is string => dataUrl !== null) + if (dataUrls.length > 0) { + setSelectedImages((prevImages) => [...prevImages, ...dataUrls].slice(0, MAX_IMAGES_PER_MESSAGE)) + if (typeof vscode !== 'undefined') { + vscode.postMessage({ + type: 'draggedImages', + dataUrls: dataUrls + }) + } + } else { + console.warn("No valid images were processed") + } + } + }} + onDragOver={(e) => { + e.preventDefault() + }} + > {showContextMenu && (
( onHeightChange?.(height) }} placeholder={placeholderText} - maxRows={10} + minRows={2} + maxRows={20} autoFocus={true} style={{ width: "100%", @@ -523,7 +581,6 @@ const ChatTextArea = forwardRef( resize: "none", overflowX: "hidden", overflowY: "scroll", - scrollbarWidth: "none", // Since we have maxRows, when text is long enough it starts to overflow the bottom padding, appearing behind the thumbnails. To fix this, we use a transparent border to push the text up instead. (https://stackoverflow.com/questions/42631947/maintaining-a-padding-inside-of-text-area/52538410#52538410) // borderTop: "9px solid transparent", borderLeft: 0, @@ -560,11 +617,11 @@ const ChatTextArea = forwardRef(
diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 8dedae9e54..7a89951895 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -689,7 +689,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie useEvent("wheel", handleWheel, window, { passive: true }) // passive improves scrolling performance const placeholderText = useMemo(() => { - const text = task ? "Type a message (@ to add context)..." : "Type your task here (@ to add context)..." + const text = task ? "Type a message...\n(@ to add context, hold shift to drag in images)" : "Type your task here...\n(@ to add context, hold shift to drag in images)" return text }, [task]) From 8dbd01937d417af579101fe8bb6fcaded813dc6a Mon Sep 17 00:00:00 2001 From: ColemanRoo <117104599+ColemanRoo@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:36:00 -0600 Subject: [PATCH 27/29] update command to build local vsix file and directory (#79) --- .changeset/rare-terms-worry.md | 5 +++++ .gitignore | 1 + package.json | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changeset/rare-terms-worry.md diff --git a/.changeset/rare-terms-worry.md b/.changeset/rare-terms-worry.md new file mode 100644 index 0000000000..8e8e66c3e1 --- /dev/null +++ b/.changeset/rare-terms-worry.md @@ -0,0 +1,5 @@ +--- +"roo-cline": minor +--- + +Larger Promp Text Input diff --git a/.gitignore b/.gitignore index 8c9d9cf5db..91e0bb9331 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ node_modules .DS_Store # Builds +bin roo-cline-*.vsix # Local prompts diff --git a/package.json b/package.json index 5be828468b..28cc201be0 100644 --- a/package.json +++ b/package.json @@ -153,7 +153,7 @@ "publish": "npm run build && changeset publish && npm install --package-lock-only", "version-packages": "changeset version && npm install --package-lock-only", "vscode:prepublish": "npm run package", - "vsix": "npx vsce package --out bin", + "vsix": "mkdir -p bin && npx vsce package --out bin", "watch": "npm-run-all -p watch:*", "watch:esbuild": "node esbuild.js --watch", "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", From af9df77c2c012e828ad03ab81199256ebfdddec2 Mon Sep 17 00:00:00 2001 From: R00-B0T <110429663+R00-B0T@users.noreply.github.com> Date: Wed, 11 Dec 2024 13:48:53 -0800 Subject: [PATCH 28/29] Changeset version bump (#80) Co-authored-by: github-actions[bot] Co-authored-by: ColemanRoo --- .changeset/rare-terms-worry.md | 5 ---- CHANGELOG.md | 50 +++++++++++++++++++--------------- package-lock.json | 4 +-- package.json | 4 +-- 4 files changed, 32 insertions(+), 31 deletions(-) delete mode 100644 .changeset/rare-terms-worry.md diff --git a/.changeset/rare-terms-worry.md b/.changeset/rare-terms-worry.md deleted file mode 100644 index 8e8e66c3e1..0000000000 --- a/.changeset/rare-terms-worry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"roo-cline": minor ---- - -Larger Promp Text Input diff --git a/CHANGELOG.md b/CHANGELOG.md index f74ef92480..0920e85695 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,80 +1,86 @@ # Roo Cline Changelog +## 2.1.21 + +### Patch Changes + +- 8dbd019: Larger Promp Text Input + ## [2.1.20] -- Add Gemini 2.0 +- Add Gemini 2.0 ## [2.1.19] -- Better error handling for diff editing +- Better error handling for diff editing ## [2.1.18] -- Diff editing bugfix to handle Windows line endings +- Diff editing bugfix to handle Windows line endings ## [2.1.17] -- Switch to search/replace diffs in experimental diff editing mode +- Switch to search/replace diffs in experimental diff editing mode ## [2.1.16] -- Allow copying prompts from the history screen +- Allow copying prompts from the history screen ## [2.1.15] -- Incorporate dbasclpy's [PR](https://github.com/RooVetGit/Roo-Cline/pull/54) to add support for gemini-exp-1206 -- Make it clear that diff editing is very experimental +- Incorporate dbasclpy's [PR](https://github.com/RooVetGit/Roo-Cline/pull/54) to add support for gemini-exp-1206 +- Make it clear that diff editing is very experimental ## [2.1.14] -- Fix bug where diffs were not being applied correctly and try Aider's [unified diff prompt](https://github.com/Aider-AI/aider/blob/3995accd0ca71cea90ef76d516837f8c2731b9fe/aider/coders/udiff_prompts.py#L75-L105) -- If diffs are enabled, automatically reject write_to_file commands that lead to truncated output +- Fix bug where diffs were not being applied correctly and try Aider's [unified diff prompt](https://github.com/Aider-AI/aider/blob/3995accd0ca71cea90ef76d516837f8c2731b9fe/aider/coders/udiff_prompts.py#L75-L105) +- If diffs are enabled, automatically reject write_to_file commands that lead to truncated output ## [2.1.13] -- Fix https://github.com/RooVetGit/Roo-Cline/issues/50 where sound effects were not respecting settings +- Fix https://github.com/RooVetGit/Roo-Cline/issues/50 where sound effects were not respecting settings ## [2.1.12] -- Incorporate JoziGila's [PR](https://github.com/cline/cline/pull/158) to add support for editing through diffs +- Incorporate JoziGila's [PR](https://github.com/cline/cline/pull/158) to add support for editing through diffs ## [2.1.11] -- Incorporate lloydchang's [PR](https://github.com/RooVetGit/Roo-Cline/pull/42) to add support for OpenRouter compression +- Incorporate lloydchang's [PR](https://github.com/RooVetGit/Roo-Cline/pull/42) to add support for OpenRouter compression ## [2.1.10] -- Incorporate HeavenOSK's [PR](https://github.com/cline/cline/pull/818) to add sound effects to Cline +- Incorporate HeavenOSK's [PR](https://github.com/cline/cline/pull/818) to add sound effects to Cline ## [2.1.9] -- Add instructions for using .clinerules on the settings screen +- Add instructions for using .clinerules on the settings screen ## [2.1.8] -- Roo Cline now allows configuration of which commands are allowed without approval! +- Roo Cline now allows configuration of which commands are allowed without approval! ## [2.1.7] -- Updated extension icon and metadata +- Updated extension icon and metadata ## [2.1.6] -- Roo Cline now runs in all VSCode-compatible editors +- Roo Cline now runs in all VSCode-compatible editors ## [2.1.5] -- Fix bug in browser action approval +- Fix bug in browser action approval ## [2.1.4] -- Roo Cline now can run side-by-side with Cline +- Roo Cline now can run side-by-side with Cline ## [2.1.3] -- Roo Cline now allows browser actions without approval when `alwaysAllowBrowser` is true +- Roo Cline now allows browser actions without approval when `alwaysAllowBrowser` is true ## [2.1.2] -- Support for auto-approval of write operations and command execution -- Support for .clinerules custom instructions +- Support for auto-approval of write operations and command execution +- Support for .clinerules custom instructions diff --git a/package-lock.json b/package-lock.json index 49b0bfca39..89fcac9ee3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "roo-cline", - "version": "2.1.20", + "version": "2.1.21", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "roo-cline", - "version": "2.1.20", + "version": "2.1.21", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", "@anthropic-ai/sdk": "^0.26.0", diff --git a/package.json b/package.json index 28cc201be0..ffea77c820 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Roo Cline", "description": "A fork of Cline, an autonomous coding agent, with some added experimental configuration and automation features.", "publisher": "RooVeterinaryInc", - "version": "2.1.20", + "version": "2.1.21", "icon": "assets/icons/rocket.png", "galleryBanner": { "color": "#617A91", @@ -214,7 +214,7 @@ }, "lint-staged": { "src/**/*.{ts,tsx}": [ - "npx eslint -c .eslintrc.json" + "npx eslint -c .eslintrc.json" ] } } From 33eb0a6fc0d9b9de76a4af489bcbf6124021684e Mon Sep 17 00:00:00 2001 From: Abel Trejo Pineda Date: Wed, 11 Dec 2024 14:15:16 -0800 Subject: [PATCH 29/29] Adding scripts and workflow for release notes generation (#81) --- .github/actions/ai-release-notes/action.yml | 86 ++++++++++++++ .github/scripts/ai-release-notes.py | 123 ++++++++++++++++++++ .github/scripts/release-notes-prompt.py | 118 +++++++++++++++++-- .github/workflows/changeset-ai-releases.yml | 8 +- 4 files changed, 320 insertions(+), 15 deletions(-) create mode 100644 .github/actions/ai-release-notes/action.yml create mode 100644 .github/scripts/ai-release-notes.py diff --git a/.github/actions/ai-release-notes/action.yml b/.github/actions/ai-release-notes/action.yml new file mode 100644 index 0000000000..294e64500c --- /dev/null +++ b/.github/actions/ai-release-notes/action.yml @@ -0,0 +1,86 @@ +name: AI Release Notes +description: Generate AI release notes using git and openai, outputs 'RELEASE_NOTES' and 'OPENAI_PROMPT' + +inputs: + OPENAI_API_KEY: + required: true + type: string + GHA_PAT: + required: true + type: string + model_name: + required: false + type: string + default: gpt-4o-mini + repo_path: + required: false + type: string + custom_prompt: + required: false + default: '' + type: string + git_ref: + required: false + type: string + default: '' + head_ref: + required: false + type: string + default: main + base_ref: + required: false + type: string + default: main + +outputs: + RELEASE_NOTES: + description: "AI generated release notes" + value: ${{ steps.ai_release_notes.outputs.RELEASE_NOTES }} + OPENAI_PROMPT: + description: "Prompt used to generate release notes" + value: ${{ steps.ai_prompt.outputs.OPENAI_PROMPT }} + +env: + GITHUB_REF: ${{ inputs.git_ref == '' && github.event.pull_request.head.ref || inputs.git_ref }} + BASE_REF: ${{ inputs.base_ref == '' && github.base_ref || inputs.base_ref }} + HEAD_REF: ${{ inputs.head_ref == '' && github.event.pull_request.head.sha || inputs.head_ref }} + +runs: + using: "composite" + steps: + - uses: actions/checkout@v4 + with: + repository: ${{ inputs.repo_path }} + token: ${{ inputs.GHA_PAT }} + ref: ${{ env.GITHUB_REF }} + fetch-depth: 0 + + - name: Set Workspace + shell: bash + run: | + pip install tiktoken + pip install pytz + + # Github outputs: 'OPENAI_PROMPT' + - name: Add Git Info to base prompt + id: ai_prompt + shell: bash + env: + BASE_REF: ${{ env.BASE_REF }} + HEAD_SHA: ${{ env.HEAD_SHA }} + PR_TITLE: ${{ github.event.pull_request.title }} + PR_BODY: ${{ github.event.pull_request.body }} + MODEL_NAME: ${{ inputs.model_name }} + CUSTOM_PROMPT: ${{ inputs.custom_prompt }} # Default: '' + run: python .github/scripts/release-notes-prompt.py + + # Github outputs: 'RELEASE_NOTES' + - name: Generate AI release notes + id: ai_release_notes + shell: bash + env: + OPENAI_API_KEY: ${{ inputs.OPENAI_API_KEY }} + CUSTOM_PROMPT: ${{ steps.ai_prompt.outputs.OPENAI_PROMPT }} + MODEL_NAME: ${{ inputs.model_name }} + run: python .github/scripts/ai-release-notes.py + diff --git a/.github/scripts/ai-release-notes.py b/.github/scripts/ai-release-notes.py new file mode 100644 index 0000000000..5dc451810e --- /dev/null +++ b/.github/scripts/ai-release-notes.py @@ -0,0 +1,123 @@ +""" +AI-powered release notes generator that creates concise and informative release notes from git changes. + +This script uses OpenAI's API to analyze git changes (summary, diff, and commit log) and generate +well-formatted release notes in markdown. It focuses on important changes and their impact, +particularly highlighting new types and schemas while avoiding repetitive information. + +Environment Variables Required: + OPENAI_API_KEY: OpenAI API key for authentication + CHANGE_SUMMARY: Summary of changes made (optional if CUSTOM_PROMPT provided) + CHANGE_DIFF: Git diff of changes (optional if CUSTOM_PROMPT provided) + CHANGE_LOG: Git commit log (optional if CUSTOM_PROMPT provided) + GITHUB_OUTPUT: Path to GitHub output file + CUSTOM_PROMPT: Custom prompt to override default (optional) +""" + +import os +import requests # type: ignore +import json +import tiktoken # type: ignore + +OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] +CHANGE_SUMMARY = os.environ.get('CHANGE_SUMMARY', '') +CHANGE_DIFF = os.environ.get('CHANGE_DIFF', '') +CHANGE_LOG = os.environ.get('CHANGE_LOG', '') +GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT") +OPEN_AI_BASE_URL = "https://api.openai.com/v1" +OPEN_API_HEADERS = {"Authorization": f"Bearer {OPENAI_API_KEY}", "Content-Type": "application/json"} +CUSTOM_PROMPT = os.environ.get('CUSTOM_PROMPT', '') +MODEL_NAME = os.environ.get('MODEL_NAME', 'gpt-3.5-turbo-16k') + +def num_tokens_from_string(string: str, model_name: str) -> int: + """ + Calculate the number of tokens in a text string for a specific model. + + Args: + string: The input text to count tokens for + model_name: Name of the OpenAI model to use for token counting + + Returns: + int: Number of tokens in the input string + """ + encoding = tiktoken.encoding_for_model(model_name) + num_tokens = len(encoding.encode(string)) + return num_tokens + +def truncate_to_token_limit(text, max_tokens, model_name): + """ + Truncate text to fit within a maximum token limit for a specific model. + + Args: + text: The input text to truncate + max_tokens: Maximum number of tokens allowed + model_name: Name of the OpenAI model to use for tokenization + + Returns: + str: Truncated text that fits within the token limit + """ + encoding = tiktoken.encoding_for_model(model_name) + encoded = encoding.encode(text) + truncated = encoded[:max_tokens] + return encoding.decode(truncated) + +def generate_release_notes(model_name): + """ + Generate release notes using OpenAI's API based on git changes. + + Uses the GPT-3.5-turbo model to analyze change summary, commit log, and code diff + to generate concise and informative release notes in markdown format. The notes + focus on important changes and their impact, with sections for new types/schemas + and other updates. + + Returns: + str: Generated release notes in markdown format + + Raises: + requests.exceptions.RequestException: If the OpenAI API request fails + """ + max_tokens = 14000 # Reserve some tokens for the response + + # Truncate inputs if necessary to fit within token limits + change_summary = '' if CUSTOM_PROMPT else truncate_to_token_limit(CHANGE_SUMMARY, 1000, model_name) + change_log = '' if CUSTOM_PROMPT else truncate_to_token_limit(CHANGE_LOG, 2000, model_name) + change_diff = '' if CUSTOM_PROMPT else truncate_to_token_limit(CHANGE_DIFF, max_tokens - num_tokens_from_string(change_summary, model_name) - num_tokens_from_string(change_log, model_name) - 1000, model_name) + + url = f"{OPEN_AI_BASE_URL}/chat/completions" + + # Construct prompt for OpenAI API + openai_prompt = CUSTOM_PROMPT if CUSTOM_PROMPT else f"""Based on the following summary of changes, commit log and code diff, please generate concise and informative release notes: + Summary of changes: + {change_summary} + Commit log: + {change_log} + Code Diff: + {json.dumps(change_diff)} + """ + + data = { + "model": model_name, + "messages": [{"role": "user", "content": openai_prompt}], + "temperature": 0.7, + "max_tokens": 1000, + } + + print("----------------------------------------------------------------------------------------------------------") + print("POST request to OpenAI") + print("----------------------------------------------------------------------------------------------------------") + ai_response = requests.post(url, headers=OPEN_API_HEADERS, json=data) + print(f"Status Code: {str(ai_response.status_code)}") + print(f"Response: {ai_response.text}") + ai_response.raise_for_status() + + return ai_response.json()["choices"][0]["message"]["content"] + +release_notes = generate_release_notes(MODEL_NAME) +print("----------------------------------------------------------------------------------------------------------") +print("OpenAI generated release notes") +print("----------------------------------------------------------------------------------------------------------") +print(release_notes) + +# Write the release notes to GITHUB_OUTPUT +with open(GITHUB_OUTPUT, "a") as outputs_file: + outputs_file.write(f"RELEASE_NOTES< and that contains [!IMPORTANT] + ellipsis_match = re.search(r'(.*?)', pr_body, re.DOTALL) + if ellipsis_match: + content = ellipsis_match.group(1).strip() + important_match = re.search(r'\[!IMPORTANT\](.*?)(?=\[!|$)', content, re.DOTALL) + if important_match: + important_text = important_match.group(1).strip() + important_text = re.sub(r'^-+\s*', '', important_text) + return important_text.strip() + return "" + +def extract_coderabbit_summary(pr_body): + # Find content between ## Summary by CodeRabbit and the next ## or end of text + summary_match = re.search(r'## Summary by CodeRabbit\s*\n(.*?)(?=\n##|$)', pr_body, re.DOTALL) + return summary_match.group(1).strip() if summary_match else "" + +def num_tokens_from_string(string: str, model_name: str) -> int: + """ + Calculate the number of tokens in a text string for a specific model. + + Args: + string: The input text to count tokens for + model_name: Name of the OpenAI model to use for token counting + + Returns: + int: Number of tokens in the input string + """ + encoding = tiktoken.encoding_for_model(model_name) + num_tokens = len(encoding.encode(string)) + return num_tokens + +def truncate_to_token_limit(text, max_tokens, model_name): + """ + Truncate text to fit within a maximum token limit for a specific model. + + Args: + text: The input text to truncate + max_tokens: Maximum number of tokens allowed + model_name: Name of the OpenAI model to use for tokenization + + Returns: + str: Truncated text that fits within the token limit + """ + encoding = tiktoken.encoding_for_model(model_name) + encoded = encoding.encode(text) + truncated = encoded[:max_tokens] + return encoding.decode(truncated) + +# Extract sections and combine into PR_OVERVIEW +description = extract_description_section(PR_BODY) +important = extract_ellipsis_important(PR_BODY) +summary = extract_coderabbit_summary(PR_BODY) + +PR_OVERVIEW = "\n\n".join(filter(None, [description, important, summary])) + +# Get git information +base_sha = subprocess.getoutput(f"git rev-parse origin/{BASE_REF}") if BASE_REF == 'main' else BASE_REF +diff_overview = subprocess.getoutput(f"git diff {base_sha}..{HEAD_SHA} --name-status | awk '{{print $2}}' | sort | uniq -c | awk '{{print $2 \": \" $1 \" files changed\"}}'") +git_log = subprocess.getoutput(f"git log {base_sha}..{HEAD_SHA} --pretty=format:'%h - %s (%an)' --reverse | head -n 50") +git_diff = subprocess.getoutput(f"git diff {base_sha}..{HEAD_SHA} --minimal --abbrev --ignore-cr-at-eol --ignore-space-at-eol --ignore-space-change --ignore-all-space --ignore-blank-lines --unified=0 --diff-filter=ACDMRT") + +max_tokens = 14000 # Reserve some tokens for the response +changes_summary = truncate_to_token_limit(diff_overview, 1000, MODEL_NAME) +git_logs = truncate_to_token_limit(git_log, 2000, MODEL_NAME) +changes_diff = truncate_to_token_limit(git_diff, max_tokens - num_tokens_from_string(changes_summary, MODEL_NAME) - num_tokens_from_string(git_logs, MODEL_NAME) - 1000, MODEL_NAME) + +# Get today's existing changelog if any +existing_changelog = EXISTING_NOTES if EXISTING_NOTES != "null" else None +existing_changelog_text = f"\nAdditional context:\n{existing_changelog}" if existing_changelog else "" TODAY = datetime.now(timezone('US/Eastern')).isoformat(sep=' ', timespec='seconds') -BASE_PROMPT = f"""Based on the following 'PR Information', please generate concise and informative release notes to be read by developers. +BASE_PROMPT = CUSTOM_PROMPT if CUSTOM_PROMPT else f"""Based on the following 'PR Information', please generate concise and informative release notes to be read by developers. Format the release notes with markdown, and always use this structure: a descriptive and very short title (no more than 8 words) with heading level 2, a paragraph with a summary of changes (no header), and if applicable, sections for '🚀 New Features & Improvements', '🐛 Bugs Fixed' and '🔧 Other Updates', with heading level 3, skip respectively the sections if not applicable. Finally include the following markdown comment with the PR merged date: . Avoid being repetitive and focus on the most important changes and their impact, discard any mention of version bumps/updates, changeset files, environment variables or syntax updates. PR Information:""" +OPENAI_PROMPT = f"""{BASE_PROMPT} +Git log summary: +{changes_summary} +Commit Messages: +{git_logs} +PR Title: +{PR_TITLE} +PR Overview: +{PR_OVERVIEW}{existing_changelog_text} +Code Diff: +{json.dumps(changes_diff)}""" + +print("OpenAI Prompt") +print("----------------------------------------------------------------") +print(OPENAI_PROMPT) + # Write the prompt to GITHUB_OUTPUT with open(GITHUB_OUTPUT, "a") as outputs_file: - outputs_file.write(f"BASE_PROMPT<