├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── src ├── app.ts ├── constants.ts ├── context │ ├── language │ │ ├── javascript-parser.ts │ │ └── python-parser.ts │ └── review.ts ├── data │ └── PRSuggestionImpl.ts ├── env.ts ├── llms │ ├── chat.ts │ └── groq.ts ├── prompts.ts ├── prompts │ └── inline-prompt.ts ├── review-agent.ts └── reviews.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .env 4 | misc.txt 5 | review-agent-prime-pk.pem 6 | review-agent-test-pk.pem 7 | *.pem 8 | .DS_Store 9 | src/test.ts 10 | src/test-files.ts 11 | src/tests 12 | src/scripts -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AI Review Agent 2 | 3 | This is a GitHub App that reviews pull requests and submits reviews with AI. 4 | 5 | ## Setup 6 | 7 | 1. Download NGROK [here](https://download.ngrok.com/). This will be used to create a secure tunnel to your local server. 8 | 9 | 2. Run NGROK in your terminal with the following command: 10 | 11 | ``` 12 | ngrok http 3000 13 | ``` 14 | 15 | Here you'll see a URL in the format of `https://.ngrok.app`. Make sure to save this URL as you'll need it to configure your GitHub App. 16 | 17 | 3. Create a new [GitHub App here](https://github.com/settings/apps) 18 | 19 | - Make sure to paste the NGROK URL + `/api/review` (e.g. `https://4836-204-48-36-234.ngrok-free.app/api/review`) as the "Webhook URL" 20 | - Create a webhook secret, this can be anything and then paste it in the "secret" field when setting up the GitHub app 21 | - Make sure to grant the app the read & write permissions for the following: 22 | - Pull Requests 23 | - Repository Contents 24 | - Issues 25 | - Commit Statuses 26 | - Webhooks 27 | - Subscribe to the following events: 28 | 29 | - Pull Request 30 | - Pull Request Review 31 | - Pull Request Review Comment 32 | - Pull Request Comment Thread 33 | - Commit Comment 34 | 35 | - Download your private key - this will be used later on to authenticate your app 36 | 37 | - Install your GitHub app to all of your repositories 38 | 39 | 4. Clone the repo 40 | 41 | ``` 42 | git clone https://github.com/CoderAgent/SecureAgent 43 | cd SecureAgent 44 | ``` 45 | 46 | 5. Install dependencies 47 | 48 | ``` 49 | npm install 50 | ``` 51 | 52 | 6. Get your Groq API key [here](https://console.groq.com/keys). Through Groq, you'll have free access to the Llama and Gemini models. 53 | 54 | 7. Create a `.env` file in the root of the project with the following variables: 55 | 56 | ``` 57 | GITHUB_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY----- 58 | 59 | -----END RSA PRIVATE KEY-----" 60 | GITHUB_APP_ID= 61 | GITHUB_WEBHOOK_SECRET= 62 | GROQ_API_KEY= 63 | ``` 64 | 65 | Make sure your GITHUB_PRIVATE_KEY is formatted correctly, with the "--- BEGIN RSA PRIVATE KEY ---" and "--- END RSA PRIVATE KEY ---" lines, and is enclosed in quotes. 66 | 67 | 8. Within the `SecureAgent` directory in your IDE, run the code with the following command: 68 | 69 | ``` 70 | npm run start 71 | ``` 72 | 73 | 9. Create a pull request on one of your repositories and watch the review agent submit a review! 74 | - Make sure to create the pull request on a repository that your GitHub app has access to. 75 | - Make sure the pull request has at least one changed file that is supported by the review agent. The following file extensions are ignored: ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".mp4", ".mp3", ".md", ".json", ".env", ".toml", and ".svg". 76 | - You will have to create new pull requests each time to test the review agent, as it will not work on the same pull request twice. 77 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "secure-agent", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "secure-agent", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@babel/parser": "^7.23.0", 13 | "@babel/traverse": "^7.23.2", 14 | "@octokit/rest": "^20.0.2", 15 | "@octokit/webhooks-definitions": "^3.67.3", 16 | "@types/node": "^20.8.3", 17 | "chalk": "^5.3.0", 18 | "diff": "^5.1.0", 19 | "dotenv": "^16.3.1", 20 | "gpt-tokenizer": "^2.1.2", 21 | "groq-sdk": "^0.8.0", 22 | "octokit": "^3.1.1", 23 | "xml2js": "^0.6.2" 24 | }, 25 | "devDependencies": { 26 | "@types/babel__traverse": "^7.20.3", 27 | "@types/diff": "^5.0.7", 28 | "@types/xml2js": "^0.4.13", 29 | "csv-writer": "^1.6.0", 30 | "smee-client": "^1.2.3", 31 | "tsx": "^4.19.2", 32 | "typescript": "^5.2.2" 33 | } 34 | }, 35 | "node_modules/@babel/code-frame": { 36 | "version": "7.22.13", 37 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", 38 | "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", 39 | "dependencies": { 40 | "@babel/highlight": "^7.22.13", 41 | "chalk": "^2.4.2" 42 | }, 43 | "engines": { 44 | "node": ">=6.9.0" 45 | } 46 | }, 47 | "node_modules/@babel/code-frame/node_modules/chalk": { 48 | "version": "2.4.2", 49 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 50 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 51 | "license": "MIT", 52 | "dependencies": { 53 | "ansi-styles": "^3.2.1", 54 | "escape-string-regexp": "^1.0.5", 55 | "supports-color": "^5.3.0" 56 | }, 57 | "engines": { 58 | "node": ">=4" 59 | } 60 | }, 61 | "node_modules/@babel/generator": { 62 | "version": "7.23.0", 63 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", 64 | "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", 65 | "dependencies": { 66 | "@babel/types": "^7.23.0", 67 | "@jridgewell/gen-mapping": "^0.3.2", 68 | "@jridgewell/trace-mapping": "^0.3.17", 69 | "jsesc": "^2.5.1" 70 | }, 71 | "engines": { 72 | "node": ">=6.9.0" 73 | } 74 | }, 75 | "node_modules/@babel/helper-environment-visitor": { 76 | "version": "7.22.20", 77 | "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", 78 | "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", 79 | "engines": { 80 | "node": ">=6.9.0" 81 | } 82 | }, 83 | "node_modules/@babel/helper-function-name": { 84 | "version": "7.23.0", 85 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", 86 | "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", 87 | "dependencies": { 88 | "@babel/template": "^7.22.15", 89 | "@babel/types": "^7.23.0" 90 | }, 91 | "engines": { 92 | "node": ">=6.9.0" 93 | } 94 | }, 95 | "node_modules/@babel/helper-hoist-variables": { 96 | "version": "7.22.5", 97 | "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", 98 | "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", 99 | "dependencies": { 100 | "@babel/types": "^7.22.5" 101 | }, 102 | "engines": { 103 | "node": ">=6.9.0" 104 | } 105 | }, 106 | "node_modules/@babel/helper-split-export-declaration": { 107 | "version": "7.22.6", 108 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", 109 | "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", 110 | "dependencies": { 111 | "@babel/types": "^7.22.5" 112 | }, 113 | "engines": { 114 | "node": ">=6.9.0" 115 | } 116 | }, 117 | "node_modules/@babel/helper-string-parser": { 118 | "version": "7.22.5", 119 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", 120 | "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", 121 | "engines": { 122 | "node": ">=6.9.0" 123 | } 124 | }, 125 | "node_modules/@babel/helper-validator-identifier": { 126 | "version": "7.22.20", 127 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", 128 | "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", 129 | "engines": { 130 | "node": ">=6.9.0" 131 | } 132 | }, 133 | "node_modules/@babel/highlight": { 134 | "version": "7.22.20", 135 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", 136 | "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", 137 | "dependencies": { 138 | "@babel/helper-validator-identifier": "^7.22.20", 139 | "chalk": "^2.4.2", 140 | "js-tokens": "^4.0.0" 141 | }, 142 | "engines": { 143 | "node": ">=6.9.0" 144 | } 145 | }, 146 | "node_modules/@babel/highlight/node_modules/chalk": { 147 | "version": "2.4.2", 148 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 149 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 150 | "license": "MIT", 151 | "dependencies": { 152 | "ansi-styles": "^3.2.1", 153 | "escape-string-regexp": "^1.0.5", 154 | "supports-color": "^5.3.0" 155 | }, 156 | "engines": { 157 | "node": ">=4" 158 | } 159 | }, 160 | "node_modules/@babel/parser": { 161 | "version": "7.23.0", 162 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", 163 | "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", 164 | "bin": { 165 | "parser": "bin/babel-parser.js" 166 | }, 167 | "engines": { 168 | "node": ">=6.0.0" 169 | } 170 | }, 171 | "node_modules/@babel/template": { 172 | "version": "7.22.15", 173 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", 174 | "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", 175 | "dependencies": { 176 | "@babel/code-frame": "^7.22.13", 177 | "@babel/parser": "^7.22.15", 178 | "@babel/types": "^7.22.15" 179 | }, 180 | "engines": { 181 | "node": ">=6.9.0" 182 | } 183 | }, 184 | "node_modules/@babel/traverse": { 185 | "version": "7.23.2", 186 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", 187 | "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", 188 | "dependencies": { 189 | "@babel/code-frame": "^7.22.13", 190 | "@babel/generator": "^7.23.0", 191 | "@babel/helper-environment-visitor": "^7.22.20", 192 | "@babel/helper-function-name": "^7.23.0", 193 | "@babel/helper-hoist-variables": "^7.22.5", 194 | "@babel/helper-split-export-declaration": "^7.22.6", 195 | "@babel/parser": "^7.23.0", 196 | "@babel/types": "^7.23.0", 197 | "debug": "^4.1.0", 198 | "globals": "^11.1.0" 199 | }, 200 | "engines": { 201 | "node": ">=6.9.0" 202 | } 203 | }, 204 | "node_modules/@babel/traverse/node_modules/debug": { 205 | "version": "4.3.4", 206 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 207 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 208 | "dependencies": { 209 | "ms": "2.1.2" 210 | }, 211 | "engines": { 212 | "node": ">=6.0" 213 | }, 214 | "peerDependenciesMeta": { 215 | "supports-color": { 216 | "optional": true 217 | } 218 | } 219 | }, 220 | "node_modules/@babel/traverse/node_modules/ms": { 221 | "version": "2.1.2", 222 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 223 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 224 | }, 225 | "node_modules/@babel/types": { 226 | "version": "7.23.0", 227 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", 228 | "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", 229 | "dependencies": { 230 | "@babel/helper-string-parser": "^7.22.5", 231 | "@babel/helper-validator-identifier": "^7.22.20", 232 | "to-fast-properties": "^2.0.0" 233 | }, 234 | "engines": { 235 | "node": ">=6.9.0" 236 | } 237 | }, 238 | "node_modules/@esbuild/aix-ppc64": { 239 | "version": "0.23.1", 240 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", 241 | "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", 242 | "cpu": [ 243 | "ppc64" 244 | ], 245 | "dev": true, 246 | "license": "MIT", 247 | "optional": true, 248 | "os": [ 249 | "aix" 250 | ], 251 | "engines": { 252 | "node": ">=18" 253 | } 254 | }, 255 | "node_modules/@esbuild/android-arm": { 256 | "version": "0.23.1", 257 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", 258 | "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", 259 | "cpu": [ 260 | "arm" 261 | ], 262 | "dev": true, 263 | "license": "MIT", 264 | "optional": true, 265 | "os": [ 266 | "android" 267 | ], 268 | "engines": { 269 | "node": ">=18" 270 | } 271 | }, 272 | "node_modules/@esbuild/android-arm64": { 273 | "version": "0.23.1", 274 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", 275 | "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", 276 | "cpu": [ 277 | "arm64" 278 | ], 279 | "dev": true, 280 | "license": "MIT", 281 | "optional": true, 282 | "os": [ 283 | "android" 284 | ], 285 | "engines": { 286 | "node": ">=18" 287 | } 288 | }, 289 | "node_modules/@esbuild/android-x64": { 290 | "version": "0.23.1", 291 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", 292 | "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", 293 | "cpu": [ 294 | "x64" 295 | ], 296 | "dev": true, 297 | "license": "MIT", 298 | "optional": true, 299 | "os": [ 300 | "android" 301 | ], 302 | "engines": { 303 | "node": ">=18" 304 | } 305 | }, 306 | "node_modules/@esbuild/darwin-arm64": { 307 | "version": "0.23.1", 308 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", 309 | "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", 310 | "cpu": [ 311 | "arm64" 312 | ], 313 | "dev": true, 314 | "license": "MIT", 315 | "optional": true, 316 | "os": [ 317 | "darwin" 318 | ], 319 | "engines": { 320 | "node": ">=18" 321 | } 322 | }, 323 | "node_modules/@esbuild/darwin-x64": { 324 | "version": "0.23.1", 325 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", 326 | "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", 327 | "cpu": [ 328 | "x64" 329 | ], 330 | "dev": true, 331 | "license": "MIT", 332 | "optional": true, 333 | "os": [ 334 | "darwin" 335 | ], 336 | "engines": { 337 | "node": ">=18" 338 | } 339 | }, 340 | "node_modules/@esbuild/freebsd-arm64": { 341 | "version": "0.23.1", 342 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", 343 | "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", 344 | "cpu": [ 345 | "arm64" 346 | ], 347 | "dev": true, 348 | "license": "MIT", 349 | "optional": true, 350 | "os": [ 351 | "freebsd" 352 | ], 353 | "engines": { 354 | "node": ">=18" 355 | } 356 | }, 357 | "node_modules/@esbuild/freebsd-x64": { 358 | "version": "0.23.1", 359 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", 360 | "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", 361 | "cpu": [ 362 | "x64" 363 | ], 364 | "dev": true, 365 | "license": "MIT", 366 | "optional": true, 367 | "os": [ 368 | "freebsd" 369 | ], 370 | "engines": { 371 | "node": ">=18" 372 | } 373 | }, 374 | "node_modules/@esbuild/linux-arm": { 375 | "version": "0.23.1", 376 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", 377 | "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", 378 | "cpu": [ 379 | "arm" 380 | ], 381 | "dev": true, 382 | "license": "MIT", 383 | "optional": true, 384 | "os": [ 385 | "linux" 386 | ], 387 | "engines": { 388 | "node": ">=18" 389 | } 390 | }, 391 | "node_modules/@esbuild/linux-arm64": { 392 | "version": "0.23.1", 393 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", 394 | "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", 395 | "cpu": [ 396 | "arm64" 397 | ], 398 | "dev": true, 399 | "license": "MIT", 400 | "optional": true, 401 | "os": [ 402 | "linux" 403 | ], 404 | "engines": { 405 | "node": ">=18" 406 | } 407 | }, 408 | "node_modules/@esbuild/linux-ia32": { 409 | "version": "0.23.1", 410 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", 411 | "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", 412 | "cpu": [ 413 | "ia32" 414 | ], 415 | "dev": true, 416 | "license": "MIT", 417 | "optional": true, 418 | "os": [ 419 | "linux" 420 | ], 421 | "engines": { 422 | "node": ">=18" 423 | } 424 | }, 425 | "node_modules/@esbuild/linux-loong64": { 426 | "version": "0.23.1", 427 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", 428 | "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", 429 | "cpu": [ 430 | "loong64" 431 | ], 432 | "dev": true, 433 | "license": "MIT", 434 | "optional": true, 435 | "os": [ 436 | "linux" 437 | ], 438 | "engines": { 439 | "node": ">=18" 440 | } 441 | }, 442 | "node_modules/@esbuild/linux-mips64el": { 443 | "version": "0.23.1", 444 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", 445 | "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", 446 | "cpu": [ 447 | "mips64el" 448 | ], 449 | "dev": true, 450 | "license": "MIT", 451 | "optional": true, 452 | "os": [ 453 | "linux" 454 | ], 455 | "engines": { 456 | "node": ">=18" 457 | } 458 | }, 459 | "node_modules/@esbuild/linux-ppc64": { 460 | "version": "0.23.1", 461 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", 462 | "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", 463 | "cpu": [ 464 | "ppc64" 465 | ], 466 | "dev": true, 467 | "license": "MIT", 468 | "optional": true, 469 | "os": [ 470 | "linux" 471 | ], 472 | "engines": { 473 | "node": ">=18" 474 | } 475 | }, 476 | "node_modules/@esbuild/linux-riscv64": { 477 | "version": "0.23.1", 478 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", 479 | "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", 480 | "cpu": [ 481 | "riscv64" 482 | ], 483 | "dev": true, 484 | "license": "MIT", 485 | "optional": true, 486 | "os": [ 487 | "linux" 488 | ], 489 | "engines": { 490 | "node": ">=18" 491 | } 492 | }, 493 | "node_modules/@esbuild/linux-s390x": { 494 | "version": "0.23.1", 495 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", 496 | "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", 497 | "cpu": [ 498 | "s390x" 499 | ], 500 | "dev": true, 501 | "license": "MIT", 502 | "optional": true, 503 | "os": [ 504 | "linux" 505 | ], 506 | "engines": { 507 | "node": ">=18" 508 | } 509 | }, 510 | "node_modules/@esbuild/linux-x64": { 511 | "version": "0.23.1", 512 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", 513 | "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", 514 | "cpu": [ 515 | "x64" 516 | ], 517 | "dev": true, 518 | "license": "MIT", 519 | "optional": true, 520 | "os": [ 521 | "linux" 522 | ], 523 | "engines": { 524 | "node": ">=18" 525 | } 526 | }, 527 | "node_modules/@esbuild/netbsd-x64": { 528 | "version": "0.23.1", 529 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", 530 | "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", 531 | "cpu": [ 532 | "x64" 533 | ], 534 | "dev": true, 535 | "license": "MIT", 536 | "optional": true, 537 | "os": [ 538 | "netbsd" 539 | ], 540 | "engines": { 541 | "node": ">=18" 542 | } 543 | }, 544 | "node_modules/@esbuild/openbsd-arm64": { 545 | "version": "0.23.1", 546 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", 547 | "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", 548 | "cpu": [ 549 | "arm64" 550 | ], 551 | "dev": true, 552 | "license": "MIT", 553 | "optional": true, 554 | "os": [ 555 | "openbsd" 556 | ], 557 | "engines": { 558 | "node": ">=18" 559 | } 560 | }, 561 | "node_modules/@esbuild/openbsd-x64": { 562 | "version": "0.23.1", 563 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", 564 | "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", 565 | "cpu": [ 566 | "x64" 567 | ], 568 | "dev": true, 569 | "license": "MIT", 570 | "optional": true, 571 | "os": [ 572 | "openbsd" 573 | ], 574 | "engines": { 575 | "node": ">=18" 576 | } 577 | }, 578 | "node_modules/@esbuild/sunos-x64": { 579 | "version": "0.23.1", 580 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", 581 | "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", 582 | "cpu": [ 583 | "x64" 584 | ], 585 | "dev": true, 586 | "license": "MIT", 587 | "optional": true, 588 | "os": [ 589 | "sunos" 590 | ], 591 | "engines": { 592 | "node": ">=18" 593 | } 594 | }, 595 | "node_modules/@esbuild/win32-arm64": { 596 | "version": "0.23.1", 597 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", 598 | "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", 599 | "cpu": [ 600 | "arm64" 601 | ], 602 | "dev": true, 603 | "license": "MIT", 604 | "optional": true, 605 | "os": [ 606 | "win32" 607 | ], 608 | "engines": { 609 | "node": ">=18" 610 | } 611 | }, 612 | "node_modules/@esbuild/win32-ia32": { 613 | "version": "0.23.1", 614 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", 615 | "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", 616 | "cpu": [ 617 | "ia32" 618 | ], 619 | "dev": true, 620 | "license": "MIT", 621 | "optional": true, 622 | "os": [ 623 | "win32" 624 | ], 625 | "engines": { 626 | "node": ">=18" 627 | } 628 | }, 629 | "node_modules/@esbuild/win32-x64": { 630 | "version": "0.23.1", 631 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", 632 | "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", 633 | "cpu": [ 634 | "x64" 635 | ], 636 | "dev": true, 637 | "license": "MIT", 638 | "optional": true, 639 | "os": [ 640 | "win32" 641 | ], 642 | "engines": { 643 | "node": ">=18" 644 | } 645 | }, 646 | "node_modules/@jridgewell/gen-mapping": { 647 | "version": "0.3.3", 648 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", 649 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", 650 | "dependencies": { 651 | "@jridgewell/set-array": "^1.0.1", 652 | "@jridgewell/sourcemap-codec": "^1.4.10", 653 | "@jridgewell/trace-mapping": "^0.3.9" 654 | }, 655 | "engines": { 656 | "node": ">=6.0.0" 657 | } 658 | }, 659 | "node_modules/@jridgewell/resolve-uri": { 660 | "version": "3.1.1", 661 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", 662 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", 663 | "engines": { 664 | "node": ">=6.0.0" 665 | } 666 | }, 667 | "node_modules/@jridgewell/set-array": { 668 | "version": "1.1.2", 669 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", 670 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", 671 | "engines": { 672 | "node": ">=6.0.0" 673 | } 674 | }, 675 | "node_modules/@jridgewell/sourcemap-codec": { 676 | "version": "1.4.15", 677 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 678 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" 679 | }, 680 | "node_modules/@jridgewell/trace-mapping": { 681 | "version": "0.3.20", 682 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", 683 | "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", 684 | "dependencies": { 685 | "@jridgewell/resolve-uri": "^3.1.0", 686 | "@jridgewell/sourcemap-codec": "^1.4.14" 687 | } 688 | }, 689 | "node_modules/@octokit/app": { 690 | "version": "14.0.1", 691 | "resolved": "https://registry.npmjs.org/@octokit/app/-/app-14.0.1.tgz", 692 | "integrity": "sha512-4opdXcWBVhzd6FOxlaxDKXXqi9Vz2hsDSWQGNo49HbYFAX11UqMpksMjEdfvHy0x19Pse8Nvn+R6inNb/V398w==", 693 | "dependencies": { 694 | "@octokit/auth-app": "^6.0.0", 695 | "@octokit/auth-unauthenticated": "^5.0.0", 696 | "@octokit/core": "^5.0.0", 697 | "@octokit/oauth-app": "^6.0.0", 698 | "@octokit/plugin-paginate-rest": "^9.0.0", 699 | "@octokit/types": "^12.0.0", 700 | "@octokit/webhooks": "^12.0.1" 701 | }, 702 | "engines": { 703 | "node": ">= 18" 704 | } 705 | }, 706 | "node_modules/@octokit/auth-app": { 707 | "version": "6.0.1", 708 | "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-6.0.1.tgz", 709 | "integrity": "sha512-tjCD4nzQNZgmLH62+PSnTF6eGerisFgV4v6euhqJik6yWV96e1ZiiGj+NXIqbgnpjLmtnBqVUrNyGKu3DoGEGA==", 710 | "dependencies": { 711 | "@octokit/auth-oauth-app": "^7.0.0", 712 | "@octokit/auth-oauth-user": "^4.0.0", 713 | "@octokit/request": "^8.0.2", 714 | "@octokit/request-error": "^5.0.0", 715 | "@octokit/types": "^12.0.0", 716 | "deprecation": "^2.3.1", 717 | "lru-cache": "^10.0.0", 718 | "universal-github-app-jwt": "^1.1.1", 719 | "universal-user-agent": "^6.0.0" 720 | }, 721 | "engines": { 722 | "node": ">= 18" 723 | } 724 | }, 725 | "node_modules/@octokit/auth-oauth-app": { 726 | "version": "7.0.1", 727 | "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.0.1.tgz", 728 | "integrity": "sha512-RE0KK0DCjCHXHlQBoubwlLijXEKfhMhKm9gO56xYvFmP1QTMb+vvwRPmQLLx0V+5AvV9N9I3lr1WyTzwL3rMDg==", 729 | "dependencies": { 730 | "@octokit/auth-oauth-device": "^6.0.0", 731 | "@octokit/auth-oauth-user": "^4.0.0", 732 | "@octokit/request": "^8.0.2", 733 | "@octokit/types": "^12.0.0", 734 | "@types/btoa-lite": "^1.0.0", 735 | "btoa-lite": "^1.0.0", 736 | "universal-user-agent": "^6.0.0" 737 | }, 738 | "engines": { 739 | "node": ">= 18" 740 | } 741 | }, 742 | "node_modules/@octokit/auth-oauth-device": { 743 | "version": "6.0.1", 744 | "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-6.0.1.tgz", 745 | "integrity": "sha512-yxU0rkL65QkjbqQedgVx3gmW7YM5fF+r5uaSj9tM/cQGVqloXcqP2xK90eTyYvl29arFVCW8Vz4H/t47mL0ELw==", 746 | "dependencies": { 747 | "@octokit/oauth-methods": "^4.0.0", 748 | "@octokit/request": "^8.0.0", 749 | "@octokit/types": "^12.0.0", 750 | "universal-user-agent": "^6.0.0" 751 | }, 752 | "engines": { 753 | "node": ">= 18" 754 | } 755 | }, 756 | "node_modules/@octokit/auth-oauth-user": { 757 | "version": "4.0.1", 758 | "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-4.0.1.tgz", 759 | "integrity": "sha512-N94wWW09d0hleCnrO5wt5MxekatqEJ4zf+1vSe8MKMrhZ7gAXKFOKrDEZW2INltvBWJCyDUELgGRv8gfErH1Iw==", 760 | "dependencies": { 761 | "@octokit/auth-oauth-device": "^6.0.0", 762 | "@octokit/oauth-methods": "^4.0.0", 763 | "@octokit/request": "^8.0.2", 764 | "@octokit/types": "^12.0.0", 765 | "btoa-lite": "^1.0.0", 766 | "universal-user-agent": "^6.0.0" 767 | }, 768 | "engines": { 769 | "node": ">= 18" 770 | } 771 | }, 772 | "node_modules/@octokit/auth-token": { 773 | "version": "4.0.0", 774 | "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", 775 | "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", 776 | "engines": { 777 | "node": ">= 18" 778 | } 779 | }, 780 | "node_modules/@octokit/auth-unauthenticated": { 781 | "version": "5.0.1", 782 | "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-5.0.1.tgz", 783 | "integrity": "sha512-oxeWzmBFxWd+XolxKTc4zr+h3mt+yofn4r7OfoIkR/Cj/o70eEGmPsFbueyJE2iBAGpjgTnEOKM3pnuEGVmiqg==", 784 | "dependencies": { 785 | "@octokit/request-error": "^5.0.0", 786 | "@octokit/types": "^12.0.0" 787 | }, 788 | "engines": { 789 | "node": ">= 18" 790 | } 791 | }, 792 | "node_modules/@octokit/core": { 793 | "version": "5.0.1", 794 | "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz", 795 | "integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==", 796 | "dependencies": { 797 | "@octokit/auth-token": "^4.0.0", 798 | "@octokit/graphql": "^7.0.0", 799 | "@octokit/request": "^8.0.2", 800 | "@octokit/request-error": "^5.0.0", 801 | "@octokit/types": "^12.0.0", 802 | "before-after-hook": "^2.2.0", 803 | "universal-user-agent": "^6.0.0" 804 | }, 805 | "engines": { 806 | "node": ">= 18" 807 | } 808 | }, 809 | "node_modules/@octokit/endpoint": { 810 | "version": "9.0.1", 811 | "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.1.tgz", 812 | "integrity": "sha512-hRlOKAovtINHQPYHZlfyFwaM8OyetxeoC81lAkBy34uLb8exrZB50SQdeW3EROqiY9G9yxQTpp5OHTV54QD+vA==", 813 | "dependencies": { 814 | "@octokit/types": "^12.0.0", 815 | "is-plain-object": "^5.0.0", 816 | "universal-user-agent": "^6.0.0" 817 | }, 818 | "engines": { 819 | "node": ">= 18" 820 | } 821 | }, 822 | "node_modules/@octokit/graphql": { 823 | "version": "7.0.2", 824 | "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", 825 | "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", 826 | "dependencies": { 827 | "@octokit/request": "^8.0.1", 828 | "@octokit/types": "^12.0.0", 829 | "universal-user-agent": "^6.0.0" 830 | }, 831 | "engines": { 832 | "node": ">= 18" 833 | } 834 | }, 835 | "node_modules/@octokit/oauth-app": { 836 | "version": "6.0.0", 837 | "resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-6.0.0.tgz", 838 | "integrity": "sha512-bNMkS+vJ6oz2hCyraT9ZfTpAQ8dZNqJJQVNaKjPLx4ue5RZiFdU1YWXguOPR8AaSHS+lKe+lR3abn2siGd+zow==", 839 | "dependencies": { 840 | "@octokit/auth-oauth-app": "^7.0.0", 841 | "@octokit/auth-oauth-user": "^4.0.0", 842 | "@octokit/auth-unauthenticated": "^5.0.0", 843 | "@octokit/core": "^5.0.0", 844 | "@octokit/oauth-authorization-url": "^6.0.2", 845 | "@octokit/oauth-methods": "^4.0.0", 846 | "@types/aws-lambda": "^8.10.83", 847 | "universal-user-agent": "^6.0.0" 848 | }, 849 | "engines": { 850 | "node": ">= 18" 851 | } 852 | }, 853 | "node_modules/@octokit/oauth-authorization-url": { 854 | "version": "6.0.2", 855 | "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz", 856 | "integrity": "sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA==", 857 | "engines": { 858 | "node": ">= 18" 859 | } 860 | }, 861 | "node_modules/@octokit/oauth-methods": { 862 | "version": "4.0.0", 863 | "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-4.0.0.tgz", 864 | "integrity": "sha512-dqy7BZLfLbi3/8X8xPKUKZclMEK9vN3fK5WF3ortRvtplQTszFvdAGbTo71gGLO+4ZxspNiLjnqdd64Chklf7w==", 865 | "dependencies": { 866 | "@octokit/oauth-authorization-url": "^6.0.2", 867 | "@octokit/request": "^8.0.2", 868 | "@octokit/request-error": "^5.0.0", 869 | "@octokit/types": "^11.0.0", 870 | "btoa-lite": "^1.0.0" 871 | }, 872 | "engines": { 873 | "node": ">= 18" 874 | } 875 | }, 876 | "node_modules/@octokit/oauth-methods/node_modules/@octokit/openapi-types": { 877 | "version": "18.1.1", 878 | "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", 879 | "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==" 880 | }, 881 | "node_modules/@octokit/oauth-methods/node_modules/@octokit/types": { 882 | "version": "11.1.0", 883 | "resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz", 884 | "integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==", 885 | "dependencies": { 886 | "@octokit/openapi-types": "^18.0.0" 887 | } 888 | }, 889 | "node_modules/@octokit/openapi-types": { 890 | "version": "19.0.0", 891 | "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz", 892 | "integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw==" 893 | }, 894 | "node_modules/@octokit/plugin-paginate-graphql": { 895 | "version": "4.0.0", 896 | "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-4.0.0.tgz", 897 | "integrity": "sha512-7HcYW5tP7/Z6AETAPU14gp5H5KmCPT3hmJrS/5tO7HIgbwenYmgw4OY9Ma54FDySuxMwD+wsJlxtuGWwuZuItA==", 898 | "engines": { 899 | "node": ">= 18" 900 | }, 901 | "peerDependencies": { 902 | "@octokit/core": ">=5" 903 | } 904 | }, 905 | "node_modules/@octokit/plugin-paginate-rest": { 906 | "version": "9.0.0", 907 | "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.0.0.tgz", 908 | "integrity": "sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==", 909 | "dependencies": { 910 | "@octokit/types": "^12.0.0" 911 | }, 912 | "engines": { 913 | "node": ">= 18" 914 | }, 915 | "peerDependencies": { 916 | "@octokit/core": ">=5" 917 | } 918 | }, 919 | "node_modules/@octokit/plugin-request-log": { 920 | "version": "4.0.0", 921 | "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", 922 | "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", 923 | "engines": { 924 | "node": ">= 18" 925 | }, 926 | "peerDependencies": { 927 | "@octokit/core": ">=5" 928 | } 929 | }, 930 | "node_modules/@octokit/plugin-rest-endpoint-methods": { 931 | "version": "10.0.0", 932 | "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.0.0.tgz", 933 | "integrity": "sha512-16VkwE2v6rXU+/gBsYC62M8lKWOphY5Lg4wpjYnVE9Zbu0J6IwiT5kILoj1YOB53XLmcJR+Nqp8DmifOPY4H3g==", 934 | "dependencies": { 935 | "@octokit/types": "^12.0.0" 936 | }, 937 | "engines": { 938 | "node": ">= 18" 939 | }, 940 | "peerDependencies": { 941 | "@octokit/core": ">=5" 942 | } 943 | }, 944 | "node_modules/@octokit/plugin-retry": { 945 | "version": "6.0.1", 946 | "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.0.1.tgz", 947 | "integrity": "sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog==", 948 | "dependencies": { 949 | "@octokit/request-error": "^5.0.0", 950 | "@octokit/types": "^12.0.0", 951 | "bottleneck": "^2.15.3" 952 | }, 953 | "engines": { 954 | "node": ">= 18" 955 | }, 956 | "peerDependencies": { 957 | "@octokit/core": ">=5" 958 | } 959 | }, 960 | "node_modules/@octokit/plugin-throttling": { 961 | "version": "8.0.0", 962 | "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.0.0.tgz", 963 | "integrity": "sha512-OkMbHYUidj81q92YRkPzWmwXkEtsI3KOcSkNm763aqUOh9IEplyX05XjKAdZFANAvaYH0Q4JBZwu4h2VnPVXZA==", 964 | "dependencies": { 965 | "@octokit/types": "^12.0.0", 966 | "bottleneck": "^2.15.3" 967 | }, 968 | "engines": { 969 | "node": ">= 18" 970 | }, 971 | "peerDependencies": { 972 | "@octokit/core": "^5.0.0" 973 | } 974 | }, 975 | "node_modules/@octokit/request": { 976 | "version": "8.1.3", 977 | "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.3.tgz", 978 | "integrity": "sha512-iUvXP4QmysS8kyE/a4AGwR0A+tHDVxgW6TmPd2ci8/Xc8KjlBtTKSDpZlUT5Y4S4Nu+eM8LvbOYjVAp/sz3Gpg==", 979 | "dependencies": { 980 | "@octokit/endpoint": "^9.0.0", 981 | "@octokit/request-error": "^5.0.0", 982 | "@octokit/types": "^12.0.0", 983 | "is-plain-object": "^5.0.0", 984 | "universal-user-agent": "^6.0.0" 985 | }, 986 | "engines": { 987 | "node": ">= 18" 988 | } 989 | }, 990 | "node_modules/@octokit/request-error": { 991 | "version": "5.0.1", 992 | "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", 993 | "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", 994 | "dependencies": { 995 | "@octokit/types": "^12.0.0", 996 | "deprecation": "^2.0.0", 997 | "once": "^1.4.0" 998 | }, 999 | "engines": { 1000 | "node": ">= 18" 1001 | } 1002 | }, 1003 | "node_modules/@octokit/rest": { 1004 | "version": "20.0.2", 1005 | "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", 1006 | "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", 1007 | "dependencies": { 1008 | "@octokit/core": "^5.0.0", 1009 | "@octokit/plugin-paginate-rest": "^9.0.0", 1010 | "@octokit/plugin-request-log": "^4.0.0", 1011 | "@octokit/plugin-rest-endpoint-methods": "^10.0.0" 1012 | }, 1013 | "engines": { 1014 | "node": ">= 18" 1015 | } 1016 | }, 1017 | "node_modules/@octokit/types": { 1018 | "version": "12.0.0", 1019 | "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz", 1020 | "integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==", 1021 | "dependencies": { 1022 | "@octokit/openapi-types": "^19.0.0" 1023 | } 1024 | }, 1025 | "node_modules/@octokit/webhooks": { 1026 | "version": "12.0.3", 1027 | "resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-12.0.3.tgz", 1028 | "integrity": "sha512-8iG+/yza7hwz1RrQ7i7uGpK2/tuItZxZq1aTmeg2TNp2xTUB8F8lZF/FcZvyyAxT8tpDMF74TjFGCDACkf1kAQ==", 1029 | "dependencies": { 1030 | "@octokit/request-error": "^5.0.0", 1031 | "@octokit/webhooks-methods": "^4.0.0", 1032 | "@octokit/webhooks-types": "7.1.0", 1033 | "aggregate-error": "^3.1.0" 1034 | }, 1035 | "engines": { 1036 | "node": ">= 18" 1037 | } 1038 | }, 1039 | "node_modules/@octokit/webhooks-definitions": { 1040 | "version": "3.67.3", 1041 | "resolved": "https://registry.npmjs.org/@octokit/webhooks-definitions/-/webhooks-definitions-3.67.3.tgz", 1042 | "integrity": "sha512-do4Z1r2OVhuI0ihJhQ8Hg+yPWnBYEBNuFNCrvtPKoYT1w81jD7pBXgGe86lYuuNirkDHb0Nxt+zt4O5GiFJfgA==", 1043 | "deprecated": "Use @octokit/webhooks-types, @octokit/webhooks-schemas, or @octokit/webhooks-examples instead. See https://github.com/octokit/webhooks/issues/447" 1044 | }, 1045 | "node_modules/@octokit/webhooks-methods": { 1046 | "version": "4.0.0", 1047 | "resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-4.0.0.tgz", 1048 | "integrity": "sha512-M8mwmTXp+VeolOS/kfRvsDdW+IO0qJ8kYodM/sAysk093q6ApgmBXwK1ZlUvAwXVrp/YVHp6aArj4auAxUAOFw==", 1049 | "engines": { 1050 | "node": ">= 18" 1051 | } 1052 | }, 1053 | "node_modules/@octokit/webhooks-types": { 1054 | "version": "7.1.0", 1055 | "resolved": "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-7.1.0.tgz", 1056 | "integrity": "sha512-y92CpG4kFFtBBjni8LHoV12IegJ+KFxLgKRengrVjKmGE5XMeCuGvlfRe75lTRrgXaG6XIWJlFpIDTlkoJsU8w==" 1057 | }, 1058 | "node_modules/@types/aws-lambda": { 1059 | "version": "8.10.124", 1060 | "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.124.tgz", 1061 | "integrity": "sha512-PHqK0SuAkFS3tZjceqRXecxxrWIN3VqTicuialtK2wZmvBy7H9WGc3u3+wOgaZB7N8SpSXDpWk9qa7eorpTStg==" 1062 | }, 1063 | "node_modules/@types/babel__traverse": { 1064 | "version": "7.20.3", 1065 | "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.3.tgz", 1066 | "integrity": "sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw==", 1067 | "dev": true, 1068 | "dependencies": { 1069 | "@babel/types": "^7.20.7" 1070 | } 1071 | }, 1072 | "node_modules/@types/btoa-lite": { 1073 | "version": "1.0.0", 1074 | "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz", 1075 | "integrity": "sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==" 1076 | }, 1077 | "node_modules/@types/diff": { 1078 | "version": "5.0.7", 1079 | "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.0.7.tgz", 1080 | "integrity": "sha512-adBosR2GntaQQiuHnfRN9HtxYpoHHJBcdyz7VSXhjpSAmtvIfu/S1fjTqwuIx/Ypba6LCZdfWIqPYx2BR5TneQ==", 1081 | "dev": true 1082 | }, 1083 | "node_modules/@types/jsonwebtoken": { 1084 | "version": "9.0.3", 1085 | "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", 1086 | "integrity": "sha512-b0jGiOgHtZ2jqdPgPnP6WLCXZk1T8p06A/vPGzUvxpFGgKMbjXJDjC5m52ErqBnIuWZFgGoIJyRdeG5AyreJjA==", 1087 | "dependencies": { 1088 | "@types/node": "*" 1089 | } 1090 | }, 1091 | "node_modules/@types/node": { 1092 | "version": "20.8.3", 1093 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.3.tgz", 1094 | "integrity": "sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw==" 1095 | }, 1096 | "node_modules/@types/node-fetch": { 1097 | "version": "2.6.6", 1098 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", 1099 | "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", 1100 | "dependencies": { 1101 | "@types/node": "*", 1102 | "form-data": "^4.0.0" 1103 | } 1104 | }, 1105 | "node_modules/@types/xml2js": { 1106 | "version": "0.4.13", 1107 | "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.13.tgz", 1108 | "integrity": "sha512-nuT42GzgoUa4zZgBoF4d+Zqc12/FlVxXCT4xU6j3RfqTFVQWrUAClI/0sNJ5ImM9Wv6KB42KMG2xsVMn4cSBzA==", 1109 | "dev": true, 1110 | "dependencies": { 1111 | "@types/node": "*" 1112 | } 1113 | }, 1114 | "node_modules/abort-controller": { 1115 | "version": "3.0.0", 1116 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 1117 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 1118 | "dependencies": { 1119 | "event-target-shim": "^5.0.0" 1120 | }, 1121 | "engines": { 1122 | "node": ">=6.5" 1123 | } 1124 | }, 1125 | "node_modules/agentkeepalive": { 1126 | "version": "4.5.0", 1127 | "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", 1128 | "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", 1129 | "dependencies": { 1130 | "humanize-ms": "^1.2.1" 1131 | }, 1132 | "engines": { 1133 | "node": ">= 8.0.0" 1134 | } 1135 | }, 1136 | "node_modules/aggregate-error": { 1137 | "version": "3.1.0", 1138 | "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", 1139 | "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", 1140 | "dependencies": { 1141 | "clean-stack": "^2.0.0", 1142 | "indent-string": "^4.0.0" 1143 | }, 1144 | "engines": { 1145 | "node": ">=8" 1146 | } 1147 | }, 1148 | "node_modules/ansi-styles": { 1149 | "version": "3.2.1", 1150 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 1151 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 1152 | "license": "MIT", 1153 | "dependencies": { 1154 | "color-convert": "^1.9.0" 1155 | }, 1156 | "engines": { 1157 | "node": ">=4" 1158 | } 1159 | }, 1160 | "node_modules/asap": { 1161 | "version": "2.0.6", 1162 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 1163 | "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", 1164 | "dev": true 1165 | }, 1166 | "node_modules/asynckit": { 1167 | "version": "0.4.0", 1168 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 1169 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 1170 | }, 1171 | "node_modules/basic-auth": { 1172 | "version": "2.0.1", 1173 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", 1174 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", 1175 | "dev": true, 1176 | "dependencies": { 1177 | "safe-buffer": "5.1.2" 1178 | }, 1179 | "engines": { 1180 | "node": ">= 0.8" 1181 | } 1182 | }, 1183 | "node_modules/basic-auth/node_modules/safe-buffer": { 1184 | "version": "5.1.2", 1185 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1186 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1187 | "dev": true 1188 | }, 1189 | "node_modules/before-after-hook": { 1190 | "version": "2.2.3", 1191 | "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", 1192 | "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" 1193 | }, 1194 | "node_modules/bottleneck": { 1195 | "version": "2.19.5", 1196 | "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", 1197 | "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" 1198 | }, 1199 | "node_modules/btoa-lite": { 1200 | "version": "1.0.0", 1201 | "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", 1202 | "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==" 1203 | }, 1204 | "node_modules/buffer-equal-constant-time": { 1205 | "version": "1.0.1", 1206 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 1207 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" 1208 | }, 1209 | "node_modules/call-bind": { 1210 | "version": "1.0.2", 1211 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 1212 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 1213 | "dev": true, 1214 | "dependencies": { 1215 | "function-bind": "^1.1.1", 1216 | "get-intrinsic": "^1.0.2" 1217 | }, 1218 | "funding": { 1219 | "url": "https://github.com/sponsors/ljharb" 1220 | } 1221 | }, 1222 | "node_modules/chalk": { 1223 | "version": "5.3.0", 1224 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", 1225 | "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", 1226 | "license": "MIT", 1227 | "engines": { 1228 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 1229 | }, 1230 | "funding": { 1231 | "url": "https://github.com/chalk/chalk?sponsor=1" 1232 | } 1233 | }, 1234 | "node_modules/clean-stack": { 1235 | "version": "2.2.0", 1236 | "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", 1237 | "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", 1238 | "engines": { 1239 | "node": ">=6" 1240 | } 1241 | }, 1242 | "node_modules/color-convert": { 1243 | "version": "1.9.3", 1244 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 1245 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 1246 | "license": "MIT", 1247 | "dependencies": { 1248 | "color-name": "1.1.3" 1249 | } 1250 | }, 1251 | "node_modules/color-name": { 1252 | "version": "1.1.3", 1253 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 1254 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", 1255 | "license": "MIT" 1256 | }, 1257 | "node_modules/combined-stream": { 1258 | "version": "1.0.8", 1259 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 1260 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 1261 | "dependencies": { 1262 | "delayed-stream": "~1.0.0" 1263 | }, 1264 | "engines": { 1265 | "node": ">= 0.8" 1266 | } 1267 | }, 1268 | "node_modules/commander": { 1269 | "version": "2.20.3", 1270 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 1271 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 1272 | "dev": true 1273 | }, 1274 | "node_modules/component-emitter": { 1275 | "version": "1.3.0", 1276 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", 1277 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", 1278 | "dev": true 1279 | }, 1280 | "node_modules/cookiejar": { 1281 | "version": "2.1.4", 1282 | "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", 1283 | "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", 1284 | "dev": true 1285 | }, 1286 | "node_modules/csv-writer": { 1287 | "version": "1.6.0", 1288 | "resolved": "https://registry.npmjs.org/csv-writer/-/csv-writer-1.6.0.tgz", 1289 | "integrity": "sha512-NOx7YDFWEsM/fTRAJjRpPp8t+MKRVvniAg9wQlUKx20MFrPs73WLJhFf5iteqrxNYnsy924K3Iroh3yNHeYd2g==", 1290 | "dev": true 1291 | }, 1292 | "node_modules/debug": { 1293 | "version": "2.6.9", 1294 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1295 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1296 | "dev": true, 1297 | "dependencies": { 1298 | "ms": "2.0.0" 1299 | } 1300 | }, 1301 | "node_modules/debug/node_modules/ms": { 1302 | "version": "2.0.0", 1303 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1304 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", 1305 | "dev": true 1306 | }, 1307 | "node_modules/delayed-stream": { 1308 | "version": "1.0.0", 1309 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 1310 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 1311 | "engines": { 1312 | "node": ">=0.4.0" 1313 | } 1314 | }, 1315 | "node_modules/depd": { 1316 | "version": "2.0.0", 1317 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 1318 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 1319 | "dev": true, 1320 | "engines": { 1321 | "node": ">= 0.8" 1322 | } 1323 | }, 1324 | "node_modules/deprecation": { 1325 | "version": "2.3.1", 1326 | "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", 1327 | "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" 1328 | }, 1329 | "node_modules/dezalgo": { 1330 | "version": "1.0.4", 1331 | "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", 1332 | "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", 1333 | "dev": true, 1334 | "dependencies": { 1335 | "asap": "^2.0.0", 1336 | "wrappy": "1" 1337 | } 1338 | }, 1339 | "node_modules/diff": { 1340 | "version": "5.1.0", 1341 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", 1342 | "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", 1343 | "engines": { 1344 | "node": ">=0.3.1" 1345 | } 1346 | }, 1347 | "node_modules/dotenv": { 1348 | "version": "16.3.1", 1349 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", 1350 | "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", 1351 | "engines": { 1352 | "node": ">=12" 1353 | }, 1354 | "funding": { 1355 | "url": "https://github.com/motdotla/dotenv?sponsor=1" 1356 | } 1357 | }, 1358 | "node_modules/ecdsa-sig-formatter": { 1359 | "version": "1.0.11", 1360 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 1361 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 1362 | "dependencies": { 1363 | "safe-buffer": "^5.0.1" 1364 | } 1365 | }, 1366 | "node_modules/ee-first": { 1367 | "version": "1.1.1", 1368 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 1369 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", 1370 | "dev": true 1371 | }, 1372 | "node_modules/esbuild": { 1373 | "version": "0.23.1", 1374 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", 1375 | "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", 1376 | "dev": true, 1377 | "hasInstallScript": true, 1378 | "license": "MIT", 1379 | "bin": { 1380 | "esbuild": "bin/esbuild" 1381 | }, 1382 | "engines": { 1383 | "node": ">=18" 1384 | }, 1385 | "optionalDependencies": { 1386 | "@esbuild/aix-ppc64": "0.23.1", 1387 | "@esbuild/android-arm": "0.23.1", 1388 | "@esbuild/android-arm64": "0.23.1", 1389 | "@esbuild/android-x64": "0.23.1", 1390 | "@esbuild/darwin-arm64": "0.23.1", 1391 | "@esbuild/darwin-x64": "0.23.1", 1392 | "@esbuild/freebsd-arm64": "0.23.1", 1393 | "@esbuild/freebsd-x64": "0.23.1", 1394 | "@esbuild/linux-arm": "0.23.1", 1395 | "@esbuild/linux-arm64": "0.23.1", 1396 | "@esbuild/linux-ia32": "0.23.1", 1397 | "@esbuild/linux-loong64": "0.23.1", 1398 | "@esbuild/linux-mips64el": "0.23.1", 1399 | "@esbuild/linux-ppc64": "0.23.1", 1400 | "@esbuild/linux-riscv64": "0.23.1", 1401 | "@esbuild/linux-s390x": "0.23.1", 1402 | "@esbuild/linux-x64": "0.23.1", 1403 | "@esbuild/netbsd-x64": "0.23.1", 1404 | "@esbuild/openbsd-arm64": "0.23.1", 1405 | "@esbuild/openbsd-x64": "0.23.1", 1406 | "@esbuild/sunos-x64": "0.23.1", 1407 | "@esbuild/win32-arm64": "0.23.1", 1408 | "@esbuild/win32-ia32": "0.23.1", 1409 | "@esbuild/win32-x64": "0.23.1" 1410 | } 1411 | }, 1412 | "node_modules/escape-string-regexp": { 1413 | "version": "1.0.5", 1414 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 1415 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", 1416 | "license": "MIT", 1417 | "engines": { 1418 | "node": ">=0.8.0" 1419 | } 1420 | }, 1421 | "node_modules/event-target-shim": { 1422 | "version": "5.0.1", 1423 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 1424 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", 1425 | "engines": { 1426 | "node": ">=6" 1427 | } 1428 | }, 1429 | "node_modules/eventsource": { 1430 | "version": "1.1.2", 1431 | "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz", 1432 | "integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==", 1433 | "dev": true, 1434 | "engines": { 1435 | "node": ">=0.12.0" 1436 | } 1437 | }, 1438 | "node_modules/fast-safe-stringify": { 1439 | "version": "2.1.1", 1440 | "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", 1441 | "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", 1442 | "dev": true 1443 | }, 1444 | "node_modules/form-data": { 1445 | "version": "4.0.0", 1446 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 1447 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 1448 | "dependencies": { 1449 | "asynckit": "^0.4.0", 1450 | "combined-stream": "^1.0.8", 1451 | "mime-types": "^2.1.12" 1452 | }, 1453 | "engines": { 1454 | "node": ">= 6" 1455 | } 1456 | }, 1457 | "node_modules/form-data-encoder": { 1458 | "version": "1.7.2", 1459 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", 1460 | "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" 1461 | }, 1462 | "node_modules/formdata-node": { 1463 | "version": "4.4.1", 1464 | "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", 1465 | "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", 1466 | "dependencies": { 1467 | "node-domexception": "1.0.0", 1468 | "web-streams-polyfill": "4.0.0-beta.3" 1469 | }, 1470 | "engines": { 1471 | "node": ">= 12.20" 1472 | } 1473 | }, 1474 | "node_modules/formidable": { 1475 | "version": "2.1.2", 1476 | "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", 1477 | "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", 1478 | "dev": true, 1479 | "dependencies": { 1480 | "dezalgo": "^1.0.4", 1481 | "hexoid": "^1.0.0", 1482 | "once": "^1.4.0", 1483 | "qs": "^6.11.0" 1484 | }, 1485 | "funding": { 1486 | "url": "https://ko-fi.com/tunnckoCore/commissions" 1487 | } 1488 | }, 1489 | "node_modules/fsevents": { 1490 | "version": "2.3.3", 1491 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1492 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1493 | "dev": true, 1494 | "hasInstallScript": true, 1495 | "license": "MIT", 1496 | "optional": true, 1497 | "os": [ 1498 | "darwin" 1499 | ], 1500 | "engines": { 1501 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1502 | } 1503 | }, 1504 | "node_modules/function-bind": { 1505 | "version": "1.1.1", 1506 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1507 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 1508 | "dev": true 1509 | }, 1510 | "node_modules/get-intrinsic": { 1511 | "version": "1.2.1", 1512 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", 1513 | "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", 1514 | "dev": true, 1515 | "dependencies": { 1516 | "function-bind": "^1.1.1", 1517 | "has": "^1.0.3", 1518 | "has-proto": "^1.0.1", 1519 | "has-symbols": "^1.0.3" 1520 | }, 1521 | "funding": { 1522 | "url": "https://github.com/sponsors/ljharb" 1523 | } 1524 | }, 1525 | "node_modules/get-tsconfig": { 1526 | "version": "4.8.1", 1527 | "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", 1528 | "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", 1529 | "dev": true, 1530 | "license": "MIT", 1531 | "dependencies": { 1532 | "resolve-pkg-maps": "^1.0.0" 1533 | }, 1534 | "funding": { 1535 | "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" 1536 | } 1537 | }, 1538 | "node_modules/globals": { 1539 | "version": "11.12.0", 1540 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 1541 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 1542 | "engines": { 1543 | "node": ">=4" 1544 | } 1545 | }, 1546 | "node_modules/gpt-tokenizer": { 1547 | "version": "2.1.2", 1548 | "resolved": "https://registry.npmjs.org/gpt-tokenizer/-/gpt-tokenizer-2.1.2.tgz", 1549 | "integrity": "sha512-HSuI5d6uey+c7x/VzQlPfCoGrfLyAc28vxWofKbjR9PJHm0AjQGSWkKw/OJnb+8S1g7nzgRsf0WH3dK+NNWYbg==", 1550 | "dependencies": { 1551 | "rfc4648": "^1.5.2" 1552 | } 1553 | }, 1554 | "node_modules/groq-sdk": { 1555 | "version": "0.8.0", 1556 | "resolved": "https://registry.npmjs.org/groq-sdk/-/groq-sdk-0.8.0.tgz", 1557 | "integrity": "sha512-hSgCjZCkoM4CY/TWfsaNlh512svWRR2td4HGpmEV8MbVEVrxZARJq5BHt8gbEF9Gex092/X7VJvaQpha0dIC8g==", 1558 | "license": "Apache-2.0", 1559 | "dependencies": { 1560 | "@types/node": "^18.11.18", 1561 | "@types/node-fetch": "^2.6.4", 1562 | "abort-controller": "^3.0.0", 1563 | "agentkeepalive": "^4.2.1", 1564 | "form-data-encoder": "1.7.2", 1565 | "formdata-node": "^4.3.2", 1566 | "node-fetch": "^2.6.7" 1567 | } 1568 | }, 1569 | "node_modules/groq-sdk/node_modules/@types/node": { 1570 | "version": "18.19.64", 1571 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.64.tgz", 1572 | "integrity": "sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==", 1573 | "license": "MIT", 1574 | "dependencies": { 1575 | "undici-types": "~5.26.4" 1576 | } 1577 | }, 1578 | "node_modules/has": { 1579 | "version": "1.0.4", 1580 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", 1581 | "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", 1582 | "dev": true, 1583 | "engines": { 1584 | "node": ">= 0.4.0" 1585 | } 1586 | }, 1587 | "node_modules/has-flag": { 1588 | "version": "3.0.0", 1589 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1590 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", 1591 | "license": "MIT", 1592 | "engines": { 1593 | "node": ">=4" 1594 | } 1595 | }, 1596 | "node_modules/has-proto": { 1597 | "version": "1.0.1", 1598 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", 1599 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", 1600 | "dev": true, 1601 | "engines": { 1602 | "node": ">= 0.4" 1603 | }, 1604 | "funding": { 1605 | "url": "https://github.com/sponsors/ljharb" 1606 | } 1607 | }, 1608 | "node_modules/has-symbols": { 1609 | "version": "1.0.3", 1610 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 1611 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 1612 | "dev": true, 1613 | "engines": { 1614 | "node": ">= 0.4" 1615 | }, 1616 | "funding": { 1617 | "url": "https://github.com/sponsors/ljharb" 1618 | } 1619 | }, 1620 | "node_modules/hexoid": { 1621 | "version": "1.0.0", 1622 | "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", 1623 | "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", 1624 | "dev": true, 1625 | "engines": { 1626 | "node": ">=8" 1627 | } 1628 | }, 1629 | "node_modules/humanize-ms": { 1630 | "version": "1.2.1", 1631 | "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", 1632 | "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", 1633 | "dependencies": { 1634 | "ms": "^2.0.0" 1635 | } 1636 | }, 1637 | "node_modules/indent-string": { 1638 | "version": "4.0.0", 1639 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", 1640 | "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", 1641 | "engines": { 1642 | "node": ">=8" 1643 | } 1644 | }, 1645 | "node_modules/inherits": { 1646 | "version": "2.0.4", 1647 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1648 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1649 | "dev": true 1650 | }, 1651 | "node_modules/is-plain-object": { 1652 | "version": "5.0.0", 1653 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", 1654 | "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", 1655 | "engines": { 1656 | "node": ">=0.10.0" 1657 | } 1658 | }, 1659 | "node_modules/js-tokens": { 1660 | "version": "4.0.0", 1661 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1662 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 1663 | }, 1664 | "node_modules/jsesc": { 1665 | "version": "2.5.2", 1666 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 1667 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", 1668 | "bin": { 1669 | "jsesc": "bin/jsesc" 1670 | }, 1671 | "engines": { 1672 | "node": ">=4" 1673 | } 1674 | }, 1675 | "node_modules/jsonwebtoken": { 1676 | "version": "9.0.2", 1677 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", 1678 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", 1679 | "dependencies": { 1680 | "jws": "^3.2.2", 1681 | "lodash.includes": "^4.3.0", 1682 | "lodash.isboolean": "^3.0.3", 1683 | "lodash.isinteger": "^4.0.4", 1684 | "lodash.isnumber": "^3.0.3", 1685 | "lodash.isplainobject": "^4.0.6", 1686 | "lodash.isstring": "^4.0.1", 1687 | "lodash.once": "^4.0.0", 1688 | "ms": "^2.1.1", 1689 | "semver": "^7.5.4" 1690 | }, 1691 | "engines": { 1692 | "node": ">=12", 1693 | "npm": ">=6" 1694 | } 1695 | }, 1696 | "node_modules/jwa": { 1697 | "version": "1.4.1", 1698 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 1699 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 1700 | "dependencies": { 1701 | "buffer-equal-constant-time": "1.0.1", 1702 | "ecdsa-sig-formatter": "1.0.11", 1703 | "safe-buffer": "^5.0.1" 1704 | } 1705 | }, 1706 | "node_modules/jws": { 1707 | "version": "3.2.2", 1708 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 1709 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 1710 | "dependencies": { 1711 | "jwa": "^1.4.1", 1712 | "safe-buffer": "^5.0.1" 1713 | } 1714 | }, 1715 | "node_modules/lodash.includes": { 1716 | "version": "4.3.0", 1717 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 1718 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" 1719 | }, 1720 | "node_modules/lodash.isboolean": { 1721 | "version": "3.0.3", 1722 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 1723 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" 1724 | }, 1725 | "node_modules/lodash.isinteger": { 1726 | "version": "4.0.4", 1727 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 1728 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" 1729 | }, 1730 | "node_modules/lodash.isnumber": { 1731 | "version": "3.0.3", 1732 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 1733 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" 1734 | }, 1735 | "node_modules/lodash.isplainobject": { 1736 | "version": "4.0.6", 1737 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 1738 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" 1739 | }, 1740 | "node_modules/lodash.isstring": { 1741 | "version": "4.0.1", 1742 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 1743 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" 1744 | }, 1745 | "node_modules/lodash.once": { 1746 | "version": "4.1.1", 1747 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 1748 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" 1749 | }, 1750 | "node_modules/lru-cache": { 1751 | "version": "10.0.1", 1752 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", 1753 | "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", 1754 | "engines": { 1755 | "node": "14 || >=16.14" 1756 | } 1757 | }, 1758 | "node_modules/methods": { 1759 | "version": "1.1.2", 1760 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1761 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 1762 | "dev": true, 1763 | "engines": { 1764 | "node": ">= 0.6" 1765 | } 1766 | }, 1767 | "node_modules/mime": { 1768 | "version": "2.6.0", 1769 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", 1770 | "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", 1771 | "dev": true, 1772 | "bin": { 1773 | "mime": "cli.js" 1774 | }, 1775 | "engines": { 1776 | "node": ">=4.0.0" 1777 | } 1778 | }, 1779 | "node_modules/mime-db": { 1780 | "version": "1.52.0", 1781 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1782 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1783 | "engines": { 1784 | "node": ">= 0.6" 1785 | } 1786 | }, 1787 | "node_modules/mime-types": { 1788 | "version": "2.1.35", 1789 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1790 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1791 | "dependencies": { 1792 | "mime-db": "1.52.0" 1793 | }, 1794 | "engines": { 1795 | "node": ">= 0.6" 1796 | } 1797 | }, 1798 | "node_modules/morgan": { 1799 | "version": "1.10.0", 1800 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", 1801 | "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", 1802 | "dev": true, 1803 | "dependencies": { 1804 | "basic-auth": "~2.0.1", 1805 | "debug": "2.6.9", 1806 | "depd": "~2.0.0", 1807 | "on-finished": "~2.3.0", 1808 | "on-headers": "~1.0.2" 1809 | }, 1810 | "engines": { 1811 | "node": ">= 0.8.0" 1812 | } 1813 | }, 1814 | "node_modules/ms": { 1815 | "version": "2.1.3", 1816 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1817 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1818 | }, 1819 | "node_modules/node-domexception": { 1820 | "version": "1.0.0", 1821 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", 1822 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", 1823 | "funding": [ 1824 | { 1825 | "type": "github", 1826 | "url": "https://github.com/sponsors/jimmywarting" 1827 | }, 1828 | { 1829 | "type": "github", 1830 | "url": "https://paypal.me/jimmywarting" 1831 | } 1832 | ], 1833 | "engines": { 1834 | "node": ">=10.5.0" 1835 | } 1836 | }, 1837 | "node_modules/node-fetch": { 1838 | "version": "2.7.0", 1839 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 1840 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 1841 | "dependencies": { 1842 | "whatwg-url": "^5.0.0" 1843 | }, 1844 | "engines": { 1845 | "node": "4.x || >=6.0.0" 1846 | }, 1847 | "peerDependencies": { 1848 | "encoding": "^0.1.0" 1849 | }, 1850 | "peerDependenciesMeta": { 1851 | "encoding": { 1852 | "optional": true 1853 | } 1854 | } 1855 | }, 1856 | "node_modules/object-inspect": { 1857 | "version": "1.12.3", 1858 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", 1859 | "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", 1860 | "dev": true, 1861 | "funding": { 1862 | "url": "https://github.com/sponsors/ljharb" 1863 | } 1864 | }, 1865 | "node_modules/octokit": { 1866 | "version": "3.1.1", 1867 | "resolved": "https://registry.npmjs.org/octokit/-/octokit-3.1.1.tgz", 1868 | "integrity": "sha512-AKJs5XYs7iAh7bskkYpxhUIpsYZdLqjnlnqrN5s9FFZuJ/a6ATUHivGpUKDpGB/xa+LGDtG9Lu8bOCfPM84vHQ==", 1869 | "dependencies": { 1870 | "@octokit/app": "^14.0.0", 1871 | "@octokit/core": "^5.0.0", 1872 | "@octokit/oauth-app": "^6.0.0", 1873 | "@octokit/plugin-paginate-graphql": "^4.0.0", 1874 | "@octokit/plugin-paginate-rest": "^9.0.0", 1875 | "@octokit/plugin-rest-endpoint-methods": "^10.0.0", 1876 | "@octokit/plugin-retry": "^6.0.0", 1877 | "@octokit/plugin-throttling": "^8.0.0", 1878 | "@octokit/request-error": "^5.0.0", 1879 | "@octokit/types": "^12.0.0" 1880 | }, 1881 | "engines": { 1882 | "node": ">= 18" 1883 | } 1884 | }, 1885 | "node_modules/on-finished": { 1886 | "version": "2.3.0", 1887 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1888 | "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", 1889 | "dev": true, 1890 | "dependencies": { 1891 | "ee-first": "1.1.1" 1892 | }, 1893 | "engines": { 1894 | "node": ">= 0.8" 1895 | } 1896 | }, 1897 | "node_modules/on-headers": { 1898 | "version": "1.0.2", 1899 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", 1900 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", 1901 | "dev": true, 1902 | "engines": { 1903 | "node": ">= 0.8" 1904 | } 1905 | }, 1906 | "node_modules/once": { 1907 | "version": "1.4.0", 1908 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1909 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1910 | "dependencies": { 1911 | "wrappy": "1" 1912 | } 1913 | }, 1914 | "node_modules/qs": { 1915 | "version": "6.11.2", 1916 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", 1917 | "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", 1918 | "dev": true, 1919 | "dependencies": { 1920 | "side-channel": "^1.0.4" 1921 | }, 1922 | "engines": { 1923 | "node": ">=0.6" 1924 | }, 1925 | "funding": { 1926 | "url": "https://github.com/sponsors/ljharb" 1927 | } 1928 | }, 1929 | "node_modules/readable-stream": { 1930 | "version": "3.6.2", 1931 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 1932 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 1933 | "dev": true, 1934 | "dependencies": { 1935 | "inherits": "^2.0.3", 1936 | "string_decoder": "^1.1.1", 1937 | "util-deprecate": "^1.0.1" 1938 | }, 1939 | "engines": { 1940 | "node": ">= 6" 1941 | } 1942 | }, 1943 | "node_modules/resolve-pkg-maps": { 1944 | "version": "1.0.0", 1945 | "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", 1946 | "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", 1947 | "dev": true, 1948 | "license": "MIT", 1949 | "funding": { 1950 | "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" 1951 | } 1952 | }, 1953 | "node_modules/rfc4648": { 1954 | "version": "1.5.2", 1955 | "resolved": "https://registry.npmjs.org/rfc4648/-/rfc4648-1.5.2.tgz", 1956 | "integrity": "sha512-tLOizhR6YGovrEBLatX1sdcuhoSCXddw3mqNVAcKxGJ+J0hFeJ+SjeWCv5UPA/WU3YzWPPuCVYgXBKZUPGpKtg==" 1957 | }, 1958 | "node_modules/safe-buffer": { 1959 | "version": "5.2.1", 1960 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1961 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1962 | "funding": [ 1963 | { 1964 | "type": "github", 1965 | "url": "https://github.com/sponsors/feross" 1966 | }, 1967 | { 1968 | "type": "patreon", 1969 | "url": "https://www.patreon.com/feross" 1970 | }, 1971 | { 1972 | "type": "consulting", 1973 | "url": "https://feross.org/support" 1974 | } 1975 | ] 1976 | }, 1977 | "node_modules/sax": { 1978 | "version": "1.3.0", 1979 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", 1980 | "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" 1981 | }, 1982 | "node_modules/semver": { 1983 | "version": "7.5.4", 1984 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 1985 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 1986 | "dependencies": { 1987 | "lru-cache": "^6.0.0" 1988 | }, 1989 | "bin": { 1990 | "semver": "bin/semver.js" 1991 | }, 1992 | "engines": { 1993 | "node": ">=10" 1994 | } 1995 | }, 1996 | "node_modules/semver/node_modules/lru-cache": { 1997 | "version": "6.0.0", 1998 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1999 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 2000 | "dependencies": { 2001 | "yallist": "^4.0.0" 2002 | }, 2003 | "engines": { 2004 | "node": ">=10" 2005 | } 2006 | }, 2007 | "node_modules/side-channel": { 2008 | "version": "1.0.4", 2009 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 2010 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 2011 | "dev": true, 2012 | "dependencies": { 2013 | "call-bind": "^1.0.0", 2014 | "get-intrinsic": "^1.0.2", 2015 | "object-inspect": "^1.9.0" 2016 | }, 2017 | "funding": { 2018 | "url": "https://github.com/sponsors/ljharb" 2019 | } 2020 | }, 2021 | "node_modules/smee-client": { 2022 | "version": "1.2.3", 2023 | "resolved": "https://registry.npmjs.org/smee-client/-/smee-client-1.2.3.tgz", 2024 | "integrity": "sha512-uDrU8u9/Ln7aRXyzGHgVaNUS8onHZZeSwQjCdkMoSL7U85xI+l+Y2NgjibkMJAyXkW7IAbb8rw9RMHIjS6lAwA==", 2025 | "dev": true, 2026 | "dependencies": { 2027 | "commander": "^2.19.0", 2028 | "eventsource": "^1.1.0", 2029 | "morgan": "^1.9.1", 2030 | "superagent": "^7.1.3", 2031 | "validator": "^13.7.0" 2032 | }, 2033 | "bin": { 2034 | "smee": "bin/smee.js" 2035 | } 2036 | }, 2037 | "node_modules/string_decoder": { 2038 | "version": "1.3.0", 2039 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 2040 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 2041 | "dev": true, 2042 | "dependencies": { 2043 | "safe-buffer": "~5.2.0" 2044 | } 2045 | }, 2046 | "node_modules/superagent": { 2047 | "version": "7.1.5", 2048 | "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.5.tgz", 2049 | "integrity": "sha512-HQYyGuDRFGmZ6GNC4hq2f37KnsY9Lr0/R1marNZTgMweVDQLTLJJ6DGQ9Tj/xVVs5HEnop9EMmTbywb5P30aqw==", 2050 | "dev": true, 2051 | "dependencies": { 2052 | "component-emitter": "^1.3.0", 2053 | "cookiejar": "^2.1.3", 2054 | "debug": "^4.3.4", 2055 | "fast-safe-stringify": "^2.1.1", 2056 | "form-data": "^4.0.0", 2057 | "formidable": "^2.0.1", 2058 | "methods": "^1.1.2", 2059 | "mime": "^2.5.0", 2060 | "qs": "^6.10.3", 2061 | "readable-stream": "^3.6.0", 2062 | "semver": "^7.3.7" 2063 | }, 2064 | "engines": { 2065 | "node": ">=6.4.0 <13 || >=14" 2066 | } 2067 | }, 2068 | "node_modules/superagent/node_modules/debug": { 2069 | "version": "4.3.4", 2070 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 2071 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 2072 | "dev": true, 2073 | "dependencies": { 2074 | "ms": "2.1.2" 2075 | }, 2076 | "engines": { 2077 | "node": ">=6.0" 2078 | }, 2079 | "peerDependenciesMeta": { 2080 | "supports-color": { 2081 | "optional": true 2082 | } 2083 | } 2084 | }, 2085 | "node_modules/superagent/node_modules/ms": { 2086 | "version": "2.1.2", 2087 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2088 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 2089 | "dev": true 2090 | }, 2091 | "node_modules/supports-color": { 2092 | "version": "5.5.0", 2093 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 2094 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 2095 | "license": "MIT", 2096 | "dependencies": { 2097 | "has-flag": "^3.0.0" 2098 | }, 2099 | "engines": { 2100 | "node": ">=4" 2101 | } 2102 | }, 2103 | "node_modules/to-fast-properties": { 2104 | "version": "2.0.0", 2105 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 2106 | "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", 2107 | "engines": { 2108 | "node": ">=4" 2109 | } 2110 | }, 2111 | "node_modules/tr46": { 2112 | "version": "0.0.3", 2113 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 2114 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 2115 | }, 2116 | "node_modules/tsx": { 2117 | "version": "4.19.2", 2118 | "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", 2119 | "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", 2120 | "dev": true, 2121 | "license": "MIT", 2122 | "dependencies": { 2123 | "esbuild": "~0.23.0", 2124 | "get-tsconfig": "^4.7.5" 2125 | }, 2126 | "bin": { 2127 | "tsx": "dist/cli.mjs" 2128 | }, 2129 | "engines": { 2130 | "node": ">=18.0.0" 2131 | }, 2132 | "optionalDependencies": { 2133 | "fsevents": "~2.3.3" 2134 | } 2135 | }, 2136 | "node_modules/typescript": { 2137 | "version": "5.2.2", 2138 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", 2139 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", 2140 | "dev": true, 2141 | "bin": { 2142 | "tsc": "bin/tsc", 2143 | "tsserver": "bin/tsserver" 2144 | }, 2145 | "engines": { 2146 | "node": ">=14.17" 2147 | } 2148 | }, 2149 | "node_modules/undici-types": { 2150 | "version": "5.26.5", 2151 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 2152 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 2153 | "license": "MIT" 2154 | }, 2155 | "node_modules/universal-github-app-jwt": { 2156 | "version": "1.1.1", 2157 | "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.1.tgz", 2158 | "integrity": "sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==", 2159 | "dependencies": { 2160 | "@types/jsonwebtoken": "^9.0.0", 2161 | "jsonwebtoken": "^9.0.0" 2162 | } 2163 | }, 2164 | "node_modules/universal-user-agent": { 2165 | "version": "6.0.0", 2166 | "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", 2167 | "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" 2168 | }, 2169 | "node_modules/util-deprecate": { 2170 | "version": "1.0.2", 2171 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2172 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 2173 | "dev": true 2174 | }, 2175 | "node_modules/validator": { 2176 | "version": "13.11.0", 2177 | "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", 2178 | "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", 2179 | "dev": true, 2180 | "engines": { 2181 | "node": ">= 0.10" 2182 | } 2183 | }, 2184 | "node_modules/web-streams-polyfill": { 2185 | "version": "4.0.0-beta.3", 2186 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", 2187 | "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", 2188 | "engines": { 2189 | "node": ">= 14" 2190 | } 2191 | }, 2192 | "node_modules/webidl-conversions": { 2193 | "version": "3.0.1", 2194 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 2195 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 2196 | }, 2197 | "node_modules/whatwg-url": { 2198 | "version": "5.0.0", 2199 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 2200 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 2201 | "dependencies": { 2202 | "tr46": "~0.0.3", 2203 | "webidl-conversions": "^3.0.0" 2204 | } 2205 | }, 2206 | "node_modules/wrappy": { 2207 | "version": "1.0.2", 2208 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2209 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 2210 | }, 2211 | "node_modules/xml2js": { 2212 | "version": "0.6.2", 2213 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", 2214 | "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", 2215 | "dependencies": { 2216 | "sax": ">=0.6.0", 2217 | "xmlbuilder": "~11.0.0" 2218 | }, 2219 | "engines": { 2220 | "node": ">=4.0.0" 2221 | } 2222 | }, 2223 | "node_modules/xmlbuilder": { 2224 | "version": "11.0.1", 2225 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 2226 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", 2227 | "engines": { 2228 | "node": ">=4.0" 2229 | } 2230 | }, 2231 | "node_modules/yallist": { 2232 | "version": "4.0.0", 2233 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 2234 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 2235 | } 2236 | }, 2237 | "dependencies": { 2238 | "@babel/code-frame": { 2239 | "version": "7.22.13", 2240 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", 2241 | "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", 2242 | "requires": { 2243 | "@babel/highlight": "^7.22.13", 2244 | "chalk": "^2.4.2" 2245 | }, 2246 | "dependencies": { 2247 | "chalk": { 2248 | "version": "2.4.2", 2249 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 2250 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 2251 | "requires": { 2252 | "ansi-styles": "^3.2.1", 2253 | "escape-string-regexp": "^1.0.5", 2254 | "supports-color": "^5.3.0" 2255 | } 2256 | } 2257 | } 2258 | }, 2259 | "@babel/generator": { 2260 | "version": "7.23.0", 2261 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", 2262 | "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", 2263 | "requires": { 2264 | "@babel/types": "^7.23.0", 2265 | "@jridgewell/gen-mapping": "^0.3.2", 2266 | "@jridgewell/trace-mapping": "^0.3.17", 2267 | "jsesc": "^2.5.1" 2268 | } 2269 | }, 2270 | "@babel/helper-environment-visitor": { 2271 | "version": "7.22.20", 2272 | "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", 2273 | "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" 2274 | }, 2275 | "@babel/helper-function-name": { 2276 | "version": "7.23.0", 2277 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", 2278 | "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", 2279 | "requires": { 2280 | "@babel/template": "^7.22.15", 2281 | "@babel/types": "^7.23.0" 2282 | } 2283 | }, 2284 | "@babel/helper-hoist-variables": { 2285 | "version": "7.22.5", 2286 | "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", 2287 | "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", 2288 | "requires": { 2289 | "@babel/types": "^7.22.5" 2290 | } 2291 | }, 2292 | "@babel/helper-split-export-declaration": { 2293 | "version": "7.22.6", 2294 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", 2295 | "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", 2296 | "requires": { 2297 | "@babel/types": "^7.22.5" 2298 | } 2299 | }, 2300 | "@babel/helper-string-parser": { 2301 | "version": "7.22.5", 2302 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", 2303 | "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" 2304 | }, 2305 | "@babel/helper-validator-identifier": { 2306 | "version": "7.22.20", 2307 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", 2308 | "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" 2309 | }, 2310 | "@babel/highlight": { 2311 | "version": "7.22.20", 2312 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", 2313 | "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", 2314 | "requires": { 2315 | "@babel/helper-validator-identifier": "^7.22.20", 2316 | "chalk": "^2.4.2", 2317 | "js-tokens": "^4.0.0" 2318 | }, 2319 | "dependencies": { 2320 | "chalk": { 2321 | "version": "2.4.2", 2322 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 2323 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 2324 | "requires": { 2325 | "ansi-styles": "^3.2.1", 2326 | "escape-string-regexp": "^1.0.5", 2327 | "supports-color": "^5.3.0" 2328 | } 2329 | } 2330 | } 2331 | }, 2332 | "@babel/parser": { 2333 | "version": "7.23.0", 2334 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", 2335 | "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==" 2336 | }, 2337 | "@babel/template": { 2338 | "version": "7.22.15", 2339 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", 2340 | "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", 2341 | "requires": { 2342 | "@babel/code-frame": "^7.22.13", 2343 | "@babel/parser": "^7.22.15", 2344 | "@babel/types": "^7.22.15" 2345 | } 2346 | }, 2347 | "@babel/traverse": { 2348 | "version": "7.23.2", 2349 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", 2350 | "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", 2351 | "requires": { 2352 | "@babel/code-frame": "^7.22.13", 2353 | "@babel/generator": "^7.23.0", 2354 | "@babel/helper-environment-visitor": "^7.22.20", 2355 | "@babel/helper-function-name": "^7.23.0", 2356 | "@babel/helper-hoist-variables": "^7.22.5", 2357 | "@babel/helper-split-export-declaration": "^7.22.6", 2358 | "@babel/parser": "^7.23.0", 2359 | "@babel/types": "^7.23.0", 2360 | "debug": "^4.1.0", 2361 | "globals": "^11.1.0" 2362 | }, 2363 | "dependencies": { 2364 | "debug": { 2365 | "version": "4.3.4", 2366 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 2367 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 2368 | "requires": { 2369 | "ms": "2.1.2" 2370 | } 2371 | }, 2372 | "ms": { 2373 | "version": "2.1.2", 2374 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2375 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 2376 | } 2377 | } 2378 | }, 2379 | "@babel/types": { 2380 | "version": "7.23.0", 2381 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", 2382 | "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", 2383 | "requires": { 2384 | "@babel/helper-string-parser": "^7.22.5", 2385 | "@babel/helper-validator-identifier": "^7.22.20", 2386 | "to-fast-properties": "^2.0.0" 2387 | } 2388 | }, 2389 | "@esbuild/aix-ppc64": { 2390 | "version": "0.23.1", 2391 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", 2392 | "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", 2393 | "dev": true, 2394 | "optional": true 2395 | }, 2396 | "@esbuild/android-arm": { 2397 | "version": "0.23.1", 2398 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", 2399 | "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", 2400 | "dev": true, 2401 | "optional": true 2402 | }, 2403 | "@esbuild/android-arm64": { 2404 | "version": "0.23.1", 2405 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", 2406 | "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", 2407 | "dev": true, 2408 | "optional": true 2409 | }, 2410 | "@esbuild/android-x64": { 2411 | "version": "0.23.1", 2412 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", 2413 | "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", 2414 | "dev": true, 2415 | "optional": true 2416 | }, 2417 | "@esbuild/darwin-arm64": { 2418 | "version": "0.23.1", 2419 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", 2420 | "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", 2421 | "dev": true, 2422 | "optional": true 2423 | }, 2424 | "@esbuild/darwin-x64": { 2425 | "version": "0.23.1", 2426 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", 2427 | "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", 2428 | "dev": true, 2429 | "optional": true 2430 | }, 2431 | "@esbuild/freebsd-arm64": { 2432 | "version": "0.23.1", 2433 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", 2434 | "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", 2435 | "dev": true, 2436 | "optional": true 2437 | }, 2438 | "@esbuild/freebsd-x64": { 2439 | "version": "0.23.1", 2440 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", 2441 | "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", 2442 | "dev": true, 2443 | "optional": true 2444 | }, 2445 | "@esbuild/linux-arm": { 2446 | "version": "0.23.1", 2447 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", 2448 | "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", 2449 | "dev": true, 2450 | "optional": true 2451 | }, 2452 | "@esbuild/linux-arm64": { 2453 | "version": "0.23.1", 2454 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", 2455 | "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", 2456 | "dev": true, 2457 | "optional": true 2458 | }, 2459 | "@esbuild/linux-ia32": { 2460 | "version": "0.23.1", 2461 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", 2462 | "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", 2463 | "dev": true, 2464 | "optional": true 2465 | }, 2466 | "@esbuild/linux-loong64": { 2467 | "version": "0.23.1", 2468 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", 2469 | "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", 2470 | "dev": true, 2471 | "optional": true 2472 | }, 2473 | "@esbuild/linux-mips64el": { 2474 | "version": "0.23.1", 2475 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", 2476 | "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", 2477 | "dev": true, 2478 | "optional": true 2479 | }, 2480 | "@esbuild/linux-ppc64": { 2481 | "version": "0.23.1", 2482 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", 2483 | "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", 2484 | "dev": true, 2485 | "optional": true 2486 | }, 2487 | "@esbuild/linux-riscv64": { 2488 | "version": "0.23.1", 2489 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", 2490 | "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", 2491 | "dev": true, 2492 | "optional": true 2493 | }, 2494 | "@esbuild/linux-s390x": { 2495 | "version": "0.23.1", 2496 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", 2497 | "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", 2498 | "dev": true, 2499 | "optional": true 2500 | }, 2501 | "@esbuild/linux-x64": { 2502 | "version": "0.23.1", 2503 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", 2504 | "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", 2505 | "dev": true, 2506 | "optional": true 2507 | }, 2508 | "@esbuild/netbsd-x64": { 2509 | "version": "0.23.1", 2510 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", 2511 | "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", 2512 | "dev": true, 2513 | "optional": true 2514 | }, 2515 | "@esbuild/openbsd-arm64": { 2516 | "version": "0.23.1", 2517 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", 2518 | "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", 2519 | "dev": true, 2520 | "optional": true 2521 | }, 2522 | "@esbuild/openbsd-x64": { 2523 | "version": "0.23.1", 2524 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", 2525 | "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", 2526 | "dev": true, 2527 | "optional": true 2528 | }, 2529 | "@esbuild/sunos-x64": { 2530 | "version": "0.23.1", 2531 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", 2532 | "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", 2533 | "dev": true, 2534 | "optional": true 2535 | }, 2536 | "@esbuild/win32-arm64": { 2537 | "version": "0.23.1", 2538 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", 2539 | "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", 2540 | "dev": true, 2541 | "optional": true 2542 | }, 2543 | "@esbuild/win32-ia32": { 2544 | "version": "0.23.1", 2545 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", 2546 | "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", 2547 | "dev": true, 2548 | "optional": true 2549 | }, 2550 | "@esbuild/win32-x64": { 2551 | "version": "0.23.1", 2552 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", 2553 | "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", 2554 | "dev": true, 2555 | "optional": true 2556 | }, 2557 | "@jridgewell/gen-mapping": { 2558 | "version": "0.3.3", 2559 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", 2560 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", 2561 | "requires": { 2562 | "@jridgewell/set-array": "^1.0.1", 2563 | "@jridgewell/sourcemap-codec": "^1.4.10", 2564 | "@jridgewell/trace-mapping": "^0.3.9" 2565 | } 2566 | }, 2567 | "@jridgewell/resolve-uri": { 2568 | "version": "3.1.1", 2569 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", 2570 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" 2571 | }, 2572 | "@jridgewell/set-array": { 2573 | "version": "1.1.2", 2574 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", 2575 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" 2576 | }, 2577 | "@jridgewell/sourcemap-codec": { 2578 | "version": "1.4.15", 2579 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 2580 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" 2581 | }, 2582 | "@jridgewell/trace-mapping": { 2583 | "version": "0.3.20", 2584 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", 2585 | "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", 2586 | "requires": { 2587 | "@jridgewell/resolve-uri": "^3.1.0", 2588 | "@jridgewell/sourcemap-codec": "^1.4.14" 2589 | } 2590 | }, 2591 | "@octokit/app": { 2592 | "version": "14.0.1", 2593 | "resolved": "https://registry.npmjs.org/@octokit/app/-/app-14.0.1.tgz", 2594 | "integrity": "sha512-4opdXcWBVhzd6FOxlaxDKXXqi9Vz2hsDSWQGNo49HbYFAX11UqMpksMjEdfvHy0x19Pse8Nvn+R6inNb/V398w==", 2595 | "requires": { 2596 | "@octokit/auth-app": "^6.0.0", 2597 | "@octokit/auth-unauthenticated": "^5.0.0", 2598 | "@octokit/core": "^5.0.0", 2599 | "@octokit/oauth-app": "^6.0.0", 2600 | "@octokit/plugin-paginate-rest": "^9.0.0", 2601 | "@octokit/types": "^12.0.0", 2602 | "@octokit/webhooks": "^12.0.1" 2603 | } 2604 | }, 2605 | "@octokit/auth-app": { 2606 | "version": "6.0.1", 2607 | "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-6.0.1.tgz", 2608 | "integrity": "sha512-tjCD4nzQNZgmLH62+PSnTF6eGerisFgV4v6euhqJik6yWV96e1ZiiGj+NXIqbgnpjLmtnBqVUrNyGKu3DoGEGA==", 2609 | "requires": { 2610 | "@octokit/auth-oauth-app": "^7.0.0", 2611 | "@octokit/auth-oauth-user": "^4.0.0", 2612 | "@octokit/request": "^8.0.2", 2613 | "@octokit/request-error": "^5.0.0", 2614 | "@octokit/types": "^12.0.0", 2615 | "deprecation": "^2.3.1", 2616 | "lru-cache": "^10.0.0", 2617 | "universal-github-app-jwt": "^1.1.1", 2618 | "universal-user-agent": "^6.0.0" 2619 | } 2620 | }, 2621 | "@octokit/auth-oauth-app": { 2622 | "version": "7.0.1", 2623 | "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.0.1.tgz", 2624 | "integrity": "sha512-RE0KK0DCjCHXHlQBoubwlLijXEKfhMhKm9gO56xYvFmP1QTMb+vvwRPmQLLx0V+5AvV9N9I3lr1WyTzwL3rMDg==", 2625 | "requires": { 2626 | "@octokit/auth-oauth-device": "^6.0.0", 2627 | "@octokit/auth-oauth-user": "^4.0.0", 2628 | "@octokit/request": "^8.0.2", 2629 | "@octokit/types": "^12.0.0", 2630 | "@types/btoa-lite": "^1.0.0", 2631 | "btoa-lite": "^1.0.0", 2632 | "universal-user-agent": "^6.0.0" 2633 | } 2634 | }, 2635 | "@octokit/auth-oauth-device": { 2636 | "version": "6.0.1", 2637 | "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-6.0.1.tgz", 2638 | "integrity": "sha512-yxU0rkL65QkjbqQedgVx3gmW7YM5fF+r5uaSj9tM/cQGVqloXcqP2xK90eTyYvl29arFVCW8Vz4H/t47mL0ELw==", 2639 | "requires": { 2640 | "@octokit/oauth-methods": "^4.0.0", 2641 | "@octokit/request": "^8.0.0", 2642 | "@octokit/types": "^12.0.0", 2643 | "universal-user-agent": "^6.0.0" 2644 | } 2645 | }, 2646 | "@octokit/auth-oauth-user": { 2647 | "version": "4.0.1", 2648 | "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-4.0.1.tgz", 2649 | "integrity": "sha512-N94wWW09d0hleCnrO5wt5MxekatqEJ4zf+1vSe8MKMrhZ7gAXKFOKrDEZW2INltvBWJCyDUELgGRv8gfErH1Iw==", 2650 | "requires": { 2651 | "@octokit/auth-oauth-device": "^6.0.0", 2652 | "@octokit/oauth-methods": "^4.0.0", 2653 | "@octokit/request": "^8.0.2", 2654 | "@octokit/types": "^12.0.0", 2655 | "btoa-lite": "^1.0.0", 2656 | "universal-user-agent": "^6.0.0" 2657 | } 2658 | }, 2659 | "@octokit/auth-token": { 2660 | "version": "4.0.0", 2661 | "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", 2662 | "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==" 2663 | }, 2664 | "@octokit/auth-unauthenticated": { 2665 | "version": "5.0.1", 2666 | "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-5.0.1.tgz", 2667 | "integrity": "sha512-oxeWzmBFxWd+XolxKTc4zr+h3mt+yofn4r7OfoIkR/Cj/o70eEGmPsFbueyJE2iBAGpjgTnEOKM3pnuEGVmiqg==", 2668 | "requires": { 2669 | "@octokit/request-error": "^5.0.0", 2670 | "@octokit/types": "^12.0.0" 2671 | } 2672 | }, 2673 | "@octokit/core": { 2674 | "version": "5.0.1", 2675 | "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz", 2676 | "integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==", 2677 | "requires": { 2678 | "@octokit/auth-token": "^4.0.0", 2679 | "@octokit/graphql": "^7.0.0", 2680 | "@octokit/request": "^8.0.2", 2681 | "@octokit/request-error": "^5.0.0", 2682 | "@octokit/types": "^12.0.0", 2683 | "before-after-hook": "^2.2.0", 2684 | "universal-user-agent": "^6.0.0" 2685 | } 2686 | }, 2687 | "@octokit/endpoint": { 2688 | "version": "9.0.1", 2689 | "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.1.tgz", 2690 | "integrity": "sha512-hRlOKAovtINHQPYHZlfyFwaM8OyetxeoC81lAkBy34uLb8exrZB50SQdeW3EROqiY9G9yxQTpp5OHTV54QD+vA==", 2691 | "requires": { 2692 | "@octokit/types": "^12.0.0", 2693 | "is-plain-object": "^5.0.0", 2694 | "universal-user-agent": "^6.0.0" 2695 | } 2696 | }, 2697 | "@octokit/graphql": { 2698 | "version": "7.0.2", 2699 | "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", 2700 | "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", 2701 | "requires": { 2702 | "@octokit/request": "^8.0.1", 2703 | "@octokit/types": "^12.0.0", 2704 | "universal-user-agent": "^6.0.0" 2705 | } 2706 | }, 2707 | "@octokit/oauth-app": { 2708 | "version": "6.0.0", 2709 | "resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-6.0.0.tgz", 2710 | "integrity": "sha512-bNMkS+vJ6oz2hCyraT9ZfTpAQ8dZNqJJQVNaKjPLx4ue5RZiFdU1YWXguOPR8AaSHS+lKe+lR3abn2siGd+zow==", 2711 | "requires": { 2712 | "@octokit/auth-oauth-app": "^7.0.0", 2713 | "@octokit/auth-oauth-user": "^4.0.0", 2714 | "@octokit/auth-unauthenticated": "^5.0.0", 2715 | "@octokit/core": "^5.0.0", 2716 | "@octokit/oauth-authorization-url": "^6.0.2", 2717 | "@octokit/oauth-methods": "^4.0.0", 2718 | "@types/aws-lambda": "^8.10.83", 2719 | "universal-user-agent": "^6.0.0" 2720 | } 2721 | }, 2722 | "@octokit/oauth-authorization-url": { 2723 | "version": "6.0.2", 2724 | "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz", 2725 | "integrity": "sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA==" 2726 | }, 2727 | "@octokit/oauth-methods": { 2728 | "version": "4.0.0", 2729 | "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-4.0.0.tgz", 2730 | "integrity": "sha512-dqy7BZLfLbi3/8X8xPKUKZclMEK9vN3fK5WF3ortRvtplQTszFvdAGbTo71gGLO+4ZxspNiLjnqdd64Chklf7w==", 2731 | "requires": { 2732 | "@octokit/oauth-authorization-url": "^6.0.2", 2733 | "@octokit/request": "^8.0.2", 2734 | "@octokit/request-error": "^5.0.0", 2735 | "@octokit/types": "^11.0.0", 2736 | "btoa-lite": "^1.0.0" 2737 | }, 2738 | "dependencies": { 2739 | "@octokit/openapi-types": { 2740 | "version": "18.1.1", 2741 | "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", 2742 | "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==" 2743 | }, 2744 | "@octokit/types": { 2745 | "version": "11.1.0", 2746 | "resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz", 2747 | "integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==", 2748 | "requires": { 2749 | "@octokit/openapi-types": "^18.0.0" 2750 | } 2751 | } 2752 | } 2753 | }, 2754 | "@octokit/openapi-types": { 2755 | "version": "19.0.0", 2756 | "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz", 2757 | "integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw==" 2758 | }, 2759 | "@octokit/plugin-paginate-graphql": { 2760 | "version": "4.0.0", 2761 | "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-4.0.0.tgz", 2762 | "integrity": "sha512-7HcYW5tP7/Z6AETAPU14gp5H5KmCPT3hmJrS/5tO7HIgbwenYmgw4OY9Ma54FDySuxMwD+wsJlxtuGWwuZuItA==", 2763 | "requires": {} 2764 | }, 2765 | "@octokit/plugin-paginate-rest": { 2766 | "version": "9.0.0", 2767 | "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.0.0.tgz", 2768 | "integrity": "sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==", 2769 | "requires": { 2770 | "@octokit/types": "^12.0.0" 2771 | } 2772 | }, 2773 | "@octokit/plugin-request-log": { 2774 | "version": "4.0.0", 2775 | "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", 2776 | "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", 2777 | "requires": {} 2778 | }, 2779 | "@octokit/plugin-rest-endpoint-methods": { 2780 | "version": "10.0.0", 2781 | "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.0.0.tgz", 2782 | "integrity": "sha512-16VkwE2v6rXU+/gBsYC62M8lKWOphY5Lg4wpjYnVE9Zbu0J6IwiT5kILoj1YOB53XLmcJR+Nqp8DmifOPY4H3g==", 2783 | "requires": { 2784 | "@octokit/types": "^12.0.0" 2785 | } 2786 | }, 2787 | "@octokit/plugin-retry": { 2788 | "version": "6.0.1", 2789 | "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.0.1.tgz", 2790 | "integrity": "sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog==", 2791 | "requires": { 2792 | "@octokit/request-error": "^5.0.0", 2793 | "@octokit/types": "^12.0.0", 2794 | "bottleneck": "^2.15.3" 2795 | } 2796 | }, 2797 | "@octokit/plugin-throttling": { 2798 | "version": "8.0.0", 2799 | "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.0.0.tgz", 2800 | "integrity": "sha512-OkMbHYUidj81q92YRkPzWmwXkEtsI3KOcSkNm763aqUOh9IEplyX05XjKAdZFANAvaYH0Q4JBZwu4h2VnPVXZA==", 2801 | "requires": { 2802 | "@octokit/types": "^12.0.0", 2803 | "bottleneck": "^2.15.3" 2804 | } 2805 | }, 2806 | "@octokit/request": { 2807 | "version": "8.1.3", 2808 | "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.3.tgz", 2809 | "integrity": "sha512-iUvXP4QmysS8kyE/a4AGwR0A+tHDVxgW6TmPd2ci8/Xc8KjlBtTKSDpZlUT5Y4S4Nu+eM8LvbOYjVAp/sz3Gpg==", 2810 | "requires": { 2811 | "@octokit/endpoint": "^9.0.0", 2812 | "@octokit/request-error": "^5.0.0", 2813 | "@octokit/types": "^12.0.0", 2814 | "is-plain-object": "^5.0.0", 2815 | "universal-user-agent": "^6.0.0" 2816 | } 2817 | }, 2818 | "@octokit/request-error": { 2819 | "version": "5.0.1", 2820 | "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", 2821 | "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", 2822 | "requires": { 2823 | "@octokit/types": "^12.0.0", 2824 | "deprecation": "^2.0.0", 2825 | "once": "^1.4.0" 2826 | } 2827 | }, 2828 | "@octokit/rest": { 2829 | "version": "20.0.2", 2830 | "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", 2831 | "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", 2832 | "requires": { 2833 | "@octokit/core": "^5.0.0", 2834 | "@octokit/plugin-paginate-rest": "^9.0.0", 2835 | "@octokit/plugin-request-log": "^4.0.0", 2836 | "@octokit/plugin-rest-endpoint-methods": "^10.0.0" 2837 | } 2838 | }, 2839 | "@octokit/types": { 2840 | "version": "12.0.0", 2841 | "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz", 2842 | "integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==", 2843 | "requires": { 2844 | "@octokit/openapi-types": "^19.0.0" 2845 | } 2846 | }, 2847 | "@octokit/webhooks": { 2848 | "version": "12.0.3", 2849 | "resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-12.0.3.tgz", 2850 | "integrity": "sha512-8iG+/yza7hwz1RrQ7i7uGpK2/tuItZxZq1aTmeg2TNp2xTUB8F8lZF/FcZvyyAxT8tpDMF74TjFGCDACkf1kAQ==", 2851 | "requires": { 2852 | "@octokit/request-error": "^5.0.0", 2853 | "@octokit/webhooks-methods": "^4.0.0", 2854 | "@octokit/webhooks-types": "7.1.0", 2855 | "aggregate-error": "^3.1.0" 2856 | } 2857 | }, 2858 | "@octokit/webhooks-definitions": { 2859 | "version": "3.67.3", 2860 | "resolved": "https://registry.npmjs.org/@octokit/webhooks-definitions/-/webhooks-definitions-3.67.3.tgz", 2861 | "integrity": "sha512-do4Z1r2OVhuI0ihJhQ8Hg+yPWnBYEBNuFNCrvtPKoYT1w81jD7pBXgGe86lYuuNirkDHb0Nxt+zt4O5GiFJfgA==" 2862 | }, 2863 | "@octokit/webhooks-methods": { 2864 | "version": "4.0.0", 2865 | "resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-4.0.0.tgz", 2866 | "integrity": "sha512-M8mwmTXp+VeolOS/kfRvsDdW+IO0qJ8kYodM/sAysk093q6ApgmBXwK1ZlUvAwXVrp/YVHp6aArj4auAxUAOFw==" 2867 | }, 2868 | "@octokit/webhooks-types": { 2869 | "version": "7.1.0", 2870 | "resolved": "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-7.1.0.tgz", 2871 | "integrity": "sha512-y92CpG4kFFtBBjni8LHoV12IegJ+KFxLgKRengrVjKmGE5XMeCuGvlfRe75lTRrgXaG6XIWJlFpIDTlkoJsU8w==" 2872 | }, 2873 | "@types/aws-lambda": { 2874 | "version": "8.10.124", 2875 | "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.124.tgz", 2876 | "integrity": "sha512-PHqK0SuAkFS3tZjceqRXecxxrWIN3VqTicuialtK2wZmvBy7H9WGc3u3+wOgaZB7N8SpSXDpWk9qa7eorpTStg==" 2877 | }, 2878 | "@types/babel__traverse": { 2879 | "version": "7.20.3", 2880 | "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.3.tgz", 2881 | "integrity": "sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw==", 2882 | "dev": true, 2883 | "requires": { 2884 | "@babel/types": "^7.20.7" 2885 | } 2886 | }, 2887 | "@types/btoa-lite": { 2888 | "version": "1.0.0", 2889 | "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz", 2890 | "integrity": "sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==" 2891 | }, 2892 | "@types/diff": { 2893 | "version": "5.0.7", 2894 | "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.0.7.tgz", 2895 | "integrity": "sha512-adBosR2GntaQQiuHnfRN9HtxYpoHHJBcdyz7VSXhjpSAmtvIfu/S1fjTqwuIx/Ypba6LCZdfWIqPYx2BR5TneQ==", 2896 | "dev": true 2897 | }, 2898 | "@types/jsonwebtoken": { 2899 | "version": "9.0.3", 2900 | "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", 2901 | "integrity": "sha512-b0jGiOgHtZ2jqdPgPnP6WLCXZk1T8p06A/vPGzUvxpFGgKMbjXJDjC5m52ErqBnIuWZFgGoIJyRdeG5AyreJjA==", 2902 | "requires": { 2903 | "@types/node": "*" 2904 | } 2905 | }, 2906 | "@types/node": { 2907 | "version": "20.8.3", 2908 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.3.tgz", 2909 | "integrity": "sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw==" 2910 | }, 2911 | "@types/node-fetch": { 2912 | "version": "2.6.6", 2913 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", 2914 | "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", 2915 | "requires": { 2916 | "@types/node": "*", 2917 | "form-data": "^4.0.0" 2918 | } 2919 | }, 2920 | "@types/xml2js": { 2921 | "version": "0.4.13", 2922 | "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.13.tgz", 2923 | "integrity": "sha512-nuT42GzgoUa4zZgBoF4d+Zqc12/FlVxXCT4xU6j3RfqTFVQWrUAClI/0sNJ5ImM9Wv6KB42KMG2xsVMn4cSBzA==", 2924 | "dev": true, 2925 | "requires": { 2926 | "@types/node": "*" 2927 | } 2928 | }, 2929 | "abort-controller": { 2930 | "version": "3.0.0", 2931 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 2932 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 2933 | "requires": { 2934 | "event-target-shim": "^5.0.0" 2935 | } 2936 | }, 2937 | "agentkeepalive": { 2938 | "version": "4.5.0", 2939 | "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", 2940 | "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", 2941 | "requires": { 2942 | "humanize-ms": "^1.2.1" 2943 | } 2944 | }, 2945 | "aggregate-error": { 2946 | "version": "3.1.0", 2947 | "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", 2948 | "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", 2949 | "requires": { 2950 | "clean-stack": "^2.0.0", 2951 | "indent-string": "^4.0.0" 2952 | } 2953 | }, 2954 | "ansi-styles": { 2955 | "version": "3.2.1", 2956 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 2957 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 2958 | "requires": { 2959 | "color-convert": "^1.9.0" 2960 | } 2961 | }, 2962 | "asap": { 2963 | "version": "2.0.6", 2964 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 2965 | "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", 2966 | "dev": true 2967 | }, 2968 | "asynckit": { 2969 | "version": "0.4.0", 2970 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 2971 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 2972 | }, 2973 | "basic-auth": { 2974 | "version": "2.0.1", 2975 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", 2976 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", 2977 | "dev": true, 2978 | "requires": { 2979 | "safe-buffer": "5.1.2" 2980 | }, 2981 | "dependencies": { 2982 | "safe-buffer": { 2983 | "version": "5.1.2", 2984 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2985 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 2986 | "dev": true 2987 | } 2988 | } 2989 | }, 2990 | "before-after-hook": { 2991 | "version": "2.2.3", 2992 | "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", 2993 | "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" 2994 | }, 2995 | "bottleneck": { 2996 | "version": "2.19.5", 2997 | "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", 2998 | "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" 2999 | }, 3000 | "btoa-lite": { 3001 | "version": "1.0.0", 3002 | "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", 3003 | "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==" 3004 | }, 3005 | "buffer-equal-constant-time": { 3006 | "version": "1.0.1", 3007 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 3008 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" 3009 | }, 3010 | "call-bind": { 3011 | "version": "1.0.2", 3012 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 3013 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 3014 | "dev": true, 3015 | "requires": { 3016 | "function-bind": "^1.1.1", 3017 | "get-intrinsic": "^1.0.2" 3018 | } 3019 | }, 3020 | "chalk": { 3021 | "version": "5.3.0", 3022 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", 3023 | "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==" 3024 | }, 3025 | "clean-stack": { 3026 | "version": "2.2.0", 3027 | "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", 3028 | "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" 3029 | }, 3030 | "color-convert": { 3031 | "version": "1.9.3", 3032 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 3033 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 3034 | "requires": { 3035 | "color-name": "1.1.3" 3036 | } 3037 | }, 3038 | "color-name": { 3039 | "version": "1.1.3", 3040 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 3041 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" 3042 | }, 3043 | "combined-stream": { 3044 | "version": "1.0.8", 3045 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 3046 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 3047 | "requires": { 3048 | "delayed-stream": "~1.0.0" 3049 | } 3050 | }, 3051 | "commander": { 3052 | "version": "2.20.3", 3053 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 3054 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 3055 | "dev": true 3056 | }, 3057 | "component-emitter": { 3058 | "version": "1.3.0", 3059 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", 3060 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", 3061 | "dev": true 3062 | }, 3063 | "cookiejar": { 3064 | "version": "2.1.4", 3065 | "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", 3066 | "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", 3067 | "dev": true 3068 | }, 3069 | "csv-writer": { 3070 | "version": "1.6.0", 3071 | "resolved": "https://registry.npmjs.org/csv-writer/-/csv-writer-1.6.0.tgz", 3072 | "integrity": "sha512-NOx7YDFWEsM/fTRAJjRpPp8t+MKRVvniAg9wQlUKx20MFrPs73WLJhFf5iteqrxNYnsy924K3Iroh3yNHeYd2g==", 3073 | "dev": true 3074 | }, 3075 | "debug": { 3076 | "version": "2.6.9", 3077 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 3078 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 3079 | "dev": true, 3080 | "requires": { 3081 | "ms": "2.0.0" 3082 | }, 3083 | "dependencies": { 3084 | "ms": { 3085 | "version": "2.0.0", 3086 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 3087 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", 3088 | "dev": true 3089 | } 3090 | } 3091 | }, 3092 | "delayed-stream": { 3093 | "version": "1.0.0", 3094 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 3095 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" 3096 | }, 3097 | "depd": { 3098 | "version": "2.0.0", 3099 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 3100 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 3101 | "dev": true 3102 | }, 3103 | "deprecation": { 3104 | "version": "2.3.1", 3105 | "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", 3106 | "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" 3107 | }, 3108 | "dezalgo": { 3109 | "version": "1.0.4", 3110 | "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", 3111 | "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", 3112 | "dev": true, 3113 | "requires": { 3114 | "asap": "^2.0.0", 3115 | "wrappy": "1" 3116 | } 3117 | }, 3118 | "diff": { 3119 | "version": "5.1.0", 3120 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", 3121 | "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==" 3122 | }, 3123 | "dotenv": { 3124 | "version": "16.3.1", 3125 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", 3126 | "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" 3127 | }, 3128 | "ecdsa-sig-formatter": { 3129 | "version": "1.0.11", 3130 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 3131 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 3132 | "requires": { 3133 | "safe-buffer": "^5.0.1" 3134 | } 3135 | }, 3136 | "ee-first": { 3137 | "version": "1.1.1", 3138 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 3139 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", 3140 | "dev": true 3141 | }, 3142 | "esbuild": { 3143 | "version": "0.23.1", 3144 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", 3145 | "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", 3146 | "dev": true, 3147 | "requires": { 3148 | "@esbuild/aix-ppc64": "0.23.1", 3149 | "@esbuild/android-arm": "0.23.1", 3150 | "@esbuild/android-arm64": "0.23.1", 3151 | "@esbuild/android-x64": "0.23.1", 3152 | "@esbuild/darwin-arm64": "0.23.1", 3153 | "@esbuild/darwin-x64": "0.23.1", 3154 | "@esbuild/freebsd-arm64": "0.23.1", 3155 | "@esbuild/freebsd-x64": "0.23.1", 3156 | "@esbuild/linux-arm": "0.23.1", 3157 | "@esbuild/linux-arm64": "0.23.1", 3158 | "@esbuild/linux-ia32": "0.23.1", 3159 | "@esbuild/linux-loong64": "0.23.1", 3160 | "@esbuild/linux-mips64el": "0.23.1", 3161 | "@esbuild/linux-ppc64": "0.23.1", 3162 | "@esbuild/linux-riscv64": "0.23.1", 3163 | "@esbuild/linux-s390x": "0.23.1", 3164 | "@esbuild/linux-x64": "0.23.1", 3165 | "@esbuild/netbsd-x64": "0.23.1", 3166 | "@esbuild/openbsd-arm64": "0.23.1", 3167 | "@esbuild/openbsd-x64": "0.23.1", 3168 | "@esbuild/sunos-x64": "0.23.1", 3169 | "@esbuild/win32-arm64": "0.23.1", 3170 | "@esbuild/win32-ia32": "0.23.1", 3171 | "@esbuild/win32-x64": "0.23.1" 3172 | } 3173 | }, 3174 | "escape-string-regexp": { 3175 | "version": "1.0.5", 3176 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 3177 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" 3178 | }, 3179 | "event-target-shim": { 3180 | "version": "5.0.1", 3181 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 3182 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" 3183 | }, 3184 | "eventsource": { 3185 | "version": "1.1.2", 3186 | "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz", 3187 | "integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==", 3188 | "dev": true 3189 | }, 3190 | "fast-safe-stringify": { 3191 | "version": "2.1.1", 3192 | "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", 3193 | "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", 3194 | "dev": true 3195 | }, 3196 | "form-data": { 3197 | "version": "4.0.0", 3198 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 3199 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 3200 | "requires": { 3201 | "asynckit": "^0.4.0", 3202 | "combined-stream": "^1.0.8", 3203 | "mime-types": "^2.1.12" 3204 | } 3205 | }, 3206 | "form-data-encoder": { 3207 | "version": "1.7.2", 3208 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", 3209 | "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" 3210 | }, 3211 | "formdata-node": { 3212 | "version": "4.4.1", 3213 | "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", 3214 | "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", 3215 | "requires": { 3216 | "node-domexception": "1.0.0", 3217 | "web-streams-polyfill": "4.0.0-beta.3" 3218 | } 3219 | }, 3220 | "formidable": { 3221 | "version": "2.1.2", 3222 | "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", 3223 | "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", 3224 | "dev": true, 3225 | "requires": { 3226 | "dezalgo": "^1.0.4", 3227 | "hexoid": "^1.0.0", 3228 | "once": "^1.4.0", 3229 | "qs": "^6.11.0" 3230 | } 3231 | }, 3232 | "fsevents": { 3233 | "version": "2.3.3", 3234 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 3235 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 3236 | "dev": true, 3237 | "optional": true 3238 | }, 3239 | "function-bind": { 3240 | "version": "1.1.1", 3241 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 3242 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 3243 | "dev": true 3244 | }, 3245 | "get-intrinsic": { 3246 | "version": "1.2.1", 3247 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", 3248 | "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", 3249 | "dev": true, 3250 | "requires": { 3251 | "function-bind": "^1.1.1", 3252 | "has": "^1.0.3", 3253 | "has-proto": "^1.0.1", 3254 | "has-symbols": "^1.0.3" 3255 | } 3256 | }, 3257 | "get-tsconfig": { 3258 | "version": "4.8.1", 3259 | "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", 3260 | "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", 3261 | "dev": true, 3262 | "requires": { 3263 | "resolve-pkg-maps": "^1.0.0" 3264 | } 3265 | }, 3266 | "globals": { 3267 | "version": "11.12.0", 3268 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 3269 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" 3270 | }, 3271 | "gpt-tokenizer": { 3272 | "version": "2.1.2", 3273 | "resolved": "https://registry.npmjs.org/gpt-tokenizer/-/gpt-tokenizer-2.1.2.tgz", 3274 | "integrity": "sha512-HSuI5d6uey+c7x/VzQlPfCoGrfLyAc28vxWofKbjR9PJHm0AjQGSWkKw/OJnb+8S1g7nzgRsf0WH3dK+NNWYbg==", 3275 | "requires": { 3276 | "rfc4648": "^1.5.2" 3277 | } 3278 | }, 3279 | "groq-sdk": { 3280 | "version": "0.8.0", 3281 | "resolved": "https://registry.npmjs.org/groq-sdk/-/groq-sdk-0.8.0.tgz", 3282 | "integrity": "sha512-hSgCjZCkoM4CY/TWfsaNlh512svWRR2td4HGpmEV8MbVEVrxZARJq5BHt8gbEF9Gex092/X7VJvaQpha0dIC8g==", 3283 | "requires": { 3284 | "@types/node": "^18.11.18", 3285 | "@types/node-fetch": "^2.6.4", 3286 | "abort-controller": "^3.0.0", 3287 | "agentkeepalive": "^4.2.1", 3288 | "form-data-encoder": "1.7.2", 3289 | "formdata-node": "^4.3.2", 3290 | "node-fetch": "^2.6.7" 3291 | }, 3292 | "dependencies": { 3293 | "@types/node": { 3294 | "version": "18.19.64", 3295 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.64.tgz", 3296 | "integrity": "sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==", 3297 | "requires": { 3298 | "undici-types": "~5.26.4" 3299 | } 3300 | } 3301 | } 3302 | }, 3303 | "has": { 3304 | "version": "1.0.4", 3305 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", 3306 | "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", 3307 | "dev": true 3308 | }, 3309 | "has-flag": { 3310 | "version": "3.0.0", 3311 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 3312 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" 3313 | }, 3314 | "has-proto": { 3315 | "version": "1.0.1", 3316 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", 3317 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", 3318 | "dev": true 3319 | }, 3320 | "has-symbols": { 3321 | "version": "1.0.3", 3322 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 3323 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 3324 | "dev": true 3325 | }, 3326 | "hexoid": { 3327 | "version": "1.0.0", 3328 | "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", 3329 | "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", 3330 | "dev": true 3331 | }, 3332 | "humanize-ms": { 3333 | "version": "1.2.1", 3334 | "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", 3335 | "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", 3336 | "requires": { 3337 | "ms": "^2.0.0" 3338 | } 3339 | }, 3340 | "indent-string": { 3341 | "version": "4.0.0", 3342 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", 3343 | "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" 3344 | }, 3345 | "inherits": { 3346 | "version": "2.0.4", 3347 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 3348 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 3349 | "dev": true 3350 | }, 3351 | "is-plain-object": { 3352 | "version": "5.0.0", 3353 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", 3354 | "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" 3355 | }, 3356 | "js-tokens": { 3357 | "version": "4.0.0", 3358 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 3359 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 3360 | }, 3361 | "jsesc": { 3362 | "version": "2.5.2", 3363 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 3364 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" 3365 | }, 3366 | "jsonwebtoken": { 3367 | "version": "9.0.2", 3368 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", 3369 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", 3370 | "requires": { 3371 | "jws": "^3.2.2", 3372 | "lodash.includes": "^4.3.0", 3373 | "lodash.isboolean": "^3.0.3", 3374 | "lodash.isinteger": "^4.0.4", 3375 | "lodash.isnumber": "^3.0.3", 3376 | "lodash.isplainobject": "^4.0.6", 3377 | "lodash.isstring": "^4.0.1", 3378 | "lodash.once": "^4.0.0", 3379 | "ms": "^2.1.1", 3380 | "semver": "^7.5.4" 3381 | } 3382 | }, 3383 | "jwa": { 3384 | "version": "1.4.1", 3385 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 3386 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 3387 | "requires": { 3388 | "buffer-equal-constant-time": "1.0.1", 3389 | "ecdsa-sig-formatter": "1.0.11", 3390 | "safe-buffer": "^5.0.1" 3391 | } 3392 | }, 3393 | "jws": { 3394 | "version": "3.2.2", 3395 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 3396 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 3397 | "requires": { 3398 | "jwa": "^1.4.1", 3399 | "safe-buffer": "^5.0.1" 3400 | } 3401 | }, 3402 | "lodash.includes": { 3403 | "version": "4.3.0", 3404 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 3405 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" 3406 | }, 3407 | "lodash.isboolean": { 3408 | "version": "3.0.3", 3409 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 3410 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" 3411 | }, 3412 | "lodash.isinteger": { 3413 | "version": "4.0.4", 3414 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 3415 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" 3416 | }, 3417 | "lodash.isnumber": { 3418 | "version": "3.0.3", 3419 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 3420 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" 3421 | }, 3422 | "lodash.isplainobject": { 3423 | "version": "4.0.6", 3424 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 3425 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" 3426 | }, 3427 | "lodash.isstring": { 3428 | "version": "4.0.1", 3429 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 3430 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" 3431 | }, 3432 | "lodash.once": { 3433 | "version": "4.1.1", 3434 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 3435 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" 3436 | }, 3437 | "lru-cache": { 3438 | "version": "10.0.1", 3439 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", 3440 | "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==" 3441 | }, 3442 | "methods": { 3443 | "version": "1.1.2", 3444 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 3445 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 3446 | "dev": true 3447 | }, 3448 | "mime": { 3449 | "version": "2.6.0", 3450 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", 3451 | "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", 3452 | "dev": true 3453 | }, 3454 | "mime-db": { 3455 | "version": "1.52.0", 3456 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 3457 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 3458 | }, 3459 | "mime-types": { 3460 | "version": "2.1.35", 3461 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 3462 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 3463 | "requires": { 3464 | "mime-db": "1.52.0" 3465 | } 3466 | }, 3467 | "morgan": { 3468 | "version": "1.10.0", 3469 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", 3470 | "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", 3471 | "dev": true, 3472 | "requires": { 3473 | "basic-auth": "~2.0.1", 3474 | "debug": "2.6.9", 3475 | "depd": "~2.0.0", 3476 | "on-finished": "~2.3.0", 3477 | "on-headers": "~1.0.2" 3478 | } 3479 | }, 3480 | "ms": { 3481 | "version": "2.1.3", 3482 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 3483 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 3484 | }, 3485 | "node-domexception": { 3486 | "version": "1.0.0", 3487 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", 3488 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" 3489 | }, 3490 | "node-fetch": { 3491 | "version": "2.7.0", 3492 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 3493 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 3494 | "requires": { 3495 | "whatwg-url": "^5.0.0" 3496 | } 3497 | }, 3498 | "object-inspect": { 3499 | "version": "1.12.3", 3500 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", 3501 | "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", 3502 | "dev": true 3503 | }, 3504 | "octokit": { 3505 | "version": "3.1.1", 3506 | "resolved": "https://registry.npmjs.org/octokit/-/octokit-3.1.1.tgz", 3507 | "integrity": "sha512-AKJs5XYs7iAh7bskkYpxhUIpsYZdLqjnlnqrN5s9FFZuJ/a6ATUHivGpUKDpGB/xa+LGDtG9Lu8bOCfPM84vHQ==", 3508 | "requires": { 3509 | "@octokit/app": "^14.0.0", 3510 | "@octokit/core": "^5.0.0", 3511 | "@octokit/oauth-app": "^6.0.0", 3512 | "@octokit/plugin-paginate-graphql": "^4.0.0", 3513 | "@octokit/plugin-paginate-rest": "^9.0.0", 3514 | "@octokit/plugin-rest-endpoint-methods": "^10.0.0", 3515 | "@octokit/plugin-retry": "^6.0.0", 3516 | "@octokit/plugin-throttling": "^8.0.0", 3517 | "@octokit/request-error": "^5.0.0", 3518 | "@octokit/types": "^12.0.0" 3519 | } 3520 | }, 3521 | "on-finished": { 3522 | "version": "2.3.0", 3523 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 3524 | "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", 3525 | "dev": true, 3526 | "requires": { 3527 | "ee-first": "1.1.1" 3528 | } 3529 | }, 3530 | "on-headers": { 3531 | "version": "1.0.2", 3532 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", 3533 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", 3534 | "dev": true 3535 | }, 3536 | "once": { 3537 | "version": "1.4.0", 3538 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 3539 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 3540 | "requires": { 3541 | "wrappy": "1" 3542 | } 3543 | }, 3544 | "qs": { 3545 | "version": "6.11.2", 3546 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", 3547 | "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", 3548 | "dev": true, 3549 | "requires": { 3550 | "side-channel": "^1.0.4" 3551 | } 3552 | }, 3553 | "readable-stream": { 3554 | "version": "3.6.2", 3555 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 3556 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 3557 | "dev": true, 3558 | "requires": { 3559 | "inherits": "^2.0.3", 3560 | "string_decoder": "^1.1.1", 3561 | "util-deprecate": "^1.0.1" 3562 | } 3563 | }, 3564 | "resolve-pkg-maps": { 3565 | "version": "1.0.0", 3566 | "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", 3567 | "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", 3568 | "dev": true 3569 | }, 3570 | "rfc4648": { 3571 | "version": "1.5.2", 3572 | "resolved": "https://registry.npmjs.org/rfc4648/-/rfc4648-1.5.2.tgz", 3573 | "integrity": "sha512-tLOizhR6YGovrEBLatX1sdcuhoSCXddw3mqNVAcKxGJ+J0hFeJ+SjeWCv5UPA/WU3YzWPPuCVYgXBKZUPGpKtg==" 3574 | }, 3575 | "safe-buffer": { 3576 | "version": "5.2.1", 3577 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 3578 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 3579 | }, 3580 | "sax": { 3581 | "version": "1.3.0", 3582 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", 3583 | "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" 3584 | }, 3585 | "semver": { 3586 | "version": "7.5.4", 3587 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 3588 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 3589 | "requires": { 3590 | "lru-cache": "^6.0.0" 3591 | }, 3592 | "dependencies": { 3593 | "lru-cache": { 3594 | "version": "6.0.0", 3595 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 3596 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 3597 | "requires": { 3598 | "yallist": "^4.0.0" 3599 | } 3600 | } 3601 | } 3602 | }, 3603 | "side-channel": { 3604 | "version": "1.0.4", 3605 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 3606 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 3607 | "dev": true, 3608 | "requires": { 3609 | "call-bind": "^1.0.0", 3610 | "get-intrinsic": "^1.0.2", 3611 | "object-inspect": "^1.9.0" 3612 | } 3613 | }, 3614 | "smee-client": { 3615 | "version": "1.2.3", 3616 | "resolved": "https://registry.npmjs.org/smee-client/-/smee-client-1.2.3.tgz", 3617 | "integrity": "sha512-uDrU8u9/Ln7aRXyzGHgVaNUS8onHZZeSwQjCdkMoSL7U85xI+l+Y2NgjibkMJAyXkW7IAbb8rw9RMHIjS6lAwA==", 3618 | "dev": true, 3619 | "requires": { 3620 | "commander": "^2.19.0", 3621 | "eventsource": "^1.1.0", 3622 | "morgan": "^1.9.1", 3623 | "superagent": "^7.1.3", 3624 | "validator": "^13.7.0" 3625 | } 3626 | }, 3627 | "string_decoder": { 3628 | "version": "1.3.0", 3629 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 3630 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 3631 | "dev": true, 3632 | "requires": { 3633 | "safe-buffer": "~5.2.0" 3634 | } 3635 | }, 3636 | "superagent": { 3637 | "version": "7.1.5", 3638 | "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.5.tgz", 3639 | "integrity": "sha512-HQYyGuDRFGmZ6GNC4hq2f37KnsY9Lr0/R1marNZTgMweVDQLTLJJ6DGQ9Tj/xVVs5HEnop9EMmTbywb5P30aqw==", 3640 | "dev": true, 3641 | "requires": { 3642 | "component-emitter": "^1.3.0", 3643 | "cookiejar": "^2.1.3", 3644 | "debug": "^4.3.4", 3645 | "fast-safe-stringify": "^2.1.1", 3646 | "form-data": "^4.0.0", 3647 | "formidable": "^2.0.1", 3648 | "methods": "^1.1.2", 3649 | "mime": "^2.5.0", 3650 | "qs": "^6.10.3", 3651 | "readable-stream": "^3.6.0", 3652 | "semver": "^7.3.7" 3653 | }, 3654 | "dependencies": { 3655 | "debug": { 3656 | "version": "4.3.4", 3657 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 3658 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 3659 | "dev": true, 3660 | "requires": { 3661 | "ms": "2.1.2" 3662 | } 3663 | }, 3664 | "ms": { 3665 | "version": "2.1.2", 3666 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 3667 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 3668 | "dev": true 3669 | } 3670 | } 3671 | }, 3672 | "supports-color": { 3673 | "version": "5.5.0", 3674 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 3675 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 3676 | "requires": { 3677 | "has-flag": "^3.0.0" 3678 | } 3679 | }, 3680 | "to-fast-properties": { 3681 | "version": "2.0.0", 3682 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 3683 | "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" 3684 | }, 3685 | "tr46": { 3686 | "version": "0.0.3", 3687 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 3688 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 3689 | }, 3690 | "tsx": { 3691 | "version": "4.19.2", 3692 | "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", 3693 | "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", 3694 | "dev": true, 3695 | "requires": { 3696 | "esbuild": "~0.23.0", 3697 | "fsevents": "~2.3.3", 3698 | "get-tsconfig": "^4.7.5" 3699 | } 3700 | }, 3701 | "typescript": { 3702 | "version": "5.2.2", 3703 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", 3704 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", 3705 | "dev": true 3706 | }, 3707 | "undici-types": { 3708 | "version": "5.26.5", 3709 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 3710 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" 3711 | }, 3712 | "universal-github-app-jwt": { 3713 | "version": "1.1.1", 3714 | "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.1.tgz", 3715 | "integrity": "sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==", 3716 | "requires": { 3717 | "@types/jsonwebtoken": "^9.0.0", 3718 | "jsonwebtoken": "^9.0.0" 3719 | } 3720 | }, 3721 | "universal-user-agent": { 3722 | "version": "6.0.0", 3723 | "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", 3724 | "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" 3725 | }, 3726 | "util-deprecate": { 3727 | "version": "1.0.2", 3728 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 3729 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 3730 | "dev": true 3731 | }, 3732 | "validator": { 3733 | "version": "13.11.0", 3734 | "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", 3735 | "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", 3736 | "dev": true 3737 | }, 3738 | "web-streams-polyfill": { 3739 | "version": "4.0.0-beta.3", 3740 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", 3741 | "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==" 3742 | }, 3743 | "webidl-conversions": { 3744 | "version": "3.0.1", 3745 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 3746 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 3747 | }, 3748 | "whatwg-url": { 3749 | "version": "5.0.0", 3750 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 3751 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 3752 | "requires": { 3753 | "tr46": "~0.0.3", 3754 | "webidl-conversions": "^3.0.0" 3755 | } 3756 | }, 3757 | "wrappy": { 3758 | "version": "1.0.2", 3759 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 3760 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 3761 | }, 3762 | "xml2js": { 3763 | "version": "0.6.2", 3764 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", 3765 | "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", 3766 | "requires": { 3767 | "sax": ">=0.6.0", 3768 | "xmlbuilder": "~11.0.0" 3769 | } 3770 | }, 3771 | "xmlbuilder": { 3772 | "version": "11.0.1", 3773 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 3774 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" 3775 | }, 3776 | "yallist": { 3777 | "version": "4.0.0", 3778 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 3779 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 3780 | } 3781 | } 3782 | } 3783 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "secure-agent", 3 | "version": "1.0.0", 4 | "main": "src/app.ts", 5 | "license": "ISC", 6 | "scripts": { 7 | "start": "tsx src/app.ts" 8 | }, 9 | "dependencies": { 10 | "@babel/parser": "^7.23.0", 11 | "@babel/traverse": "^7.23.2", 12 | "@octokit/rest": "^20.0.2", 13 | "@octokit/webhooks-definitions": "^3.67.3", 14 | "@types/node": "^20.8.3", 15 | "chalk": "^5.3.0", 16 | "diff": "^5.1.0", 17 | "dotenv": "^16.3.1", 18 | "gpt-tokenizer": "^2.1.2", 19 | "groq-sdk": "^0.8.0", 20 | "octokit": "^3.1.1", 21 | "xml2js": "^0.6.2" 22 | }, 23 | "devDependencies": { 24 | "@types/babel__traverse": "^7.20.3", 25 | "@types/diff": "^5.0.7", 26 | "@types/xml2js": "^0.4.13", 27 | "csv-writer": "^1.6.0", 28 | "smee-client": "^1.2.3", 29 | "tsx": "^4.19.2", 30 | "typescript": "^5.2.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/app.ts: -------------------------------------------------------------------------------- 1 | import { Octokit } from "@octokit/rest"; 2 | import { createNodeMiddleware } from "@octokit/webhooks"; 3 | import { WebhookEventMap } from "@octokit/webhooks-definitions/schema"; 4 | import * as http from "http"; 5 | import { App } from "octokit"; 6 | import { Review } from "./constants"; 7 | import { env } from "./env"; 8 | import { processPullRequest } from "./review-agent"; 9 | import { applyReview } from "./reviews"; 10 | 11 | // This creates a new instance of the Octokit App class. 12 | const reviewApp = new App({ 13 | appId: env.GITHUB_APP_ID, 14 | privateKey: env.GITHUB_PRIVATE_KEY, 15 | webhooks: { 16 | secret: env.GITHUB_WEBHOOK_SECRET, 17 | }, 18 | }); 19 | 20 | const getChangesPerFile = async (payload: WebhookEventMap["pull_request"]) => { 21 | try { 22 | const octokit = await reviewApp.getInstallationOctokit( 23 | payload.installation.id 24 | ); 25 | const { data: files } = await octokit.rest.pulls.listFiles({ 26 | owner: payload.repository.owner.login, 27 | repo: payload.repository.name, 28 | pull_number: payload.pull_request.number, 29 | }); 30 | console.dir({ files }, { depth: null }); 31 | return files; 32 | } catch (exc) { 33 | console.log("exc"); 34 | return []; 35 | } 36 | }; 37 | 38 | // This adds an event handler that your code will call later. When this event handler is called, it will log the event to the console. Then, it will use GitHub's REST API to add a comment to the pull request that triggered the event. 39 | async function handlePullRequestOpened({ 40 | octokit, 41 | payload, 42 | }: { 43 | octokit: Octokit; 44 | payload: WebhookEventMap["pull_request"]; 45 | }) { 46 | console.log( 47 | `Received a pull request event for #${payload.pull_request.number}` 48 | ); 49 | // const reposWithInlineEnabled = new Set([601904706, 701925328]); 50 | // const canInlineSuggest = reposWithInlineEnabled.has(payload.repository.id); 51 | try { 52 | console.log("pr info", { 53 | id: payload.repository.id, 54 | fullName: payload.repository.full_name, 55 | url: payload.repository.html_url, 56 | }); 57 | const files = await getChangesPerFile(payload); 58 | const review: Review = await processPullRequest( 59 | octokit, 60 | payload, 61 | files, 62 | true 63 | ); 64 | await applyReview({ octokit, payload, review }); 65 | console.log("Review Submitted"); 66 | } catch (exc) { 67 | console.log(exc); 68 | } 69 | } 70 | 71 | // This sets up a webhook event listener. When your app receives a webhook event from GitHub with a `X-GitHub-Event` header value of `pull_request` and an `action` payload value of `opened`, it calls the `handlePullRequestOpened` event handler that is defined above. 72 | //@ts-ignore 73 | reviewApp.webhooks.on("pull_request.opened", handlePullRequestOpened); 74 | 75 | const port = process.env.PORT || 3000; 76 | const reviewWebhook = `/api/review`; 77 | 78 | const reviewMiddleware = createNodeMiddleware(reviewApp.webhooks, { 79 | path: "/api/review", 80 | }); 81 | 82 | const server = http.createServer((req, res) => { 83 | if (req.url === reviewWebhook) { 84 | reviewMiddleware(req, res); 85 | } else { 86 | res.statusCode = 404; 87 | res.end(); 88 | } 89 | }); 90 | 91 | // This creates a Node.js server that listens for incoming HTTP requests (including webhook payloads from GitHub) on the specified port. When the server receives a request, it executes the `middleware` function that you defined earlier. Once the server is running, it logs messages to the console to indicate that it is listening. 92 | server.listen(port, () => { 93 | console.log(`Server is listening for events.`); 94 | console.log("Press Ctrl + C to quit."); 95 | }); 96 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | import { Node } from "@babel/traverse"; 2 | import { JavascriptParser } from "./context/language/javascript-parser"; 3 | import { ChatCompletionMessageParam } from "groq-sdk/resources/chat/completions"; 4 | 5 | export interface PRFile { 6 | sha: string; 7 | filename: string; 8 | status: 9 | | "added" 10 | | "removed" 11 | | "renamed" 12 | | "changed" 13 | | "modified" 14 | | "copied" 15 | | "unchanged"; 16 | additions: number; 17 | deletions: number; 18 | changes: number; 19 | blob_url: string; 20 | raw_url: string; 21 | contents_url: string; 22 | patch?: string; 23 | previous_filename?: string; 24 | patchTokenLength?: number; 25 | old_contents?: string; 26 | current_contents?: string; 27 | } 28 | 29 | export interface BuilderResponse { 30 | comment: string; 31 | structuredComments: any[]; 32 | } 33 | 34 | export interface Builders { 35 | convoBuilder: (diff: string) => ChatCompletionMessageParam[]; 36 | responseBuilder: (feedbacks: string[]) => Promise; 37 | } 38 | 39 | export interface PatchInfo { 40 | hunks: { 41 | oldStart: number; 42 | oldLines: number; 43 | newStart: number; 44 | newLines: number; 45 | lines: string[]; 46 | }[]; 47 | } 48 | 49 | export interface PRSuggestion { 50 | describe: string; 51 | type: string; 52 | comment: string; 53 | code: string; 54 | filename: string; 55 | toString: () => string; 56 | identity: () => string; 57 | } 58 | 59 | export interface CodeSuggestion { 60 | file: string; 61 | line_start: number; 62 | line_end: number; 63 | correction: string; 64 | comment: string; 65 | } 66 | 67 | export interface ChatMessage { 68 | role: string; 69 | content: string; 70 | } 71 | 72 | export interface Review { 73 | review: BuilderResponse; 74 | suggestions: CodeSuggestion[]; 75 | } 76 | 77 | export interface BranchDetails { 78 | name: string; 79 | sha: string; 80 | url: string; 81 | } 82 | 83 | export const sleep = async (ms: number) => { 84 | return new Promise((resolve) => setTimeout(resolve, ms)); 85 | }; 86 | 87 | export const processGitFilepath = (filepath: string) => { 88 | // Remove the leading '/' if it exists 89 | return filepath.startsWith("/") ? filepath.slice(1) : filepath; 90 | }; 91 | 92 | export interface EnclosingContext { 93 | enclosingContext: Node | null; 94 | } 95 | 96 | export interface AbstractParser { 97 | findEnclosingContext( 98 | file: string, 99 | lineStart: number, 100 | lineEnd: number 101 | ): EnclosingContext; 102 | dryRun(file: string): { valid: boolean; error: string }; 103 | } 104 | 105 | const EXTENSIONS_TO_PARSERS: Map = new Map([ 106 | ["ts", new JavascriptParser()], 107 | ["tsx", new JavascriptParser()], 108 | ["js", new JavascriptParser()], 109 | ["jsx", new JavascriptParser()], 110 | ]); 111 | 112 | export const getParserForExtension = (filename: string) => { 113 | const fileExtension = filename.split(".").pop().toLowerCase(); 114 | return EXTENSIONS_TO_PARSERS.get(fileExtension) || null; 115 | }; 116 | 117 | export const assignLineNumbers = (contents: string): string => { 118 | const lines = contents.split("\n"); 119 | let lineNumber = 1; 120 | const linesWithNumbers = lines.map((line) => { 121 | const numberedLine = `${lineNumber}: ${line}`; 122 | lineNumber++; 123 | return numberedLine; 124 | }); 125 | return linesWithNumbers.join("\n"); 126 | }; 127 | -------------------------------------------------------------------------------- /src/context/language/javascript-parser.ts: -------------------------------------------------------------------------------- 1 | import { AbstractParser, EnclosingContext } from "../../constants"; 2 | import * as parser from "@babel/parser"; 3 | import traverse, { NodePath, Node } from "@babel/traverse"; 4 | 5 | const processNode = ( 6 | path: NodePath, 7 | lineStart: number, 8 | lineEnd: number, 9 | largestSize: number, 10 | largestEnclosingContext: Node | null 11 | ) => { 12 | const { start, end } = path.node.loc; 13 | if (start.line <= lineStart && lineEnd <= end.line) { 14 | const size = end.line - start.line; 15 | if (size > largestSize) { 16 | largestSize = size; 17 | largestEnclosingContext = path.node; 18 | } 19 | } 20 | return { largestSize, largestEnclosingContext }; 21 | }; 22 | 23 | export class JavascriptParser implements AbstractParser { 24 | findEnclosingContext( 25 | file: string, 26 | lineStart: number, 27 | lineEnd: number 28 | ): EnclosingContext { 29 | const ast = parser.parse(file, { 30 | sourceType: "module", 31 | plugins: ["jsx", "typescript"], // To allow JSX and TypeScript 32 | }); 33 | let largestEnclosingContext: Node = null; 34 | let largestSize = 0; 35 | traverse(ast, { 36 | Function(path) { 37 | ({ largestSize, largestEnclosingContext } = processNode( 38 | path, 39 | lineStart, 40 | lineEnd, 41 | largestSize, 42 | largestEnclosingContext 43 | )); 44 | }, 45 | TSInterfaceDeclaration(path) { 46 | ({ largestSize, largestEnclosingContext } = processNode( 47 | path, 48 | lineStart, 49 | lineEnd, 50 | largestSize, 51 | largestEnclosingContext 52 | )); 53 | }, 54 | }); 55 | return { 56 | enclosingContext: largestEnclosingContext, 57 | } as EnclosingContext; 58 | } 59 | 60 | dryRun(file: string): { valid: boolean; error: string } { 61 | try { 62 | const ast = parser.parse(file, { 63 | sourceType: "module", 64 | plugins: ["jsx", "typescript"], // To allow JSX and TypeScript 65 | }); 66 | return { 67 | valid: true, 68 | error: "", 69 | }; 70 | } catch (exc) { 71 | return { 72 | valid: false, 73 | error: exc, 74 | }; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/context/language/python-parser.ts: -------------------------------------------------------------------------------- 1 | import { AbstractParser, EnclosingContext } from "../../constants"; 2 | export class PythonParser implements AbstractParser { 3 | findEnclosingContext( 4 | file: string, 5 | lineStart: number, 6 | lineEnd: number 7 | ): EnclosingContext { 8 | // TODO: Implement this method for Python 9 | return null; 10 | } 11 | dryRun(file: string): { valid: boolean; error: string } { 12 | // TODO: Implement this method for Python 13 | return { valid: false, error: "Not implemented yet" }; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/context/review.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AbstractParser, 3 | PRFile, 4 | PatchInfo, 5 | getParserForExtension, 6 | } from "../constants"; 7 | import * as diff from "diff"; 8 | import { JavascriptParser } from "./language/javascript-parser"; 9 | import { Node } from "@babel/traverse"; 10 | 11 | const expandHunk = ( 12 | contents: string, 13 | hunk: diff.Hunk, 14 | linesAbove: number = 5, 15 | linesBelow: number = 5 16 | ) => { 17 | const fileLines = contents.split("\n"); 18 | const curExpansion: string[] = []; 19 | const start = Math.max(0, hunk.oldStart - 1 - linesAbove); 20 | const end = Math.min( 21 | fileLines.length, 22 | hunk.oldStart - 1 + hunk.oldLines + linesBelow 23 | ); 24 | 25 | for (let i = start; i < hunk.oldStart - 1; i++) { 26 | curExpansion.push(fileLines[i]); 27 | } 28 | 29 | curExpansion.push( 30 | `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@` 31 | ); 32 | hunk.lines.forEach((line) => { 33 | if (!curExpansion.includes(line)) { 34 | curExpansion.push(line); 35 | } 36 | }); 37 | 38 | for (let i = hunk.oldStart - 1 + hunk.oldLines; i < end; i++) { 39 | curExpansion.push(fileLines[i]); 40 | } 41 | return curExpansion.join("\n"); 42 | }; 43 | 44 | const expandFileLines = ( 45 | file: PRFile, 46 | linesAbove: number = 5, 47 | linesBelow: number = 5 48 | ) => { 49 | const fileLines = file.old_contents.split("\n"); 50 | const patches: PatchInfo[] = diff.parsePatch(file.patch); 51 | const expandedLines: string[][] = []; 52 | patches.forEach((patch) => { 53 | patch.hunks.forEach((hunk) => { 54 | const curExpansion: string[] = []; 55 | const start = Math.max(0, hunk.oldStart - 1 - linesAbove); 56 | const end = Math.min( 57 | fileLines.length, 58 | hunk.oldStart - 1 + hunk.oldLines + linesBelow 59 | ); 60 | 61 | for (let i = start; i < hunk.oldStart - 1; i++) { 62 | curExpansion.push(fileLines[i]); 63 | } 64 | 65 | curExpansion.push( 66 | `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@` 67 | ); 68 | hunk.lines.forEach((line) => { 69 | if (!curExpansion.includes(line)) { 70 | curExpansion.push(line); 71 | } 72 | }); 73 | 74 | for (let i = hunk.oldStart - 1 + hunk.oldLines; i < end; i++) { 75 | curExpansion.push(fileLines[i]); 76 | } 77 | expandedLines.push(curExpansion); 78 | }); 79 | }); 80 | 81 | return expandedLines; 82 | }; 83 | 84 | export const expandedPatchStrategy = (file: PRFile) => { 85 | const expandedPatches = expandFileLines(file); 86 | const expansions = expandedPatches 87 | .map((patchLines) => patchLines.join("\n")) 88 | .join("\n\n"); 89 | return `## ${file.filename}\n\n${expansions}`; 90 | }; 91 | 92 | export const rawPatchStrategy = (file: PRFile) => { 93 | return `## ${file.filename}\n\n${file.patch}`; 94 | }; 95 | 96 | const trimHunk = (hunk: diff.Hunk): diff.Hunk => { 97 | const startIdx = hunk.lines.findIndex( 98 | (line) => line.startsWith("+") || line.startsWith("-") 99 | ); 100 | const endIdx = hunk.lines 101 | .slice() 102 | .reverse() 103 | .findIndex((line) => line.startsWith("+") || line.startsWith("-")); 104 | const editLines = hunk.lines.slice(startIdx, hunk.lines.length - endIdx); 105 | return { ...hunk, lines: editLines, newStart: startIdx + hunk.newStart }; 106 | }; 107 | 108 | const buildingScopeString = ( 109 | currentFile: string, 110 | scope: Node, 111 | hunk: diff.Hunk 112 | ) => { 113 | const res: string[] = []; 114 | const trimmedHunk = trimHunk(hunk); 115 | const functionStartLine = scope.loc.start.line; 116 | const functionEndLine = scope.loc.end.line; 117 | const updatedFileLines = currentFile.split("\n"); 118 | // Extract the lines of the function 119 | const functionContext = updatedFileLines.slice( 120 | functionStartLine - 1, 121 | functionEndLine 122 | ); 123 | // Calculate the index where the changes should be injected into the function 124 | const injectionIdx = 125 | hunk.newStart - 126 | functionStartLine + 127 | hunk.lines.findIndex( 128 | (line) => line.startsWith("+") || line.startsWith("-") 129 | ); 130 | // Count the number of lines that should be dropped from the function 131 | const dropCount = trimmedHunk.lines.filter( 132 | (line) => !line.startsWith("-") 133 | ).length; 134 | 135 | const hunkHeader = `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`; 136 | // Inject the changes into the function, dropping the necessary lines 137 | functionContext.splice(injectionIdx, dropCount, ...trimmedHunk.lines); 138 | 139 | res.push(functionContext.join("\n")); 140 | res.unshift(hunkHeader); 141 | return res; 142 | }; 143 | 144 | /* 145 | line nums are 0 index, file is 1 index 146 | */ 147 | const combineHunks = ( 148 | file: string, 149 | overlappingHunks: diff.Hunk[] 150 | ): diff.Hunk => { 151 | if (!overlappingHunks || overlappingHunks.length === 0) { 152 | throw "Overlapping hunks are empty, this should never happen."; 153 | } 154 | const sortedHunks = overlappingHunks.sort((a, b) => a.newStart - b.newStart); 155 | const fileLines = file.split("\n"); 156 | let lastHunkEnd = sortedHunks[0].newStart + sortedHunks[0].newLines; 157 | 158 | const combinedHunk: diff.Hunk = { 159 | oldStart: sortedHunks[0].oldStart, 160 | oldLines: sortedHunks[0].oldLines, 161 | newStart: sortedHunks[0].newStart, 162 | newLines: sortedHunks[0].newLines, 163 | lines: [...sortedHunks[0].lines], 164 | linedelimiters: [...sortedHunks[0].linedelimiters], 165 | }; 166 | 167 | for (let i = 1; i < sortedHunks.length; i++) { 168 | const hunk = sortedHunks[i]; 169 | 170 | // If there's a gap between the last hunk and this one, add the lines in between 171 | if (hunk.newStart > lastHunkEnd) { 172 | combinedHunk.lines.push( 173 | ...fileLines.slice(lastHunkEnd - 1, hunk.newStart - 1) 174 | ); 175 | combinedHunk.newLines += hunk.newStart - lastHunkEnd; 176 | } 177 | 178 | combinedHunk.oldLines += hunk.oldLines; 179 | combinedHunk.newLines += hunk.newLines; 180 | combinedHunk.lines.push(...hunk.lines); 181 | combinedHunk.linedelimiters.push(...hunk.linedelimiters); 182 | 183 | lastHunkEnd = hunk.newStart + hunk.newLines; 184 | } 185 | return combinedHunk; 186 | }; 187 | 188 | const diffContextPerHunk = (file: PRFile, parser: AbstractParser) => { 189 | const updatedFile = diff.applyPatch(file.old_contents, file.patch); 190 | const patches = diff.parsePatch(file.patch); 191 | if (!updatedFile || typeof updatedFile !== "string") { 192 | console.log("APPLYING PATCH ERROR - FALLINGBACK"); 193 | throw "THIS SHOULD NOT HAPPEN!"; 194 | } 195 | 196 | const hunks: diff.Hunk[] = []; 197 | const order: number[] = []; 198 | const scopeRangeHunkMap = new Map(); 199 | const scopeRangeNodeMap = new Map(); 200 | const expandStrategy: diff.Hunk[] = []; 201 | 202 | patches.forEach((p) => { 203 | p.hunks.forEach((hunk) => { 204 | hunks.push(hunk); 205 | }); 206 | }); 207 | 208 | hunks.forEach((hunk, idx) => { 209 | try { 210 | const trimmedHunk = trimHunk(hunk); 211 | const insertions = hunk.lines.filter((line) => 212 | line.startsWith("+") 213 | ).length; 214 | const lineStart = trimmedHunk.newStart; 215 | const lineEnd = lineStart + insertions; 216 | const largestEnclosingFunction = parser.findEnclosingContext( 217 | updatedFile, 218 | lineStart, 219 | lineEnd 220 | ).enclosingContext; 221 | 222 | if (largestEnclosingFunction) { 223 | const enclosingRangeKey = `${largestEnclosingFunction.loc.start.line} -> ${largestEnclosingFunction.loc.end.line}`; 224 | let existingHunks = scopeRangeHunkMap.get(enclosingRangeKey) || []; 225 | existingHunks.push(hunk); 226 | scopeRangeHunkMap.set(enclosingRangeKey, existingHunks); 227 | scopeRangeNodeMap.set(enclosingRangeKey, largestEnclosingFunction); 228 | } else { 229 | throw "No enclosing function."; 230 | } 231 | order.push(idx); 232 | } catch (exc) { 233 | console.log(file.filename); 234 | console.log("NORMAL STRATEGY"); 235 | console.log(exc); 236 | expandStrategy.push(hunk); 237 | order.push(idx); 238 | } 239 | }); 240 | 241 | const scopeStategy: [string, diff.Hunk][] = []; // holds map range key and combined hunk: [[key, hunk]] 242 | for (const [range, hunks] of scopeRangeHunkMap.entries()) { 243 | const combinedHunk = combineHunks(updatedFile, hunks); 244 | scopeStategy.push([range, combinedHunk]); 245 | } 246 | 247 | const contexts: string[] = []; 248 | scopeStategy.forEach(([rangeKey, hunk]) => { 249 | const context = buildingScopeString( 250 | updatedFile, 251 | scopeRangeNodeMap.get(rangeKey), 252 | hunk 253 | ).join("\n"); 254 | contexts.push(context); 255 | }); 256 | expandStrategy.forEach((hunk) => { 257 | const context = expandHunk(file.old_contents, hunk); 258 | contexts.push(context); 259 | }); 260 | return contexts; 261 | }; 262 | 263 | const functionContextPatchStrategy = ( 264 | file: PRFile, 265 | parser: AbstractParser 266 | ): string => { 267 | let res = null; 268 | try { 269 | const contextChunks = diffContextPerHunk(file, parser); 270 | res = `## ${file.filename}\n\n${contextChunks.join("\n\n")}`; 271 | } catch (exc) { 272 | console.log(exc); 273 | res = expandedPatchStrategy(file); 274 | } 275 | return res; 276 | }; 277 | 278 | export const smarterContextPatchStrategy = (file: PRFile) => { 279 | const parser: AbstractParser = getParserForExtension(file.filename); 280 | if (parser != null) { 281 | return functionContextPatchStrategy(file, parser); 282 | } else { 283 | return expandedPatchStrategy(file); 284 | } 285 | }; 286 | -------------------------------------------------------------------------------- /src/data/PRSuggestionImpl.ts: -------------------------------------------------------------------------------- 1 | import { PRSuggestion } from "../constants"; 2 | 3 | export class PRSuggestionImpl implements PRSuggestion { 4 | describe: string; 5 | type: string; 6 | comment: string; 7 | code: string; 8 | filename: string; 9 | 10 | constructor( 11 | describe: string, 12 | type: string, 13 | comment: string, 14 | code: string, 15 | filename: string 16 | ) { 17 | this.describe = describe; 18 | this.type = type; 19 | this.comment = comment; 20 | this.code = code; 21 | this.filename = filename; 22 | } 23 | 24 | toString(): string { 25 | const xmlElements = [ 26 | ``, 27 | ` ${this.describe}`, 28 | ` ${this.type}`, 29 | ` ${this.comment}`, 30 | ` ${this.code}`, 31 | ` ${this.filename}`, 32 | ``, 33 | ]; 34 | return xmlElements.join("\n"); 35 | } 36 | 37 | identity(): string { 38 | return `${this.filename}:${this.comment}`; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/env.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from "dotenv"; 2 | import { createPrivateKey } from "crypto"; 3 | import chalk from "chalk"; 4 | 5 | dotenv.config(); 6 | 7 | export const env = { 8 | GITHUB_APP_ID: process.env.GITHUB_APP_ID, 9 | GITHUB_PRIVATE_KEY: process.env.GITHUB_PRIVATE_KEY, 10 | GITHUB_WEBHOOK_SECRET: process.env.GITHUB_WEBHOOK_SECRET, 11 | GROQ_API_KEY: process.env.GROQ_API_KEY, 12 | } as const; 13 | 14 | let valid = true; 15 | 16 | for (const key in env) { 17 | if (!env[key as keyof typeof env]) { 18 | console.log( 19 | chalk.red("✖") + 20 | chalk.gray(" Missing required env var: ") + 21 | chalk.bold(`process.env.${key}`) 22 | ); 23 | valid = false; 24 | } 25 | } 26 | 27 | try { 28 | createPrivateKey(env.GITHUB_PRIVATE_KEY); 29 | } catch (error) { 30 | console.log( 31 | chalk.red( 32 | "\n✖ Invalid GitHub private key format for " + 33 | chalk.bold(`process.env.GITHUB_PRIVATE_KEY`) + 34 | "\n" 35 | ) + 36 | chalk.gray(" • Must start with: ") + 37 | chalk.bold("-----BEGIN RSA PRIVATE KEY-----\n") + 38 | chalk.gray(" • Must end with: ") + 39 | chalk.bold("-----END RSA PRIVATE KEY-----\n") 40 | ); 41 | valid = false; 42 | } 43 | 44 | if (!valid) { 45 | console.log( 46 | chalk.yellow("\n⚠ ") + 47 | chalk.bold("Please check your .env file and try again.\n") 48 | ); 49 | process.exit(1); 50 | } 51 | -------------------------------------------------------------------------------- /src/llms/chat.ts: -------------------------------------------------------------------------------- 1 | import { ChatCompletionCreateParamsNonStreaming } from "groq-sdk/resources/chat/completions"; 2 | import { groq, GROQ_MODEL } from "./groq"; 3 | 4 | export const generateChatCompletion = async ( 5 | options: Omit 6 | ) => { 7 | const response = await groq.chat.completions.create({ 8 | model: GROQ_MODEL, 9 | temperature: 0, 10 | ...options, 11 | }); 12 | return response.choices[0].message; 13 | }; 14 | -------------------------------------------------------------------------------- /src/llms/groq.ts: -------------------------------------------------------------------------------- 1 | import { Groq } from "groq-sdk"; 2 | import { env } from "../env"; 3 | import { ChatCompletionCreateParamsBase } from "groq-sdk/resources/chat/completions"; 4 | 5 | export const groq = new Groq({ 6 | apiKey: env.GROQ_API_KEY, 7 | }); 8 | 9 | export type GroqChatModel = ChatCompletionCreateParamsBase["model"]; 10 | 11 | export const GROQ_MODEL: GroqChatModel = "mixtral-8x7b-32768"; 12 | -------------------------------------------------------------------------------- /src/prompts.ts: -------------------------------------------------------------------------------- 1 | import { encode, encodeChat } from "gpt-tokenizer"; 2 | import type { ChatCompletionMessageParam } from "groq-sdk/resources/chat/completions"; 3 | import type { PRFile } from "./constants"; 4 | import { 5 | rawPatchStrategy, 6 | smarterContextPatchStrategy, 7 | } from "./context/review"; 8 | import { GROQ_MODEL, type GroqChatModel } from "./llms/groq"; 9 | 10 | const ModelsToTokenLimits: Record = { 11 | "mixtral-8x7b-32768": 32768, 12 | "gemma-7b-it": 32768, 13 | "llama3-70b-8192": 8192, 14 | "llama3-8b-8192": 8192, 15 | }; 16 | 17 | export const REVIEW_DIFF_PROMPT = `You are PR-Reviewer, a language model designed to review git pull requests. 18 | Your task is to provide constructive and concise feedback for the PR, and also provide meaningful code suggestions. 19 | 20 | Example PR Diff input: 21 | ' 22 | ## src/file1.py 23 | 24 | @@ -12,5 +12,5 @@ def func1(): 25 | code line that already existed in the file... 26 | code line that already existed in the file.... 27 | -code line that was removed in the PR 28 | +new code line added in the PR 29 | code line that already existed in the file... 30 | code line that already existed in the file... 31 | 32 | @@ ... @@ def func2(): 33 | ... 34 | 35 | 36 | ## src/file2.py 37 | ... 38 | ' 39 | 40 | The review should focus on new code added in the PR (lines starting with '+'), and not on code that already existed in the file (lines starting with '-', or without prefix). 41 | 42 | - ONLY PROVIDE CODE SUGGESTIONS 43 | - Focus on important suggestions like fixing code problems, improving performance, improving security, improving readability 44 | - Avoid making suggestions that have already been implemented in the PR code. For example, if you want to add logs, or change a variable to const, or anything else, make sure it isn't already in the PR code. 45 | - Don't suggest adding docstring, type hints, or comments. 46 | - Suggestions should focus on improving the new code added in the PR (lines starting with '+') 47 | - Do not say things like without seeing the full repo, or full code, or rest of the codebase. Comment only on the code you have! 48 | 49 | Make sure the provided code suggestions are in the same programming language. 50 | 51 | Don't repeat the prompt in the answer, and avoid outputting the 'type' and 'description' fields. 52 | 53 | Think through your suggestions and make exceptional improvements.`; 54 | 55 | export const XML_PR_REVIEW_PROMPT = `As the PR-Reviewer AI model, you are tasked to analyze git pull requests across any programming language and provide comprehensive and precise code enhancements. Keep your focus on the new code modifications indicated by '+' lines in the PR. Your feedback should hunt for code issues, opportunities for performance enhancement, security improvements, and ways to increase readability. 56 | 57 | Ensure your suggestions are novel and haven't been previously incorporated in the '+' lines of the PR code. Refrain from proposing enhancements that add docstrings, type hints, or comments. Your recommendations should strictly target the '+' lines without suggesting the need for complete context such as the whole repo or codebase. 58 | 59 | Your code suggestions should match the programming language in the PR, steer clear of needless repetition or inclusion of 'type' and 'description' fields. 60 | 61 | Formulate thoughtful suggestions aimed at strengthening performance, security, and readability, and represent them in an XML format utilizing the tags: , , , , , , . While multiple recommendations can be given, they should all reside within one tag. 62 | 63 | Also note, all your code suggestions should follow the valid Markdown syntax for GitHub, identifying the language they're written in, and should be enclosed within backticks (\`\`\`). 64 | 65 | Don't hesitate to add as many constructive suggestions as are relevant to really improve the effectivity of the code. 66 | 67 | Example output: 68 | \`\`\` 69 | 70 | 71 | [Objective of the newly incorporated code] 72 | [Category of the given suggestion such as performance, security, etc.] 73 | [Guidance on enhancing the new code] 74 | 75 | \`\`\`[Programming Language] 76 | [Equivalent code amendment in the same language] 77 | \`\`\` 78 | 79 | [name of relevant file] 80 | 81 | 82 | ... 83 | 84 | ... 85 | 86 | \`\`\` 87 | 88 | Note: The 'comment' and 'describe' tags should elucidate the advice and why it’s given, while the 'code' tag hosts the recommended code snippet within proper GitHub Markdown syntax. The 'type' defines the suggestion's category such as performance, security, readability, etc.`; 89 | 90 | export const PR_SUGGESTION_TEMPLATE = `{COMMENT} 91 | {ISSUE_LINK} 92 | 93 | {CODE} 94 | `; 95 | 96 | const assignLineNumbers = (diff: string) => { 97 | const lines = diff.split("\n"); 98 | let newLine = 0; 99 | const lineNumbers = []; 100 | 101 | for (const line of lines) { 102 | if (line.startsWith("@@")) { 103 | // This is a chunk header. Parse the line numbers. 104 | const match = line.match(/@@ -\d+,\d+ \+(\d+),\d+ @@/); 105 | newLine = parseInt(match[1]); 106 | lineNumbers.push(line); // keep chunk headers as is 107 | } else if (!line.startsWith("-")) { 108 | // This is a line from the new file. 109 | lineNumbers.push(`${newLine++}: ${line}`); 110 | } 111 | } 112 | 113 | return lineNumbers.join("\n"); 114 | }; 115 | 116 | export const buildSuggestionPrompt = (file: PRFile) => { 117 | const rawPatch = String.raw`${file.patch}`; 118 | const patchWithLines = assignLineNumbers(rawPatch); 119 | return `## ${file.filename}\n\n${patchWithLines}`; 120 | }; 121 | 122 | export const buildPatchPrompt = (file: PRFile) => { 123 | if (file.old_contents == null) { 124 | return rawPatchStrategy(file); 125 | } else { 126 | return smarterContextPatchStrategy(file); 127 | } 128 | }; 129 | 130 | export const getReviewPrompt = (diff: string): ChatCompletionMessageParam[] => { 131 | return [ 132 | { role: "system", content: REVIEW_DIFF_PROMPT }, 133 | { role: "user", content: diff }, 134 | ]; 135 | }; 136 | 137 | export const getXMLReviewPrompt = ( 138 | diff: string 139 | ): ChatCompletionMessageParam[] => { 140 | return [ 141 | { role: "system", content: XML_PR_REVIEW_PROMPT }, 142 | { role: "user", content: diff }, 143 | ]; 144 | }; 145 | 146 | export const constructPrompt = ( 147 | files: PRFile[], 148 | patchBuilder: (file: PRFile) => string, 149 | convoBuilder: (diff: string) => ChatCompletionMessageParam[] 150 | ) => { 151 | const patches = files.map((file) => patchBuilder(file)); 152 | const diff = patches.join("\n"); 153 | const convo = convoBuilder(diff); 154 | return convo; 155 | }; 156 | 157 | export const getTokenLength = (blob: string) => { 158 | return encode(blob).length; 159 | }; 160 | 161 | export const isConversationWithinLimit = ( 162 | convo: any[], 163 | model: GroqChatModel = GROQ_MODEL 164 | ) => { 165 | // We don't have the encoder for our Groq model, so we're using 166 | // the one for gpt-3.5-turbo as a rough equivalent. 167 | const convoTokens = encodeChat(convo, "gpt-3.5-turbo").length; 168 | return convoTokens < ModelsToTokenLimits[model]; 169 | }; 170 | -------------------------------------------------------------------------------- /src/prompts/inline-prompt.ts: -------------------------------------------------------------------------------- 1 | import { ChatCompletionMessageParam } from "groq-sdk/resources/chat/completions"; 2 | import { PRSuggestion } from "../constants"; 3 | 4 | export const INLINE_FIX_PROMPT = `In this task, you are provided with a code suggestion in XML format, along with the corresponding file content. Your task is to radiate from this suggestion and draft a precise code fix. Here's how your input will look: 5 | 6 | \`\`\`xml 7 | 8 | Your Description Here 9 | Your Type Here 10 | Your Suggestions Here 11 | Original Code Here 12 | File Name Here 13 | 14 | \`\`\` 15 | 16 | {file} 17 | 18 | The 'comment' field contains specific code modification instructions. Based on these instructions, you're required to formulate a precise code fix. Bear in mind that the fix must include only the lines between the starting line (linestart) and ending line (lineend) where the changes are applied. 19 | 20 | The adjusted code doesn't necessarily need to be standalone valid code, but when incorporated into the corresponding file, it must result in valid, functional code, without errors. Ensure to include only the specific lines affected by the modifications. Avoid including placeholders such as 'rest of code...' 21 | 22 | Please interpret the given directions and apply the necessary changes to the provided suggestion and file content. Make the modifications unambiguous and appropriate for utilizing in an inline suggestion on GitHub.`; 23 | 24 | export const INLINE_FIX_FUNCTION = { 25 | name: "fix", 26 | description: "The code fix to address the suggestion and rectify the issue", 27 | parameters: { 28 | type: "object", 29 | properties: { 30 | comment: { 31 | type: "string", 32 | description: "Why this change improves the code", 33 | }, 34 | code: { 35 | type: "string", 36 | description: "Modified Code Snippet", 37 | }, 38 | lineStart: { 39 | type: "number", 40 | description: "Starting Line Number", 41 | }, 42 | lineEnd: { 43 | type: "number", 44 | description: "Ending Line Number", 45 | }, 46 | }, 47 | }, 48 | required: ["action"], 49 | }; 50 | 51 | const INLINE_USER_MESSAGE_TEMPLATE = `{SUGGESTION} 52 | 53 | {FILE}`; 54 | 55 | const assignFullLineNumers = (contents: string): string => { 56 | const lines = contents.split("\n"); 57 | let lineNumber = 1; 58 | const linesWithNumbers = lines.map((line) => { 59 | const numberedLine = `${lineNumber}: ${line}`; 60 | lineNumber++; 61 | return numberedLine; 62 | }); 63 | return linesWithNumbers.join("\n"); 64 | }; 65 | 66 | export const getInlineFixPrompt = ( 67 | fileContents: string, 68 | suggestion: PRSuggestion 69 | ): ChatCompletionMessageParam[] => { 70 | const userMessage = INLINE_USER_MESSAGE_TEMPLATE.replace( 71 | "{SUGGESTION}", 72 | suggestion.toString() 73 | ).replace("{FILE}", assignFullLineNumers(fileContents)); 74 | return [ 75 | { role: "system", content: INLINE_FIX_PROMPT }, 76 | { role: "user", content: userMessage }, 77 | ]; 78 | }; 79 | -------------------------------------------------------------------------------- /src/review-agent.ts: -------------------------------------------------------------------------------- 1 | import { Octokit } from "@octokit/rest"; 2 | import { WebhookEventMap } from "@octokit/webhooks-definitions/schema"; 3 | import { ChatCompletionMessageParam } from "groq-sdk/resources/chat/completions"; 4 | import * as xml2js from "xml2js"; 5 | import type { 6 | BranchDetails, 7 | BuilderResponse, 8 | Builders, 9 | CodeSuggestion, 10 | PRFile, 11 | PRSuggestion, 12 | } from "./constants"; 13 | import { PRSuggestionImpl } from "./data/PRSuggestionImpl"; 14 | import { generateChatCompletion } from "./llms/chat"; 15 | import { 16 | PR_SUGGESTION_TEMPLATE, 17 | buildPatchPrompt, 18 | constructPrompt, 19 | getReviewPrompt, 20 | getTokenLength, 21 | getXMLReviewPrompt, 22 | isConversationWithinLimit, 23 | } from "./prompts"; 24 | import { 25 | INLINE_FIX_FUNCTION, 26 | getInlineFixPrompt, 27 | } from "./prompts/inline-prompt"; 28 | import { getGitFile } from "./reviews"; 29 | 30 | export const reviewDiff = async (messages: ChatCompletionMessageParam[]) => { 31 | const message = await generateChatCompletion({ 32 | messages, 33 | }); 34 | return message.content; 35 | }; 36 | 37 | export const reviewFiles = async ( 38 | files: PRFile[], 39 | patchBuilder: (file: PRFile) => string, 40 | convoBuilder: (diff: string) => ChatCompletionMessageParam[] 41 | ) => { 42 | const patches = files.map((file) => patchBuilder(file)); 43 | const messages = convoBuilder(patches.join("\n")); 44 | const feedback = await reviewDiff(messages); 45 | return feedback; 46 | }; 47 | 48 | const filterFile = (file: PRFile) => { 49 | const extensionsToIgnore = new Set([ 50 | "pdf", 51 | "png", 52 | "jpg", 53 | "jpeg", 54 | "gif", 55 | "mp4", 56 | "mp3", 57 | "md", 58 | "json", 59 | "env", 60 | "toml", 61 | "svg", 62 | ]); 63 | const filesToIgnore = new Set([ 64 | "package-lock.json", 65 | "yarn.lock", 66 | ".gitignore", 67 | "package.json", 68 | "tsconfig.json", 69 | "poetry.lock", 70 | "readme.md", 71 | ]); 72 | const filename = file.filename.toLowerCase().split("/").pop(); 73 | if (filename && filesToIgnore.has(filename)) { 74 | console.log(`Filtering out ignored file: ${file.filename}`); 75 | return false; 76 | } 77 | const splitFilename = file.filename.toLowerCase().split("."); 78 | if (splitFilename.length <= 1) { 79 | console.log(`Filtering out file with no extension: ${file.filename}`); 80 | return false; 81 | } 82 | const extension = splitFilename.pop()?.toLowerCase(); 83 | if (extension && extensionsToIgnore.has(extension)) { 84 | console.log(`Filtering out file with ignored extension: ${file.filename} (.${extension})`); 85 | return false; 86 | } 87 | return true; 88 | }; 89 | 90 | const groupFilesByExtension = (files: PRFile[]): Map => { 91 | const filesByExtension: Map = new Map(); 92 | 93 | files.forEach((file) => { 94 | const extension = file.filename.split(".").pop()?.toLowerCase(); 95 | if (extension) { 96 | if (!filesByExtension.has(extension)) { 97 | filesByExtension.set(extension, []); 98 | } 99 | filesByExtension.get(extension)?.push(file); 100 | } 101 | }); 102 | 103 | return filesByExtension; 104 | }; 105 | 106 | // all of the files here can be processed with the prompt at minimum 107 | const processWithinLimitFiles = ( 108 | files: PRFile[], 109 | patchBuilder: (file: PRFile) => string, 110 | convoBuilder: (diff: string) => ChatCompletionMessageParam[] 111 | ) => { 112 | const processGroups: PRFile[][] = []; 113 | const convoWithinModelLimit = isConversationWithinLimit( 114 | constructPrompt(files, patchBuilder, convoBuilder) 115 | ); 116 | 117 | console.log(`Within model token limits: ${convoWithinModelLimit}`); 118 | if (!convoWithinModelLimit) { 119 | const grouped = groupFilesByExtension(files); 120 | for (const [extension, filesForExt] of grouped.entries()) { 121 | const extGroupWithinModelLimit = isConversationWithinLimit( 122 | constructPrompt(filesForExt, patchBuilder, convoBuilder) 123 | ); 124 | if (extGroupWithinModelLimit) { 125 | processGroups.push(filesForExt); 126 | } else { 127 | // extension group exceeds model limit 128 | console.log( 129 | "Processing files per extension that exceed model limit ..." 130 | ); 131 | let currentGroup: PRFile[] = []; 132 | filesForExt.sort((a, b) => a.patchTokenLength - b.patchTokenLength); 133 | filesForExt.forEach((file) => { 134 | const isPotentialGroupWithinLimit = isConversationWithinLimit( 135 | constructPrompt([...currentGroup, file], patchBuilder, convoBuilder) 136 | ); 137 | if (isPotentialGroupWithinLimit) { 138 | currentGroup.push(file); 139 | } else { 140 | processGroups.push(currentGroup); 141 | currentGroup = [file]; 142 | } 143 | }); 144 | if (currentGroup.length > 0) { 145 | processGroups.push(currentGroup); 146 | } 147 | } 148 | } 149 | } else { 150 | processGroups.push(files); 151 | } 152 | return processGroups; 153 | }; 154 | 155 | const stripRemovedLines = (originalFile: PRFile) => { 156 | // remove lines starting with a '-' 157 | const originalPatch = String.raw`${originalFile.patch}`; 158 | const strippedPatch = originalPatch 159 | .split("\n") 160 | .filter((line) => !line.startsWith("-")) 161 | .join("\n"); 162 | return { ...originalFile, patch: strippedPatch }; 163 | }; 164 | 165 | const processOutsideLimitFiles = ( 166 | files: PRFile[], 167 | patchBuilder: (file: PRFile) => string, 168 | convoBuilder: (diff: string) => ChatCompletionMessageParam[] 169 | ) => { 170 | const processGroups: PRFile[][] = []; 171 | if (files.length == 0) { 172 | return processGroups; 173 | } 174 | files = files.map((file) => stripRemovedLines(file)); 175 | const convoWithinModelLimit = isConversationWithinLimit( 176 | constructPrompt(files, patchBuilder, convoBuilder) 177 | ); 178 | if (convoWithinModelLimit) { 179 | processGroups.push(files); 180 | } else { 181 | const exceedingLimits: PRFile[] = []; 182 | const withinLimits: PRFile[] = []; 183 | files.forEach((file) => { 184 | const isFileConvoWithinLimits = isConversationWithinLimit( 185 | constructPrompt([file], patchBuilder, convoBuilder) 186 | ); 187 | if (isFileConvoWithinLimits) { 188 | withinLimits.push(file); 189 | } else { 190 | exceedingLimits.push(file); 191 | } 192 | }); 193 | const withinLimitsGroup = processWithinLimitFiles( 194 | withinLimits, 195 | patchBuilder, 196 | convoBuilder 197 | ); 198 | withinLimitsGroup.forEach((group) => { 199 | processGroups.push(group); 200 | }); 201 | if (exceedingLimits.length > 0) { 202 | console.log("TODO: Need to further chunk large file changes."); 203 | // throw "Unimplemented" 204 | } 205 | } 206 | return processGroups; 207 | }; 208 | 209 | const processXMLSuggestions = async (feedbacks: string[]) => { 210 | const xmlParser = new xml2js.Parser(); 211 | const parsedSuggestions = await Promise.all( 212 | feedbacks.map((fb) => { 213 | fb = fb 214 | .split("") 215 | .join("") 217 | .join("]]>"); 218 | console.log(fb); 219 | return xmlParser.parseStringPromise(fb); 220 | }) 221 | ); 222 | // gets suggestion arrays [[suggestion], [suggestion]], then flattens 223 | const allSuggestions = parsedSuggestions 224 | .map((sug) => sug.review.suggestion) 225 | .flat(1); 226 | const suggestions: PRSuggestion[] = allSuggestions.map((rawSuggestion) => { 227 | const lines = rawSuggestion.code[0].trim().split("\n"); 228 | lines[0] = lines[0].trim(); 229 | lines[lines.length - 1] = lines[lines.length - 1].trim(); 230 | const code = lines.join("\n"); 231 | 232 | return new PRSuggestionImpl( 233 | rawSuggestion.describe[0], 234 | rawSuggestion.type[0], 235 | rawSuggestion.comment[0], 236 | code, 237 | rawSuggestion.filename[0] 238 | ); 239 | }); 240 | return suggestions; 241 | }; 242 | 243 | const generateGithubIssueUrl = ( 244 | owner: string, 245 | repoName: string, 246 | title: string, 247 | body: string, 248 | codeblock?: string 249 | ) => { 250 | const encodedTitle = encodeURIComponent(title); 251 | const encodedBody = encodeURIComponent(body); 252 | const encodedCodeBlock = codeblock 253 | ? encodeURIComponent(`\n${codeblock}\n`) 254 | : ""; 255 | 256 | let url = `https://github.com/${owner}/${repoName}/issues/new?title=${encodedTitle}&body=${encodedBody}${encodedCodeBlock}`; 257 | 258 | if (url.length > 2048) { 259 | url = `https://github.com/${owner}/${repoName}/issues/new?title=${encodedTitle}&body=${encodedBody}`; 260 | } 261 | return `[Create Issue](${url})`; 262 | }; 263 | 264 | export const dedupSuggestions = ( 265 | suggestions: PRSuggestion[] 266 | ): PRSuggestion[] => { 267 | const suggestionsMap = new Map(); 268 | suggestions.forEach((suggestion) => { 269 | suggestionsMap.set(suggestion.identity(), suggestion); 270 | }); 271 | return Array.from(suggestionsMap.values()); 272 | }; 273 | 274 | const convertPRSuggestionToComment = ( 275 | owner: string, 276 | repo: string, 277 | suggestions: PRSuggestion[] 278 | ): string[] => { 279 | const suggestionsMap = new Map(); 280 | suggestions.forEach((suggestion) => { 281 | if (!suggestionsMap.has(suggestion.filename)) { 282 | suggestionsMap.set(suggestion.filename, []); 283 | } 284 | suggestionsMap.get(suggestion.filename).push(suggestion); 285 | }); 286 | const comments: string[] = []; 287 | for (let [filename, suggestions] of suggestionsMap) { 288 | const temp = [`## ${filename}\n`]; 289 | suggestions.forEach((suggestion: PRSuggestion) => { 290 | const issueLink = generateGithubIssueUrl( 291 | owner, 292 | repo, 293 | suggestion.describe, 294 | suggestion.comment, 295 | suggestion.code 296 | ); 297 | temp.push( 298 | PR_SUGGESTION_TEMPLATE.replace("{COMMENT}", suggestion.comment) 299 | .replace("{CODE}", suggestion.code) 300 | .replace("{ISSUE_LINK}", issueLink) 301 | ); 302 | }); 303 | comments.push(temp.join("\n")); 304 | } 305 | return comments; 306 | }; 307 | 308 | const xmlResponseBuilder = async ( 309 | owner: string, 310 | repoName: string, 311 | feedbacks: string[] 312 | ): Promise => { 313 | console.log("IN XML RESPONSE BUILDER"); 314 | const parsedXMLSuggestions = await processXMLSuggestions(feedbacks); 315 | const comments = convertPRSuggestionToComment( 316 | owner, 317 | repoName, 318 | dedupSuggestions(parsedXMLSuggestions) 319 | ); 320 | const commentBlob = comments.join("\n"); 321 | return { comment: commentBlob, structuredComments: parsedXMLSuggestions }; 322 | }; 323 | 324 | const curriedXmlResponseBuilder = (owner: string, repoName: string) => { 325 | return (feedbacks: string[]) => 326 | xmlResponseBuilder(owner, repoName, feedbacks); 327 | }; 328 | 329 | const basicResponseBuilder = async ( 330 | feedbacks: string[] 331 | ): Promise => { 332 | console.log("IN BASIC RESPONSE BUILDER"); 333 | const commentBlob = feedbacks.join("\n"); 334 | return { comment: commentBlob, structuredComments: [] }; 335 | }; 336 | 337 | export const reviewChanges = async ( 338 | files: PRFile[], 339 | convoBuilder: (diff: string) => ChatCompletionMessageParam[], 340 | responseBuilder: (responses: string[]) => Promise 341 | ) => { 342 | const patchBuilder = buildPatchPrompt; 343 | const filteredFiles = files.filter((file) => filterFile(file)); 344 | filteredFiles.map((file) => { 345 | file.patchTokenLength = getTokenLength(patchBuilder(file)); 346 | }); 347 | // further subdivide if necessary, maybe group files by common extension? 348 | const patchesWithinModelLimit: PRFile[] = []; 349 | // these single file patches are larger than the full model context 350 | const patchesOutsideModelLimit: PRFile[] = []; 351 | 352 | filteredFiles.forEach((file) => { 353 | const patchWithPromptWithinLimit = isConversationWithinLimit( 354 | constructPrompt([file], patchBuilder, convoBuilder) 355 | ); 356 | if (patchWithPromptWithinLimit) { 357 | patchesWithinModelLimit.push(file); 358 | } else { 359 | patchesOutsideModelLimit.push(file); 360 | } 361 | }); 362 | 363 | console.log(`files within limits: ${patchesWithinModelLimit.length}`); 364 | const withinLimitsPatchGroups = processWithinLimitFiles( 365 | patchesWithinModelLimit, 366 | patchBuilder, 367 | convoBuilder 368 | ); 369 | const exceedingLimitsPatchGroups = processOutsideLimitFiles( 370 | patchesOutsideModelLimit, 371 | patchBuilder, 372 | convoBuilder 373 | ); 374 | console.log(`${withinLimitsPatchGroups.length} within limits groups.`); 375 | console.log( 376 | `${patchesOutsideModelLimit.length} files outside limit, skipping them.` 377 | ); 378 | 379 | const groups = [...withinLimitsPatchGroups, ...exceedingLimitsPatchGroups]; 380 | 381 | const feedbacks = await Promise.all( 382 | groups.map((patchGroup) => { 383 | return reviewFiles(patchGroup, patchBuilder, convoBuilder); 384 | }) 385 | ); 386 | try { 387 | return await responseBuilder(feedbacks); 388 | } catch (exc) { 389 | console.log("XML parsing error"); 390 | console.log(exc); 391 | throw exc; 392 | } 393 | }; 394 | 395 | const indentCodeFix = ( 396 | file: string, 397 | code: string, 398 | lineStart: number 399 | ): string => { 400 | const fileLines = file.split("\n"); 401 | const firstLine = fileLines[lineStart - 1]; 402 | const codeLines = code.split("\n"); 403 | const indentation = firstLine.match(/^(\s*)/)[0]; 404 | const indentedCodeLines = codeLines.map((line) => indentation + line); 405 | return indentedCodeLines.join("\n"); 406 | }; 407 | 408 | const isCodeSuggestionNew = ( 409 | contents: string, 410 | suggestion: CodeSuggestion 411 | ): boolean => { 412 | const fileLines = contents.split("\n"); 413 | const targetLines = fileLines 414 | .slice(suggestion.line_start - 1, suggestion.line_end) 415 | .join("\n"); 416 | if (targetLines.trim() == suggestion.correction.trim()) { 417 | // same as existing code. 418 | return false; 419 | } 420 | return true; 421 | }; 422 | 423 | export const generateInlineComments = async ( 424 | suggestion: PRSuggestion, 425 | file: PRFile 426 | ): Promise => { 427 | try { 428 | const messages = getInlineFixPrompt(file.current_contents, suggestion); 429 | const { function_call } = await generateChatCompletion({ 430 | messages, 431 | functions: [INLINE_FIX_FUNCTION], 432 | function_call: { name: INLINE_FIX_FUNCTION.name }, 433 | }); 434 | if (!function_call) { 435 | throw new Error("No function call found"); 436 | } 437 | const args = JSON.parse(function_call.arguments); 438 | const initialCode = String.raw`${args["code"]}`; 439 | const indentedCode = indentCodeFix( 440 | file.current_contents, 441 | initialCode, 442 | args["lineStart"] 443 | ); 444 | const codeFix = { 445 | file: suggestion.filename, 446 | line_start: args["lineStart"], 447 | line_end: args["lineEnd"], 448 | correction: indentedCode, 449 | comment: args["comment"], 450 | }; 451 | if (isCodeSuggestionNew(file.current_contents, codeFix)) { 452 | return codeFix; 453 | } 454 | return null; 455 | } catch (exc) { 456 | console.log(exc); 457 | return null; 458 | } 459 | }; 460 | 461 | const preprocessFile = async ( 462 | octokit: Octokit, 463 | payload: WebhookEventMap["pull_request"], 464 | file: PRFile 465 | ) => { 466 | const { base, head } = payload.pull_request; 467 | const baseBranch: BranchDetails = { 468 | name: base.ref, 469 | sha: base.sha, 470 | url: payload.pull_request.url, 471 | }; 472 | const currentBranch: BranchDetails = { 473 | name: head.ref, 474 | sha: head.sha, 475 | url: payload.pull_request.url, 476 | }; 477 | // Handle scenario where file does not exist!! 478 | const [oldContents, currentContents] = await Promise.all([ 479 | getGitFile(octokit, payload, baseBranch, file.filename), 480 | getGitFile(octokit, payload, currentBranch, file.filename), 481 | ]); 482 | 483 | if (oldContents.content != null) { 484 | file.old_contents = String.raw`${oldContents.content}`; 485 | } else { 486 | file.old_contents = null; 487 | } 488 | 489 | if (currentContents.content != null) { 490 | file.current_contents = String.raw`${currentContents.content}`; 491 | } else { 492 | file.current_contents = null; 493 | } 494 | }; 495 | 496 | const reviewChangesRetry = async (files: PRFile[], builders: Builders[]) => { 497 | for (const { convoBuilder, responseBuilder } of builders) { 498 | try { 499 | console.log(`Trying with convoBuilder: ${convoBuilder.name}.`); 500 | return await reviewChanges(files, convoBuilder, responseBuilder); 501 | } catch (error) { 502 | console.log( 503 | `Error with convoBuilder: ${convoBuilder.name}, trying next one. Error: ${error}` 504 | ); 505 | } 506 | } 507 | throw new Error("All convoBuilders failed."); 508 | }; 509 | 510 | export const processPullRequest = async ( 511 | octokit: Octokit, 512 | payload: WebhookEventMap["pull_request"], 513 | files: PRFile[], 514 | includeSuggestions = false 515 | ) => { 516 | console.dir({ files }, { depth: null }); 517 | const filteredFiles = files.filter((file) => filterFile(file)); 518 | console.dir({ filteredFiles }, { depth: null }); 519 | if (filteredFiles.length == 0) { 520 | console.log("Nothing to comment on, all files were filtered out. The PR Agent does not support the following file types: pdf, png, jpg, jpeg, gif, mp4, mp3, md, json, env, toml, svg, package-lock.json, yarn.lock, .gitignore, package.json, tsconfig.json, poetry.lock, readme.md"); 521 | return { 522 | review: null, 523 | suggestions: [], 524 | }; 525 | } 526 | await Promise.all( 527 | filteredFiles.map((file) => { 528 | return preprocessFile(octokit, payload, file); 529 | }) 530 | ); 531 | const owner = payload.repository.owner.login; 532 | const repoName = payload.repository.name; 533 | const curriedXMLResponseBuilder = curriedXmlResponseBuilder(owner, repoName); 534 | if (includeSuggestions) { 535 | const reviewComments = await reviewChangesRetry(filteredFiles, [ 536 | { 537 | convoBuilder: getXMLReviewPrompt, 538 | responseBuilder: curriedXMLResponseBuilder, 539 | }, 540 | { 541 | convoBuilder: getReviewPrompt, 542 | responseBuilder: basicResponseBuilder, 543 | }, 544 | ]); 545 | let inlineComments: CodeSuggestion[] = []; 546 | if (reviewComments.structuredComments.length > 0) { 547 | console.log("STARTING INLINE COMMENT PROCESSING"); 548 | inlineComments = await Promise.all( 549 | reviewComments.structuredComments.map((suggestion) => { 550 | // find relevant file 551 | const file = files.find( 552 | (file) => file.filename === suggestion.filename 553 | ); 554 | if (file == null) { 555 | return null; 556 | } 557 | return generateInlineComments(suggestion, file); 558 | }) 559 | ); 560 | } 561 | const filteredInlineComments = inlineComments.filter( 562 | (comment) => comment !== null 563 | ); 564 | return { 565 | review: reviewComments, 566 | suggestions: filteredInlineComments, 567 | }; 568 | } else { 569 | const [review] = await Promise.all([ 570 | reviewChangesRetry(filteredFiles, [ 571 | { 572 | convoBuilder: getXMLReviewPrompt, 573 | responseBuilder: curriedXMLResponseBuilder, 574 | }, 575 | { 576 | convoBuilder: getReviewPrompt, 577 | responseBuilder: basicResponseBuilder, 578 | }, 579 | ]), 580 | ]); 581 | 582 | return { 583 | review, 584 | suggestions: [], 585 | }; 586 | } 587 | }; 588 | -------------------------------------------------------------------------------- /src/reviews.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BranchDetails, 3 | BuilderResponse, 4 | CodeSuggestion, 5 | Review, 6 | processGitFilepath, 7 | } from "./constants"; 8 | import { Octokit } from "@octokit/rest"; 9 | import { WebhookEventMap } from "@octokit/webhooks-definitions/schema"; 10 | 11 | const postGeneralReviewComment = async ( 12 | octokit: Octokit, 13 | payload: WebhookEventMap["pull_request"], 14 | review: string 15 | ) => { 16 | try { 17 | await octokit.request( 18 | "POST /repos/{owner}/{repo}/issues/{issue_number}/comments", 19 | { 20 | owner: payload.repository.owner.login, 21 | repo: payload.repository.name, 22 | issue_number: payload.pull_request.number, 23 | body: review, 24 | headers: { 25 | "x-github-api-version": "2022-11-28", 26 | }, 27 | } 28 | ); 29 | } catch (exc) { 30 | console.log(exc); 31 | } 32 | }; 33 | 34 | const postInlineComment = async ( 35 | octokit: Octokit, 36 | payload: WebhookEventMap["pull_request"], 37 | suggestion: CodeSuggestion 38 | ) => { 39 | try { 40 | const line = suggestion.line_end; 41 | let startLine = null; 42 | if (suggestion.line_end != suggestion.line_start) { 43 | startLine = suggestion.line_start; 44 | } 45 | const suggestionBody = `${suggestion.comment}\n\`\`\`suggestion\n${suggestion.correction}`; 46 | 47 | await octokit.request( 48 | "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments", 49 | { 50 | owner: payload.repository.owner.login, 51 | repo: payload.repository.name, 52 | pull_number: payload.pull_request.number, 53 | body: suggestionBody, 54 | commit_id: payload.pull_request.head.sha, 55 | path: suggestion.file, 56 | line: line, 57 | ...(startLine ? { start_line: startLine } : {}), 58 | // position: suggestion.line_start, 59 | // subject_type: "line", 60 | start_side: "RIGHT", 61 | side: "RIGHT", 62 | headers: { 63 | "X-GitHub-Api-Version": "2022-11-28", 64 | }, 65 | } 66 | ); 67 | } catch (exc) { 68 | console.log(exc); 69 | } 70 | }; 71 | 72 | export const applyReview = async ({ 73 | octokit, 74 | payload, 75 | review, 76 | }: { 77 | octokit: Octokit; 78 | payload: WebhookEventMap["pull_request"]; 79 | review: Review; 80 | }) => { 81 | let commentPromise = null; 82 | const comment = review.review?.comment; 83 | if (comment != null) { 84 | commentPromise = postGeneralReviewComment(octokit, payload, comment); 85 | } 86 | const suggestionPromises = review.suggestions.map((suggestion) => 87 | postInlineComment(octokit, payload, suggestion) 88 | ); 89 | await Promise.all([ 90 | ...(commentPromise ? [commentPromise] : []), 91 | ...suggestionPromises, 92 | ]); 93 | }; 94 | 95 | const addLineNumbers = (contents: string) => { 96 | const rawContents = String.raw`${contents}`; 97 | const prepended = rawContents 98 | .split("\n") 99 | .map((line, idx) => `${idx + 1}: ${line}`) 100 | .join("\n"); 101 | return prepended; 102 | }; 103 | 104 | export const getGitFile = async ( 105 | octokit: Octokit, 106 | payload: WebhookEventMap["issues"] | WebhookEventMap["pull_request"], 107 | branch: BranchDetails, 108 | filepath: string 109 | ) => { 110 | try { 111 | const response = await octokit.request( 112 | "GET /repos/{owner}/{repo}/contents/{path}", 113 | { 114 | owner: payload.repository.owner.login, 115 | repo: payload.repository.name, 116 | path: filepath, 117 | ref: branch.name, // specify the branch name here 118 | headers: { 119 | "X-GitHub-Api-Version": "2022-11-28", 120 | }, 121 | } 122 | ); 123 | //@ts-ignore 124 | const decodedContent = Buffer.from( 125 | response.data.content, 126 | "base64" 127 | ).toString("utf8"); 128 | //@ts-ignore 129 | return { content: decodedContent, sha: response.data.sha }; 130 | } catch (exc) { 131 | if (exc.status === 404) { 132 | return { content: null, sha: null }; 133 | } 134 | console.log(exc); 135 | throw exc; 136 | } 137 | }; 138 | 139 | export const getFileContents = async ( 140 | octokit: Octokit, 141 | payload: WebhookEventMap["issues"], 142 | branch: BranchDetails, 143 | filepath: string 144 | ) => { 145 | const gitFile = await getGitFile( 146 | octokit, 147 | payload, 148 | branch, 149 | processGitFilepath(filepath) 150 | ); 151 | const fileWithLines = `# ${filepath}\n${addLineNumbers(gitFile.content)}`; 152 | return { result: fileWithLines, functionString: `Opening file: ${filepath}` }; 153 | }; 154 | 155 | export const commentIssue = async ( 156 | octokit: Octokit, 157 | payload: WebhookEventMap["issues"], 158 | comment: string 159 | ) => { 160 | await octokit.rest.issues.createComment({ 161 | owner: payload.repository.owner.login, 162 | repo: payload.repository.name, 163 | issue_number: payload.issue.number, 164 | body: comment, 165 | }); 166 | }; 167 | 168 | export const createBranch = async ( 169 | octokit: Octokit, 170 | payload: WebhookEventMap["issues"] 171 | ) => { 172 | let branchDetails = null; 173 | try { 174 | const title = payload.issue.title.replace(/\s/g, "-").substring(0, 15); 175 | 176 | const hash = Math.random().toString(36).substring(2, 7); 177 | const subName = `${title}-${hash}`.substring(0, 20); 178 | const branchName = `Code-Bot/${subName}`; 179 | // Get the default branch for the repository 180 | const { data: repo } = await octokit.rest.repos.get({ 181 | owner: payload.repository.owner.login, 182 | repo: payload.repository.name, 183 | }); 184 | 185 | // Get the commit SHA of the default branch 186 | const { data: ref } = await octokit.rest.git.getRef({ 187 | owner: payload.repository.owner.login, 188 | repo: payload.repository.name, 189 | ref: `heads/${repo.default_branch}`, 190 | }); 191 | 192 | // Create a new branch from the commit SHA 193 | const { data: newBranch } = await octokit.rest.git.createRef({ 194 | owner: payload.repository.owner.login, 195 | repo: payload.repository.name, 196 | ref: `refs/heads/${branchName}`, 197 | sha: ref.object.sha, 198 | }); 199 | 200 | console.log(newBranch); 201 | 202 | branchDetails = { 203 | name: branchName, 204 | sha: newBranch.object.sha, 205 | url: newBranch.url, 206 | }; 207 | let branchUrl = `https://github.com/${payload.repository.owner.login}/${payload.repository.name}/tree/${branchName}`; 208 | const branchComment = `Branch created: [${branchName}](${branchUrl})`; 209 | await commentIssue(octokit, payload, branchComment); 210 | 211 | console.log(`Branch ${branchName} created`); 212 | } catch (exc) { 213 | console.log(exc); 214 | } 215 | return branchDetails; 216 | }; 217 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "commonjs", 7 | "target": "es6" 8 | }, 9 | "include": [ 10 | "./src/**/*" 11 | ] 12 | } --------------------------------------------------------------------------------