diff --git a/.github/workflows/jsdoc-automation.yml b/.github/workflows/jsdoc-automation.yml index d487b08fe4..332f31a7d7 100644 --- a/.github/workflows/jsdoc-automation.yml +++ b/.github/workflows/jsdoc-automation.yml @@ -3,6 +3,16 @@ name: JSDoc Automation on: workflow_dispatch: inputs: + jsdoc: + description: 'Generate JSDoc comments (T/F)' + required: true + default: 'T' + type: string + readme: + description: 'Generate README documentation (T/F)' + required: true + default: 'T' + type: string pull_number: description: 'Pull Request Number (if not provided, scans root_directory) - PR must be merged to develop branch' required: false @@ -10,7 +20,7 @@ on: root_directory: description: 'Only scans files in this directory (relative to repository root, e.g., packages/core/src)' required: true - default: 'packages/core/src/test_resources' + default: 'packages/plugin-near/' type: string excluded_directories: description: 'Directories to exclude from scanning (comma-separated, relative to root_directory)' @@ -18,7 +28,7 @@ on: default: 'node_modules,dist,test' type: string reviewers: - description: 'Pull Request Reviewers (comma-separated GitHub usernames)' + description: 'Pull Request Reviewers (Must be collaborator on the repository) comma-separated GitHub usernames' required: true default: '' type: string @@ -27,6 +37,11 @@ on: required: false default: 'develop' type: string + language: + description: 'Documentation language (e.g., English, Spanish, French)' + required: true + default: 'English' + type: string jobs: generate-docs: diff --git a/packages/plugin-near/src/actions/swap.ts b/packages/plugin-near/src/actions/swap.ts index f11f6b134f..289d9478af 100644 --- a/packages/plugin-near/src/actions/swap.ts +++ b/packages/plugin-near/src/actions/swap.ts @@ -39,6 +39,7 @@ async function checkStorageBalance( } } +// TODO: add functionality to support multiple networks async function swapToken( runtime: IAgentRuntime, inputTokenId: string, diff --git a/scripts/jsdoc-automation/package.json b/scripts/jsdoc-automation/package.json index 60902a2a41..2ce4c05bfe 100644 --- a/scripts/jsdoc-automation/package.json +++ b/scripts/jsdoc-automation/package.json @@ -3,10 +3,13 @@ "name": "plugin-audix", "version": "1.0.0", "description": "", - "main": "index.ts", + "main": "dist/index.js", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", "scripts": { - "start": "NODE_OPTIONS='--loader ts-node/esm' node src/index.ts", - "test": "echo \"Error: no test specified\" && exit 1", + "build": "tsup", + "dev": "tsup --watch", + "start": "node dist/index.js", "clean": "rm -rf node_modules dist" }, "keywords": [], @@ -16,15 +19,16 @@ "@langchain/openai": "^0.3.16", "@octokit/rest": "^21.0.2", "@types/node": "^20.11.0", - "dotenv": "^16.4.7", - "langchain": "^0.3.7", "@typescript-eslint/parser": "6.18.1", "@typescript-eslint/types": "6.18.1", "@typescript-eslint/typescript-estree": "6.18.1", + "dotenv": "^16.4.7", + "langchain": "^0.3.7", "yaml": "^2.3.4" }, "devDependencies": { "ts-node": "^10.9.2", + "tsup": "^8.3.5", "typescript": "5.3.3" } } \ No newline at end of file diff --git a/scripts/jsdoc-automation/pnpm-lock.yaml b/scripts/jsdoc-automation/pnpm-lock.yaml index 4bf18e4f59..8a536082b5 100644 --- a/scripts/jsdoc-automation/pnpm-lock.yaml +++ b/scripts/jsdoc-automation/pnpm-lock.yaml @@ -18,11 +18,14 @@ importers: specifier: ^20.11.0 version: 20.17.10 '@typescript-eslint/parser': - specifier: ^6.18.1 - version: 6.21.0(eslint@9.17.0)(typescript@5.3.3) + specifier: 6.18.1 + version: 6.18.1(eslint@9.17.0)(typescript@5.3.3) '@typescript-eslint/types': - specifier: ^6.18.1 - version: 6.21.0 + specifier: 6.18.1 + version: 6.18.1 + '@typescript-eslint/typescript-estree': + specifier: 6.18.1 + version: 6.18.1(typescript@5.3.3) dotenv: specifier: ^16.4.7 version: 16.4.7 @@ -36,6 +39,9 @@ importers: ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@20.17.10)(typescript@5.3.3) + tsup: + specifier: ^8.3.5 + version: 8.3.5(typescript@5.3.3)(yaml@2.6.1) typescript: specifier: 5.3.3 version: 5.3.3 @@ -49,6 +55,156 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@esbuild/aix-ppc64@0.24.2': + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.24.2': + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.24.2': + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.24.2': + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.24.2': + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.24.2': + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.24.2': + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.24.2': + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.24.2': + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.24.2': + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.24.2': + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.24.2': + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.24.2': + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.24.2': + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.24.2': + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.24.2': + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.24.2': + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.24.2': + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.24.2': + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.24.2': + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.24.2': + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.24.2': + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.24.2': + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.24.2': + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.24.2': + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.1': resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -103,13 +259,28 @@ packages: resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} engines: {node: '>=18.18'} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -193,6 +364,105 @@ packages: '@octokit/types@13.6.2': resolution: {integrity: sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@rollup/rollup-android-arm-eabi@4.29.1': + resolution: {integrity: sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.29.1': + resolution: {integrity: sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.29.1': + resolution: {integrity: sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.29.1': + resolution: {integrity: sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.29.1': + resolution: {integrity: sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.29.1': + resolution: {integrity: sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.29.1': + resolution: {integrity: sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.29.1': + resolution: {integrity: sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.29.1': + resolution: {integrity: sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.29.1': + resolution: {integrity: sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.29.1': + resolution: {integrity: sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.29.1': + resolution: {integrity: sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.29.1': + resolution: {integrity: sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.29.1': + resolution: {integrity: sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.29.1': + resolution: {integrity: sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.29.1': + resolution: {integrity: sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.29.1': + resolution: {integrity: sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.29.1': + resolution: {integrity: sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.29.1': + resolution: {integrity: sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==} + cpu: [x64] + os: [win32] + '@tsconfig/node10@1.0.11': resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} @@ -226,8 +496,8 @@ packages: '@types/uuid@10.0.0': resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} - '@typescript-eslint/parser@6.21.0': - resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} + '@typescript-eslint/parser@6.18.1': + resolution: {integrity: sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -236,16 +506,16 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@6.21.0': - resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} + '@typescript-eslint/scope-manager@6.18.1': + resolution: {integrity: sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/types@6.21.0': - resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} + '@typescript-eslint/types@6.18.1': + resolution: {integrity: sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/typescript-estree@6.21.0': - resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} + '@typescript-eslint/typescript-estree@6.18.1': + resolution: {integrity: sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -253,8 +523,8 @@ packages: typescript: optional: true - '@typescript-eslint/visitor-keys@6.21.0': - resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} + '@typescript-eslint/visitor-keys@6.18.1': + resolution: {integrity: sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==} engines: {node: ^16.0.0 || >=18.0.0} abort-controller@3.0.0: @@ -282,6 +552,14 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -290,6 +568,13 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} @@ -322,6 +607,16 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -334,6 +629,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -349,9 +648,17 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + consola@3.3.3: + resolution: {integrity: sha512-Qil5KwghMzlqd51UXM0b6fyaGHtOC22scxrwrz4A2882LyUMwQjnvaedN1HAeXzphspQ6CpHkzMAWxBTUruDLg==} + engines: {node: ^14.18.0 || >=16.10.0} + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -391,6 +698,20 @@ packages: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + esbuild@0.24.2: + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + engines: {node: '>=18'} + hasBin: true + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -460,6 +781,14 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fdir@6.4.2: + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -479,6 +808,10 @@ packages: flatted@3.3.2: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + form-data-encoder@1.7.2: resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} @@ -490,6 +823,11 @@ packages: resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} engines: {node: '>= 12.20'} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -498,6 +836,10 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -529,6 +871,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -540,6 +886,13 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + js-tiktoken@1.0.16: resolution: {integrity: sha512-nUVdO5k/M9llWpiaZlBBDdtmr6qWXwSD6fgaDu2zM8UP+OXxx9V37lFkI6w0/1IuaDx7WffZ37oYd9KvcWKElg==} @@ -621,6 +974,17 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -628,6 +992,12 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} @@ -654,6 +1024,14 @@ packages: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -661,6 +1039,9 @@ packages: resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -677,6 +1058,10 @@ packages: encoding: optional: true + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + openai@4.77.0: resolution: {integrity: sha512-WWacavtns/7pCUkOWvQIjyOfcdr9X+9n9Vvb0zFeKVDAqwCMDHB+iSr24SVaBAhplvSG6JrRXFpcNM9gWhOGIw==} hasBin: true @@ -717,6 +1102,9 @@ packages: resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} engines: {node: '>=8'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -729,14 +1117,47 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -748,10 +1169,18 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + retry@0.13.1: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} @@ -760,6 +1189,11 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rollup@4.29.1: + resolution: {integrity: sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -776,18 +1210,61 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.10: + resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} + engines: {node: '>=12.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -795,12 +1272,22 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + ts-api-utils@1.4.3: resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-node@10.9.2: resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true @@ -815,6 +1302,25 @@ packages: '@swc/wasm': optional: true + tsup@8.3.5: + resolution: {integrity: sha512-Tunf6r6m6tnZsG9GYWndg0z8dEV7fD733VBFzFJ5Vcm1FtlXB8xBD/rtrBi2a3YKEV7hHtxiZtW5EAVADoe1pA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -850,9 +1356,15 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -862,6 +1374,14 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + yaml@2.6.1: resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} engines: {node: '>= 14'} @@ -891,6 +1411,81 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@esbuild/aix-ppc64@0.24.2': + optional: true + + '@esbuild/android-arm64@0.24.2': + optional: true + + '@esbuild/android-arm@0.24.2': + optional: true + + '@esbuild/android-x64@0.24.2': + optional: true + + '@esbuild/darwin-arm64@0.24.2': + optional: true + + '@esbuild/darwin-x64@0.24.2': + optional: true + + '@esbuild/freebsd-arm64@0.24.2': + optional: true + + '@esbuild/freebsd-x64@0.24.2': + optional: true + + '@esbuild/linux-arm64@0.24.2': + optional: true + + '@esbuild/linux-arm@0.24.2': + optional: true + + '@esbuild/linux-ia32@0.24.2': + optional: true + + '@esbuild/linux-loong64@0.24.2': + optional: true + + '@esbuild/linux-mips64el@0.24.2': + optional: true + + '@esbuild/linux-ppc64@0.24.2': + optional: true + + '@esbuild/linux-riscv64@0.24.2': + optional: true + + '@esbuild/linux-s390x@0.24.2': + optional: true + + '@esbuild/linux-x64@0.24.2': + optional: true + + '@esbuild/netbsd-arm64@0.24.2': + optional: true + + '@esbuild/netbsd-x64@0.24.2': + optional: true + + '@esbuild/openbsd-arm64@0.24.2': + optional: true + + '@esbuild/openbsd-x64@0.24.2': + optional: true + + '@esbuild/sunos-x64@0.24.2': + optional: true + + '@esbuild/win32-arm64@0.24.2': + optional: true + + '@esbuild/win32-ia32@0.24.2': + optional: true + + '@esbuild/win32-x64@0.24.2': + optional: true + '@eslint-community/eslint-utils@4.4.1(eslint@9.17.0)': dependencies: eslint: 9.17.0 @@ -945,10 +1540,32 @@ snapshots: '@humanwhocodes/retry@0.4.1': {} + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/set-array@1.2.1': {} + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -1059,6 +1676,66 @@ snapshots: dependencies: '@octokit/openapi-types': 22.2.0 + '@pkgjs/parseargs@0.11.0': + optional: true + + '@rollup/rollup-android-arm-eabi@4.29.1': + optional: true + + '@rollup/rollup-android-arm64@4.29.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.29.1': + optional: true + + '@rollup/rollup-darwin-x64@4.29.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.29.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.29.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.29.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.29.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.29.1': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.29.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.29.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.29.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.29.1': + optional: true + '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -1088,12 +1765,12 @@ snapshots: '@types/uuid@10.0.0': {} - '@typescript-eslint/parser@6.21.0(eslint@9.17.0)(typescript@5.3.3)': + '@typescript-eslint/parser@6.18.1(eslint@9.17.0)(typescript@5.3.3)': dependencies: - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.21.0 + '@typescript-eslint/scope-manager': 6.18.1 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.18.1 debug: 4.4.0 eslint: 9.17.0 optionalDependencies: @@ -1101,17 +1778,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@6.21.0': + '@typescript-eslint/scope-manager@6.18.1': dependencies: - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/visitor-keys': 6.21.0 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/visitor-keys': 6.18.1 - '@typescript-eslint/types@6.21.0': {} + '@typescript-eslint/types@6.18.1': {} - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.3.3)': + '@typescript-eslint/typescript-estree@6.18.1(typescript@5.3.3)': dependencies: - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/visitor-keys': 6.21.0 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/visitor-keys': 6.18.1 debug: 4.4.0 globby: 11.1.0 is-glob: 4.0.3 @@ -1123,9 +1800,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@6.21.0': + '@typescript-eslint/visitor-keys@6.18.1': dependencies: - '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/types': 6.18.1 eslint-visitor-keys: 3.4.3 abort-controller@3.0.0: @@ -1153,12 +1830,20 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 ansi-styles@5.2.0: {} + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + arg@4.1.3: {} argparse@2.0.1: {} @@ -1186,6 +1871,13 @@ snapshots: dependencies: fill-range: 7.1.1 + bundle-require@5.1.0(esbuild@0.24.2): + dependencies: + esbuild: 0.24.2 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + callsites@3.1.0: {} camelcase@6.3.0: {} @@ -1195,6 +1887,10 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chokidar@4.0.3: + dependencies: + readdirp: 4.0.2 + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -1207,8 +1903,12 @@ snapshots: commander@10.0.1: {} + commander@4.1.1: {} + concat-map@0.0.1: {} + consola@3.3.3: {} + create-require@1.1.1: {} cross-spawn@7.0.6: @@ -1235,6 +1935,40 @@ snapshots: dotenv@16.4.7: {} + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + esbuild@0.24.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.2 + '@esbuild/android-arm': 0.24.2 + '@esbuild/android-arm64': 0.24.2 + '@esbuild/android-x64': 0.24.2 + '@esbuild/darwin-arm64': 0.24.2 + '@esbuild/darwin-x64': 0.24.2 + '@esbuild/freebsd-arm64': 0.24.2 + '@esbuild/freebsd-x64': 0.24.2 + '@esbuild/linux-arm': 0.24.2 + '@esbuild/linux-arm64': 0.24.2 + '@esbuild/linux-ia32': 0.24.2 + '@esbuild/linux-loong64': 0.24.2 + '@esbuild/linux-mips64el': 0.24.2 + '@esbuild/linux-ppc64': 0.24.2 + '@esbuild/linux-riscv64': 0.24.2 + '@esbuild/linux-s390x': 0.24.2 + '@esbuild/linux-x64': 0.24.2 + '@esbuild/netbsd-arm64': 0.24.2 + '@esbuild/netbsd-x64': 0.24.2 + '@esbuild/openbsd-arm64': 0.24.2 + '@esbuild/openbsd-x64': 0.24.2 + '@esbuild/sunos-x64': 0.24.2 + '@esbuild/win32-arm64': 0.24.2 + '@esbuild/win32-ia32': 0.24.2 + '@esbuild/win32-x64': 0.24.2 + escape-string-regexp@4.0.0: {} eslint-scope@8.2.0: @@ -1325,6 +2059,10 @@ snapshots: dependencies: reusify: 1.0.4 + fdir@6.4.2(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -1345,6 +2083,11 @@ snapshots: flatted@3.3.2: {} + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + form-data-encoder@1.7.2: {} form-data@4.0.1: @@ -1358,6 +2101,9 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 4.0.0-beta.3 + fsevents@2.3.3: + optional: true + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -1366,6 +2112,15 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + globals@14.0.0: {} globby@11.1.0: @@ -1394,6 +2149,8 @@ snapshots: is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -1402,6 +2159,14 @@ snapshots: isexe@2.0.0: {} + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + joycon@3.1.1: {} + js-tiktoken@1.0.16: dependencies: base64-js: 1.5.1 @@ -1457,12 +2222,22 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 lodash.merge@4.6.2: {} + lodash.sortby@4.7.0: {} + + lru-cache@10.4.3: {} + make-error@1.3.6: {} merge2@1.4.1: {} @@ -1486,10 +2261,22 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + ms@2.1.3: {} mustache@4.2.0: {} + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + natural-compare@1.4.0: {} node-domexception@1.0.0: {} @@ -1498,6 +2285,8 @@ snapshots: dependencies: whatwg-url: 5.0.0 + object-assign@4.1.1: {} + openai@4.77.0(zod@3.24.1): dependencies: '@types/node': 18.19.68 @@ -1547,6 +2336,8 @@ snapshots: dependencies: p-finally: 1.0.0 + package-json-from-dist@1.0.1: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -1555,22 +2346,68 @@ snapshots: path-key@3.1.1: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + path-type@4.0.0: {} + picocolors@1.1.1: {} + picomatch@2.3.1: {} + picomatch@4.0.2: {} + + pirates@4.0.6: {} + + postcss-load-config@6.0.1(yaml@2.6.1): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + yaml: 2.6.1 + prelude-ls@1.2.1: {} punycode@2.3.1: {} queue-microtask@1.2.3: {} + readdirp@4.0.2: {} + resolve-from@4.0.0: {} + resolve-from@5.0.0: {} + retry@0.13.1: {} reusify@1.0.4: {} + rollup@4.29.1: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.29.1 + '@rollup/rollup-android-arm64': 4.29.1 + '@rollup/rollup-darwin-arm64': 4.29.1 + '@rollup/rollup-darwin-x64': 4.29.1 + '@rollup/rollup-freebsd-arm64': 4.29.1 + '@rollup/rollup-freebsd-x64': 4.29.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.29.1 + '@rollup/rollup-linux-arm-musleabihf': 4.29.1 + '@rollup/rollup-linux-arm64-gnu': 4.29.1 + '@rollup/rollup-linux-arm64-musl': 4.29.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.29.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.29.1 + '@rollup/rollup-linux-riscv64-gnu': 4.29.1 + '@rollup/rollup-linux-s390x-gnu': 4.29.1 + '@rollup/rollup-linux-x64-gnu': 4.29.1 + '@rollup/rollup-linux-x64-musl': 4.29.1 + '@rollup/rollup-win32-arm64-msvc': 4.29.1 + '@rollup/rollup-win32-ia32-msvc': 4.29.1 + '@rollup/rollup-win32-x64-msvc': 4.29.1 + fsevents: 2.3.3 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -1583,24 +2420,83 @@ snapshots: shebang-regex@3.0.0: {} + signal-exit@4.1.0: {} + slash@3.0.0: {} + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + strip-json-comments@3.1.1: {} + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinyexec@0.3.2: {} + + tinyglobby@0.2.10: + dependencies: + fdir: 6.4.2(picomatch@4.0.2) + picomatch: 4.0.2 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 tr46@0.0.3: {} + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + ts-api-utils@1.4.3(typescript@5.3.3): dependencies: typescript: 5.3.3 + ts-interface-checker@0.1.13: {} + ts-node@10.9.2(@types/node@20.17.10)(typescript@5.3.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -1619,6 +2515,32 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + tsup@8.3.5(typescript@5.3.3)(yaml@2.6.1): + dependencies: + bundle-require: 5.1.0(esbuild@0.24.2) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.3.3 + debug: 4.4.0 + esbuild: 0.24.2 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(yaml@2.6.1) + resolve-from: 5.0.0 + rollup: 4.29.1 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.10 + tree-kill: 1.2.2 + optionalDependencies: + typescript: 5.3.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -1643,17 +2565,37 @@ snapshots: webidl-conversions@3.0.1: {} + webidl-conversions@4.0.2: {} + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + which@2.0.2: dependencies: isexe: 2.0.0 word-wrap@1.2.5: {} + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + yaml@2.6.1: {} yn@3.1.1: {} diff --git a/scripts/jsdoc-automation/src/AIService.ts b/scripts/jsdoc-automation/src/AIService.ts index 2f7d7b8225..60a3738f0a 100644 --- a/scripts/jsdoc-automation/src/AIService.ts +++ b/scripts/jsdoc-automation/src/AIService.ts @@ -1,24 +1,42 @@ import { ChatOpenAI } from "@langchain/openai"; import dotenv from 'dotenv'; +import { ActionMetadata, ASTQueueItem, EnvUsage, OrganizedDocs, PluginDocumentation, TodoItem, TodoSection } from "./types/index.js"; +import path from "path"; +import { promises as fs } from 'fs'; +import { Configuration } from "./Configuration.js"; +import { TypeScriptParser } from './TypeScriptParser.js'; +import { PROMPT_TEMPLATES } from "./utils/prompts.js"; dotenv.config(); +interface FileDocsGroup { + filePath: string; + classes: ASTQueueItem[]; + methods: ASTQueueItem[]; + interfaces: ASTQueueItem[]; + types: ASTQueueItem[]; + functions: ASTQueueItem[]; + } + /** * Service for interacting with OpenAI chat API. */ export class AIService { private chatModel: ChatOpenAI; + private typeScriptParser: TypeScriptParser; /** * Constructor for initializing the ChatOpenAI instance. - * - * @throws {Error} If OPENAI_API_KEY environment variable is not set. + * + * @param {Configuration} configuration - The configuration instance to be used + * @throws {Error} If OPENAI_API_KEY environment variable is not set */ - constructor() { + constructor(private configuration: Configuration) { if (!process.env.OPENAI_API_KEY) { throw new Error('OPENAI_API_KEY is not set'); } this.chatModel = new ChatOpenAI({ apiKey: process.env.OPENAI_API_KEY }); + this.typeScriptParser = new TypeScriptParser(); } /** @@ -28,7 +46,14 @@ export class AIService { */ public async generateComment(prompt: string): Promise { try { - const response = await this.chatModel.invoke(prompt); + let finalPrompt = prompt; + + // Only append language instruction if not English + if (this.configuration.language.toLowerCase() !== 'english') { + finalPrompt += `\n\nEverything except the JSDoc conventions and code should be in ${this.configuration.language}`; + } + + const response = await this.chatModel.invoke(finalPrompt); return response.content as string; } catch (error) { this.handleAPIError(error as Error); @@ -36,9 +61,503 @@ export class AIService { } } + public async generatePluginDocumentation({ + existingDocs, + packageJson, + readmeContent, + todoItems, + envUsages + }: { + existingDocs: ASTQueueItem[]; + packageJson: any; + readmeContent?: string; + todoItems: TodoItem[]; + envUsages: EnvUsage[]; + }): Promise { + const organizedDocs = this.organizeDocumentation(existingDocs); + + // Read the index.ts file + // Read the index.ts file + const indexPath = path.join(this.configuration.absolutePath, 'src', 'index.ts'); + const exports = this.typeScriptParser.extractExports(indexPath); + + // Extract actions, providers, and evaluators from the index.ts content + // Generate documentation for actions + const actionsDocumentation = await this.generateActionsDocumentation(exports.actions); + + // Generate documentation for providers + const providersDocumentation = await this.generateProvidersDocumentation(exports.providers); + + // Generate documentation for evaluators + const evaluatorsDocumentation = await this.generateEvaluatorsDocumentation(exports.evaluators); + + + // write organizedDocs into a json in /here directory + const jsonPath = path.join(this.configuration.absolutePath, 'here', 'organizedDocs.json'); + fs.writeFile(jsonPath, JSON.stringify(organizedDocs, null, 2)); + + const [overview, installation, configuration, usage, apiRef, troubleshooting, todoSection] = await Promise.all([ + this.generateOverview(organizedDocs, packageJson), + this.generateInstallation(packageJson), + this.generateConfiguration(envUsages), + this.generateUsage(organizedDocs, packageJson), + this.generateApiReference(organizedDocs), + this.generateTroubleshooting(organizedDocs, packageJson), + this.generateTodoSection(todoItems) + ]); + + return { + overview, + installation, + configuration, + usage, + apiReference: apiRef, + troubleshooting, + todos: todoSection.todos, + actionsDocumentation, // Added actions documentation + providersDocumentation, // Added providers documentation + evaluatorsDocumentation // Added evaluators documentation + }; + } + + private async generateOverview(docs: OrganizedDocs, packageJson: any): Promise { + const prompt = PROMPT_TEMPLATES.overview(packageJson, docs); + try { + const overview = await this.generateComment(prompt); + return overview; + } catch (error) { + console.error('Error generating overview:', error); + return `# ${packageJson.name}\n\nNo overview available. Please check package documentation.`; + } + } + + private async generateInstallation(packageJson: any): Promise { + const indexPath = path.join(this.configuration.absolutePath, 'src/index.ts'); + let mainExport = 'plugin'; + let exportName = packageJson.name.split('/').pop() + 'Plugin'; + + try { + const indexContent = await fs.readFile(indexPath, { encoding: 'utf8' }); + const exportMatch = indexContent.match(/export const (\w+):/); + if (exportMatch) { + exportName = exportMatch[1]; + } + + const prompt = `Generate installation and integration instructions for this ElizaOS plugin: + + Plugin name: ${packageJson.name} + Main export: ${exportName} + Index file exports: + ${indexContent} + Dependencies: ${JSON.stringify(packageJson.dependencies || {}, null, 2)} + Peer dependencies: ${JSON.stringify(packageJson.peerDependencies || {}, null, 2)} + + This is a plugin for the ElizaOS agent system. Generate comprehensive installation instructions that include: + + 1. How to add the plugin to your ElizaOS project: + - First, explain that users need to add the following to their agent/package.json dependencies: + \`\`\`json + { + "dependencies": { + "${packageJson.name}": "workspace:*" + } + } + \`\`\` + - Then, explain they need to: + 1. cd into the agent/ directory + 2. Run pnpm install to install the new dependency + 3. Run pnpm build to build the project with the new plugin + + 2. After installation, show how to import and use the plugin: + - Import syntax using: import { ${exportName} } from "${packageJson.name}"; + - How to add it to the AgentRuntime plugins array + + 3. Integration example showing the complete setup: + \`\`\`typescript + import { ${exportName} } from "${packageJson.name}"; + + return new AgentRuntime({ + // other configuration... + plugins: [ + ${exportName}, + // other plugins... + ], + }); + \`\`\` + + 4. Verification steps to ensure successful integration + - for this step just tell the user to ensure they see ["✓ Registering action: "] in the console + + Format the response in markdown, with clear section headers and step-by-step instructions. Emphasize that this is a workspace package that needs to be added to agent/package.json and then built.`; + + return await this.generateComment(prompt); + } catch (error) { + console.error('Error reading index.ts:', error); + return this.generateBasicInstallPrompt(packageJson); + } + } + + private async generateBasicInstallPrompt(packageJson: any): Promise { + console.log('AIService::generateInstallation threw an error, generating basic install prompt'); + const prompt = `Generate basic installation instructions for this ElizaOS plugin: + + Plugin name: ${packageJson.name} + Dependencies: ${JSON.stringify(packageJson.dependencies || {}, null, 2)} + Peer dependencies: ${JSON.stringify(packageJson.peerDependencies || {}, null, 2)} + + This is a plugin for the ElizaOS agent system. Include basic setup instructions.`; + + return await this.generateComment(prompt); + } + + private async generateConfiguration(envUsages: EnvUsage[]): Promise { + const prompt = `Generate configuration documentation based on these environment variable usages: + ${envUsages.map(item => ` + Environment Variable: ${item.code} + Full Context: ${item.fullContext} + `).join('\n')} + Create comprehensive configuration documentation that: + 1. Lists all required environment variables and their purpose + 2. Return a full .env example file + + Inform the user that the configuration is done in the .env file. + And to ensure the .env is set in the .gitignore file so it is not committed to the repository. + + Format the response in markdown with proper headings and code blocks.`; + + return await this.generateComment(prompt); + } + + private async generateUsage(docs: OrganizedDocs, packageJson: any): Promise { + const fileGroups = this.groupDocsByFile(docs); + const sections: string[] = []; + + // Generate documentation for each file without individual intros + for (const fileGroup of fileGroups) { + const fileDoc = await this.generateFileUsageDoc(fileGroup); + if (fileDoc.trim()) { + sections.push(fileDoc); + } + } + + return sections.join('\n\n'); + } + + private async generateApiReference(docs: OrganizedDocs): Promise { + const fileGroups = this.groupDocsByFile(docs); + const sections: string[] = []; + + // Generate documentation for each file without individual intros + for (const fileGroup of fileGroups) { + const fileDoc = await this.generateFileApiDoc(fileGroup); + if (fileDoc.trim()) { + sections.push(fileDoc); + } + } + + return sections.join('\n\n'); + } + +/** + * Generates troubleshooting guide based on documentation and common patterns + */ + // toDo - integrate w/ @Jin's discord scraper to pull solutions for known issues + private async generateTroubleshooting(docs: OrganizedDocs, packageJson: any): Promise { + const prompt = `${PROMPT_TEMPLATES.troubleshooting}\n\nFor package: ${packageJson.name}\n\nWith content:\n${JSON.stringify(docs, null, 2)}`; + return await this.generateComment(prompt); + } + + /** + * Generates TODO section documentation from found TODO comments + */ + // toDo - integrate w/ @Jin's discord scraper to auto create GH issues/bounties + private async generateTodoSection(todoItems: TodoItem[]): Promise { + if (todoItems.length === 0) { + return { todos: "No TODO items found.", todoCount: 0 }; + } + + const prompt = `${PROMPT_TEMPLATES.todos}\n\nWith items:\n${todoItems.map(item => + `- Comment: ${item.comment}\n Context: ${item.fullContext}` + ).join('\n')}`; + + const todos = await this.generateComment(prompt); + return { todos, todoCount: todoItems.length }; + } + + // should be moved to utils + private organizeDocumentation(docs: ASTQueueItem[]): OrganizedDocs { + return docs.reduce((acc: OrganizedDocs, doc) => { + // Use nodeType to determine the category + switch (doc.nodeType) { + case 'ClassDeclaration': + acc.classes.push(doc); + break; + case 'MethodDefinition': + case 'TSMethodSignature': + acc.methods.push(doc); + break; + case 'TSInterfaceDeclaration': + acc.interfaces.push(doc); + break; + case 'TSTypeAliasDeclaration': + acc.types.push(doc); + break; + case 'FunctionDeclaration': + acc.functions.push(doc); + break; + } + return acc; + }, { classes: [], methods: [], interfaces: [], types: [], functions: [] }); + } + + private async generateActionsDocumentation(actionsFiles: string[]): Promise { + let documentation = ''; + + for (const file of actionsFiles) { + // Remove ./ prefix and ensure path includes src directory and .ts extension + const relativePath = file.replace(/^\.\//, ''); + const filePath = path.join(this.configuration.absolutePath, 'src', relativePath + '.ts'); + + try { + const ast = this.typeScriptParser.parse(filePath); + const bounds = this.typeScriptParser.findActionBounds(ast); + + if (!bounds) { + console.warn(`No action bounds found in ${filePath}`); + continue; + } + + const actionCode = this.typeScriptParser.extractActionCode(filePath, bounds); + + // Use PROMPT_TEMPLATES.actionDoc + const prompt = `${PROMPT_TEMPLATES.actionDoc}\n\nWith content:\n\`\`\`typescript\n${actionCode}\n\`\`\``; + + const actionDocumentation = await this.generateComment(prompt); + if (actionDocumentation.trim()) { + documentation += actionDocumentation + '\n\n'; + } + + } catch (error) { + console.warn(`Warning: Could not process action file ${filePath}:`, error); + continue; + } + } + + if (!documentation.trim()) { + return 'No actions documentation available.'; + } + + return documentation; + } + + private async generateProvidersDocumentation(providersFiles: string[]): Promise { + let documentation = ''; + + for (const file of providersFiles) { + // Remove ./ prefix and ensure path includes src directory and .ts extension + const relativePath = file.replace(/^\.\//, ''); + const filePath = path.join(this.configuration.absolutePath, 'src', relativePath + '.ts'); + + try { + const content = await fs.readFile(filePath, 'utf-8'); + // Create a provider object with relevant information + const provider = { + fileName: relativePath, + content: content, + // Extract provider properties + name: relativePath.split('/').pop()?.replace('.ts', ''), + }; + + const providerDocumentation = await this.generateProviderDoc(provider); + if (providerDocumentation.trim()) { + documentation += providerDocumentation + '\n\n'; + } + } catch (error) { + console.warn(`Warning: Could not read provider file ${filePath}:`, error); + continue; + } + } + + if (!documentation.trim()) { + return 'No providers documentation available.'; + } + + return documentation; + } + + private async generateEvaluatorsDocumentation(evaluatorsFiles: string[]): Promise { + let documentation = ''; + + for (const file of evaluatorsFiles) { + // Remove ./ prefix and ensure path includes src directory and .ts extension + const relativePath = file.replace(/^\.\//, ''); + const filePath = path.join(this.configuration.absolutePath, 'src', relativePath + '.ts'); + + try { + const content = await fs.readFile(filePath, 'utf-8'); + const prompt = `Generate documentation for the following Evaluator: + \`\`\`typescript + ${content} + \`\`\` + + Provide an overview of the evaluator's purpose and functionality. + Format in markdown without adding any additional headers.`; + + const evaluatorDocumentation = await this.generateComment(prompt); + if (evaluatorDocumentation.trim()) { + documentation += `### ${relativePath}\n\n${evaluatorDocumentation}\n\n`; + } + } catch (error) { + console.warn(`Warning: Could not read evaluator file ${filePath}:`, error); + continue; + } + } + + if (!documentation.trim()) { + return 'No evaluators documentation available.'; + } + + return documentation; + } + + + private groupDocsByFile(docs: OrganizedDocs): FileDocsGroup[] { + // Get unique file paths + const filePaths = new Set(); + [...docs.classes, ...docs.methods, ...docs.interfaces, ...docs.types, ...docs.functions] + .forEach(item => filePaths.add(item.filePath)); + + // Create groups for each file path + return Array.from(filePaths).map(filePath => { + return { + filePath, + classes: docs.classes.filter(c => c.filePath === filePath), + methods: docs.methods.filter(m => m.filePath === filePath), + interfaces: docs.interfaces.filter(i => i.filePath === filePath), + types: docs.types.filter(t => t.filePath === filePath), + functions: docs.functions.filter(f => f.filePath === filePath) + }; + }); + } + + private formatFilePath(filePath: string): string { + // Get relative path from src directory + const srcIndex = filePath.indexOf('/src/'); + if (srcIndex === -1) return filePath; + + const relativePath = filePath.slice(srcIndex + 5); // +5 to skip '/src/' + return relativePath; + } + + private async generateFileUsageDoc(fileGroup: FileDocsGroup): Promise { + const filePath = this.formatFilePath(fileGroup.filePath); + const prompt = `${PROMPT_TEMPLATES.fileUsageDoc}\n\nFor file: ${filePath}\n\nWith components:\n${this.formatComponents(fileGroup)}`; + const doc = await this.generateComment(prompt); + return `### ${filePath}\n\n${doc}`; + } + + private async generateFileApiDoc(fileGroup: FileDocsGroup): Promise { + const filePath = this.formatFilePath(fileGroup.filePath); + const formattedDocs = this.formatApiComponents(fileGroup); + return formattedDocs ? `### ${filePath}\n\n${formattedDocs}` : ''; + } + + private formatApiComponents(fileGroup: FileDocsGroup): string { + const sections: string[] = []; + + // Classes + if (fileGroup.classes.length > 0) { + sections.push('#### Classes\n'); + fileGroup.classes.forEach(c => { + sections.push(`##### ${c.name}\n`); + if (c.jsDoc) sections.push(`\`\`\`\n${c.jsDoc}\n\`\`\`\n`); + + // Add any methods belonging to this class + const classMethods = fileGroup.methods.filter(m => m.className === c.name); + if (classMethods.length > 0) { + sections.push('Methods:\n'); + classMethods.forEach(m => { + sections.push(`* \`${m.name}\`\n \`\`\`\n ${m.jsDoc || ''}\n \`\`\`\n`); + }); + } + }); + } + + // Interfaces + if (fileGroup.interfaces.length > 0) { + sections.push('#### Interfaces\n'); + fileGroup.interfaces.forEach(i => { + sections.push(`##### ${i.name}\n`); + if (i.jsDoc) sections.push(`\`\`\`\n${i.jsDoc}\n\`\`\`\n`); + }); + } + + // Types + if (fileGroup.types.length > 0) { + sections.push('#### Types\n'); + fileGroup.types.forEach(t => { + sections.push(`##### ${t.name}\n`); + if (t.jsDoc) sections.push(`\`\`\`\n${t.jsDoc}\n\`\`\`\n`); + }); + } + + // Standalone Functions (not class methods) + if (fileGroup.functions.length > 0) { + sections.push('#### Functions\n'); + fileGroup.functions.forEach(f => { + sections.push(`##### ${f.name}\n`); + if (f.jsDoc) sections.push(`\`\`\`\n${f.jsDoc}\n\`\`\`\n`); + }); + } + + // Standalone Methods (not belonging to any class) + const standaloneMethods = fileGroup.methods.filter(m => !m.className); + if (standaloneMethods.length > 0) { + sections.push('#### Methods\n'); + standaloneMethods.forEach(m => { + sections.push(`##### ${m.name}\n`); + if (m.jsDoc) sections.push(`\`\`\`\n${m.jsDoc}\n\`\`\`\n`); + }); + } + + return sections.join('\n'); + } + + private formatComponents(fileGroup: FileDocsGroup): string { + const sections: string[] = []; + + if (fileGroup.classes.length > 0) { + sections.push('Classes:', fileGroup.classes.map(c => `- ${c.name}: ${c.jsDoc}`).join('\n')); + } + + if (fileGroup.methods.length > 0) { + sections.push('Methods:', fileGroup.methods.map(m => `- ${m.name}: ${m.jsDoc}`).join('\n')); + } + + if (fileGroup.interfaces.length > 0) { + sections.push('Interfaces:', fileGroup.interfaces.map(i => `- ${i.name}: ${i.jsDoc}`).join('\n')); + } + + if (fileGroup.types.length > 0) { + sections.push('Types:', fileGroup.types.map(t => `- ${t.name}: ${t.jsDoc}`).join('\n')); + } + + if (fileGroup.functions.length > 0) { + sections.push('Functions:', fileGroup.functions.map(f => `- ${f.name}: ${f.jsDoc}`).join('\n')); + } + + return sections.join('\n\n'); + } + + + private async generateProviderDoc(provider: any): Promise { + const prompt = `${PROMPT_TEMPLATES.providerDoc}\n\nWith content:\n${JSON.stringify(provider, null, 2)}`; + return await this.generateComment(prompt); + } /** * Handle API errors by logging the error message and throwing the error. - * + * + * * @param {Error} error The error object to handle * @returns {void} */ diff --git a/scripts/jsdoc-automation/src/Configuration.ts b/scripts/jsdoc-automation/src/Configuration.ts index 84758d6230..d4ab4dcf75 100644 --- a/scripts/jsdoc-automation/src/Configuration.ts +++ b/scripts/jsdoc-automation/src/Configuration.ts @@ -27,6 +27,9 @@ interface ConfigurationData { pullRequestLabels: string[]; pullRequestReviewers: string[]; excludedFiles: string[]; + generateJsDoc: boolean; + generateReadme: boolean; + language: string; } /** @@ -37,10 +40,13 @@ export class Configuration implements Omit { private _rootDirectory!: ConfigurationData['rootDirectory']; private readonly repoRoot: string; private _branch: string = 'develop'; + private _language: string = 'English'; + private _generateJsDoc: boolean = true; + private _generateReadme: boolean = true; public excludedDirectories: string[] = []; public repository: Repository = { - owner: 'elizaOS', + owner: 'Ed-Marcavage', name: 'eliza', pullNumber: undefined }; @@ -56,6 +62,22 @@ export class Configuration implements Omit { this.loadConfiguration(); } + get language(): string { + return this._language; + } + + set language(value: string) { + this._language = value; + } + + get generateJsDoc(): boolean { + return this._generateJsDoc; + } + + get generateReadme(): boolean { + return this._generateReadme; + } + get rootDirectory(): ConfigurationData['rootDirectory'] { return this._rootDirectory; } @@ -86,7 +108,21 @@ export class Configuration implements Omit { private loadConfiguration(): void { // First try to get from environment variables + this._language = process.env.INPUT_LANGUAGE || 'English'; + console.log('Using language:', this._language); const rootDirectory = process.env.INPUT_ROOT_DIRECTORY; + this._generateJsDoc = process.env.INPUT_JSDOC + ? process.env.INPUT_JSDOC.toUpperCase() === 'T' + : true; // Default from workflow + this._generateReadme = process.env.INPUT_README + ? process.env.INPUT_README.toUpperCase() === 'T' + : true; // Default from workflow + + console.log('Documentation flags:', { + generateJsDoc: this._generateJsDoc, + generateReadme: this._generateReadme + }); + let inputs; console.log('Environment variables:', { diff --git a/scripts/jsdoc-automation/src/DocumentationGenerator.ts b/scripts/jsdoc-automation/src/DocumentationGenerator.ts index 1503e62524..c39421eccc 100644 --- a/scripts/jsdoc-automation/src/DocumentationGenerator.ts +++ b/scripts/jsdoc-automation/src/DocumentationGenerator.ts @@ -3,12 +3,14 @@ import { TypeScriptParser } from './TypeScriptParser.js'; import { JsDocAnalyzer } from './JsDocAnalyzer.js'; import { JsDocGenerator } from './JsDocGenerator.js'; import type { TSESTree } from '@typescript-eslint/types'; -import { ASTQueueItem, FullModeFileChange, PrModeFileChange } from './types/index.js'; +import { ASTQueueItem, EnvUsage, FullModeFileChange, PrModeFileChange, TodoItem } from './types/index.js'; import { GitManager } from './GitManager.js'; import fs from 'fs'; import { Configuration } from './Configuration.js'; import path from 'path'; import { AIService } from './AIService.js'; +import { PluginDocumentationGenerator } from './PluginDocumentationGenerator.js'; +import { JSDocValidator } from './JSDocValidator.js'; /** * Class representing a Documentation Generator. @@ -19,8 +21,10 @@ export class DocumentationGenerator { public existingJsDocQueue: ASTQueueItem[] = []; private hasChanges: boolean = false; private fileContents: Map = new Map(); - private branchName: string = ''; + public branchName: string = ''; private fileOffsets: Map = new Map(); + private typeScriptFiles: string[] = []; + private jsDocValidator: JSDocValidator; /** * Constructor for initializing the object with necessary dependencies. @@ -41,8 +45,11 @@ export class DocumentationGenerator { public jsDocGenerator: JsDocGenerator, public gitManager: GitManager, public configuration: Configuration, - public aiService: AIService - ) { } + public aiService: AIService, + ) { + this.typeScriptFiles = this.directoryTraversal.traverse(); + this.jsDocValidator = new JSDocValidator(aiService); + } /** * Asynchronously generates JSDoc comments for the TypeScript files based on the given pull request number or full mode. @@ -50,7 +57,7 @@ export class DocumentationGenerator { * @param pullNumber - Optional. The pull request number to generate JSDoc comments for. * @returns A promise that resolves once the JSDoc generation process is completed. */ - public async generate(pullNumber?: number): Promise { + public async generate(pullNumber?: number): Promise<{ documentedItems: ASTQueueItem[], branchName: string | undefined }> { let fileChanges: PrModeFileChange[] | FullModeFileChange[] = []; this.fileOffsets.clear(); @@ -95,7 +102,6 @@ export class DocumentationGenerator { if (fileChange.status === 'deleted') continue; const filePath = this.configuration.toAbsolutePath(fileChange.filename); - console.log(`Processing file: ${filePath}`, 'resetting file offsets', 'from ', this.fileOffsets.get(filePath), 'to 0'); this.fileOffsets.set(filePath, 0); // Load and store file content @@ -104,7 +110,6 @@ export class DocumentationGenerator { const fileContent = await this.getFileContent(fileChange.contents_url); this.fileContents.set(filePath, fileContent); } else { - console.log('Getting file content from local file system'); const fileContent = fs.readFileSync(filePath, 'utf-8'); this.fileContents.set(filePath, fileContent); } @@ -125,8 +130,13 @@ export class DocumentationGenerator { // Process nodes that need JSDoc if (this.missingJsDocQueue.length > 0) { - this.branchName = `docs-update-${pullNumber || 'full'}-${Date.now()}`; - await this.gitManager.createBranch(this.branchName, this.configuration.branch); + // Always create branch if we have missing JSDoc, even if we're only generating README + // This way we have a branch for either JSDoc commits or README commits + + if (this.configuration.generateJsDoc) { + this.branchName = `docs-update-${pullNumber || 'full'}-${Date.now()}`; + await this.gitManager.createBranch(this.branchName, this.configuration.branch); + } // Process each node for (const queueItem of this.missingJsDocQueue) { @@ -136,11 +146,18 @@ export class DocumentationGenerator { } else { comment = await this.jsDocGenerator.generateComment(queueItem); } - await this.updateFileWithJSDoc(queueItem.filePath, comment, queueItem.startLine); - this.hasChanges = true; + + // Only update the actual files with JSDoc if generateJsDoc flag is true + if (this.configuration.generateJsDoc) { + await this.updateFileWithJSDoc(queueItem.filePath, comment, queueItem.startLine); + this.hasChanges = true; + } + + queueItem.jsDoc = comment; + this.existingJsDocQueue.push(queueItem); } - // Commit changes if any updates were made + // Only commit and create PR for JSDoc changes if generateJsDoc is true if (this.hasChanges && this.branchName) { for (const [filePath, content] of this.fileContents) { await this.gitManager.commitFile( @@ -161,7 +178,13 @@ export class DocumentationGenerator { reviewers: this.configuration.pullRequestReviewers || [] }); } + + } + return { + documentedItems: this.existingJsDocQueue, + branchName: this.branchName + }; } /** @@ -218,12 +241,33 @@ export class DocumentationGenerator { const content = this.fileContents.get(filePath) || ''; const lines = content.split('\n'); const currentOffset = this.fileOffsets.get(filePath) || 0; - const newLines = (jsDoc.match(/\n/g) || []).length + 1; const adjustedLine = insertLine + currentOffset; + const fileName = filePath.split('/').pop() || ''; + // Insert the comment lines.splice(adjustedLine - 1, 0, jsDoc); - this.fileOffsets.set(filePath, currentOffset + newLines); - this.fileContents.set(filePath, lines.join('\n')); + const newContent = lines.join('\n'); + + try { + // Validate and fix if necessary + const validatedJSDoc = await this.jsDocValidator.validateAndFixJSDoc(fileName,newContent, jsDoc); + + if (validatedJSDoc !== jsDoc) { + // If the comment was fixed, update the content + lines[adjustedLine - 1] = validatedJSDoc; + const newLines = (validatedJSDoc.match(/\n/g) || []).length + 1; + this.fileOffsets.set(filePath, currentOffset + newLines); + } else { + // console log just the file name from the path, and that the comment was valid + const newLines = (jsDoc.match(/\n/g) || []).length + 1; + this.fileOffsets.set(filePath, currentOffset + newLines); + } + + this.fileContents.set(filePath, lines.join('\n')); + } catch (error) { + console.error(`Error validating JSDoc in ${filePath}:`, error); + throw error; + } } /** @@ -267,29 +311,56 @@ export class DocumentationGenerator { const modifiedFiles = Array.from(this.fileContents.keys()); const filesContext = modifiedFiles.map(file => `- ${file}`).join('\n'); - const prompt = `Generate a pull request title and description for adding JSDoc documentation. - Context: - - ${modifiedFiles.length} files were modified - - Files modified:\n${filesContext} - - This is ${pullNumber ? `related to PR #${pullNumber}` : 'a full repository documentation update'} - - This is an automated PR for adding JSDoc documentation + const prompt = `Create a JSON object for a pull request about JSDoc documentation updates. + The JSON must have exactly this format, with no extra fields or markdown formatting: + { + "title": "Brief title describing JSDoc updates", + "body": "Detailed description of changes" + } + + Context for generating the content: + - ${modifiedFiles.length} files were modified + - Files modified:\n${filesContext} + - This is ${pullNumber ? `related to PR #${pullNumber}` : 'a full repository documentation update'} + - This is an automated PR for adding JSDoc documentation - Generate both a title and description. The description should be detailed and include: - 1. A clear summary of changes - 2. Summary of modified files - 3. Instructions for reviewers + The title should be concise and follow conventional commit format. + The body should include: + 1. A clear summary of changes + 2. List of modified files + 3. Brief instructions for reviewers - Format the response as a JSON object with 'title' and 'body' fields.`; + Return ONLY the JSON object, no other text.`; const response = await this.aiService.generateComment(prompt); + try { - const content = JSON.parse(response); + // Clean up the response - remove any markdown formatting or extra text + const jsonStart = response.indexOf('{'); + const jsonEnd = response.lastIndexOf('}') + 1; + if (jsonStart === -1 || jsonEnd === -1) { + throw new Error('No valid JSON object found in response'); + } + + const jsonStr = response.slice(jsonStart, jsonEnd) + .replace(/```json/g, '') + .replace(/```/g, '') + .trim(); + + const content = JSON.parse(jsonStr); + + // Validate the parsed content + if (!content.title || !content.body || typeof content.title !== 'string' || typeof content.body !== 'string') { + throw new Error('Invalid JSON structure'); + } + return { title: content.title, body: content.body }; } catch (error) { - console.error('Error parsing AI response for PR content generation, using default values'); + console.error('Error parsing AI response for PR content:', error); + console.error('Raw response:', response); return { title: `docs: Add JSDoc documentation${pullNumber ? ` for PR #${pullNumber}` : ''}`, body: this.generateDefaultPRBody() @@ -316,4 +387,29 @@ export class DocumentationGenerator { ### 🤖 Generated by Documentation Bot This is an automated PR created by the documentation generator tool.`; } + + /** + * Analyzes TODOs and environment variables in the code + */ + public async analyzeCodebase(): Promise<{ todoItems: TodoItem[], envUsages: EnvUsage[] }> { + const todoItems: TodoItem[] = []; + const envUsages: EnvUsage[] = []; + + for (const filePath of this.typeScriptFiles) { + const ast = this.typeScriptParser.parse(filePath); + if (!ast) continue; + + const sourceCode = fs.readFileSync(filePath, 'utf-8'); + + // Find TODOs + this.jsDocAnalyzer.findTodoComments(ast, ast.comments || [], sourceCode); + todoItems.push(...this.jsDocAnalyzer.todoItems); + + // Find env usages + this.jsDocAnalyzer.findEnvUsages(ast, sourceCode); + envUsages.push(...this.jsDocAnalyzer.envUsages); + } + + return { todoItems, envUsages }; + } } \ No newline at end of file diff --git a/scripts/jsdoc-automation/src/JSDocValidator.ts b/scripts/jsdoc-automation/src/JSDocValidator.ts new file mode 100644 index 0000000000..e9f5ca8491 --- /dev/null +++ b/scripts/jsdoc-automation/src/JSDocValidator.ts @@ -0,0 +1,137 @@ +import { parse, ParserOptions } from '@typescript-eslint/parser'; +import { AIService } from './AIService.js'; + +export class JSDocValidator { + private parserOptions: ParserOptions = { + sourceType: 'module', + ecmaVersion: 2020, + ecmaFeatures: { + jsx: true + }, + range: true, + loc: true, + tokens: true, + comment: true + }; + + constructor(private aiService: AIService) {} + + /** + * Validates and fixes JSDoc comments in TypeScript code + */ + public async validateAndFixJSDoc(fileName: string, code: string, originalComment: string): Promise { + // First try parsing with the original comment + if (this.isValidTypeScript(code)) { + return originalComment; + } + + // Try fixing common JSDoc issues + const fixedComment = this.fixCommonJSDocIssues(originalComment); + const codeWithFixedComment = code.replace(originalComment, fixedComment); + + if (this.isValidTypeScript(codeWithFixedComment)) { + console.log(`✓ JSDoc comment in ${fileName} was fixed using regex patterns`); + return fixedComment; + } else { + console.log(`❌JSDoc comment in ${fileName} regex patterns failed, making AI call for help`); + } + + // If still invalid, try regenerating with AI + try { + const regeneratedComment = await this.regenerateJSDoc(code); + const codeWithRegeneratedComment = code.replace(originalComment, regeneratedComment); + + if (this.isValidTypeScript(codeWithRegeneratedComment)) { + console.log(`✓ JSDoc comment in ${fileName} was regenerated using AI`); + return regeneratedComment; + } + } catch (error) { + console.error(`Error during AI regeneration for ${fileName}:`, error); + } + + // Instead of throwing, log the issue and return original + console.warn(`⚠️ HUMAN INTERVENTION NEEDED - Invalid JSDoc in ${fileName}`); + console.warn('Original comment:', originalComment); + return originalComment; + } + + /** + * Checks if the TypeScript code is valid + */ + private isValidTypeScript(code: string): boolean { + try { + parse(code, this.parserOptions); + return true; + } catch (error) { + return false; + } + } + + /** + * Fixes common JSDoc formatting issues + */ + private fixCommonJSDocIssues(comment: string): string { + const fixes = [ + // Fix opening format + [/\/\*\*?(?!\*)/, '/**'], // Ensure proper opening + + // Fix body asterisks and spacing + [/\*{3,}/g, '**'], // Remove excessive asterisks in body + [/\*(?!\s|\*|\/)/g, '* '], // Add space after single asterisk + [/^(\s*)\*\s\s+/gm, '$1* '], // Remove multiple spaces after asterisk + + // Fix multi-line issues (from bash script insights) + [/\*\/\s*\n\s*\*\*\//g, '*/'], // Remove stray closing after proper closing + [/\n\s*\*\s*\n\s*\*\//g, '\n */'], // Fix empty line before closing + + // Fix closing format + [/\*+\//g, '*/'], // Fix multiple asterisks in closing + [/(? { + const prompt = `Fix the following JSDoc comment to be syntactically valid. + Ensure proper formatting: + - Start with /** + - Each line should start with a single * + - End with */ + - No extra asterisks + - Space after each asterisk + - Space before closing tag + + Code: + ${code} + + Return ONLY the fixed JSDoc comment, nothing else.`; + + return await this.aiService.generateComment(prompt); + } +} \ No newline at end of file diff --git a/scripts/jsdoc-automation/src/JsDocAnalyzer.ts b/scripts/jsdoc-automation/src/JsDocAnalyzer.ts index 223d1893b4..f05b09dba4 100644 --- a/scripts/jsdoc-automation/src/JsDocAnalyzer.ts +++ b/scripts/jsdoc-automation/src/JsDocAnalyzer.ts @@ -1,6 +1,7 @@ import type { TSESTree } from '@typescript-eslint/types'; import { TypeScriptParser } from './TypeScriptParser.js'; -import { ASTQueueItem } from './types/index.js'; +import { ASTQueueItem, EnvUsage, TodoItem } from './types/index.js'; +import { ASTQueueItem, EnvUsage, TodoItem } from './types/index.js'; type AST_NODE_TYPES = { ClassDeclaration: 'ClassDeclaration'; @@ -156,6 +157,8 @@ export class JsDocAnalyzer { public missingJsDocNodes: TSESTree.Node[] = []; + public todoItems: TodoItem[] = []; + public envUsages: EnvUsage[] = []; /** * Constructor for initializing a new instance. @@ -387,4 +390,269 @@ export class JsDocAnalyzer { return methods; } + + + /** + * Finds TODO comments in the code and their associated nodes + * @param ast - The AST to analyze + * @param comments - Array of comments to search through + * @param sourceCode - The original source code + */ + public findTodoComments(ast: TSESTree.Program, comments: TSESTree.Comment[], sourceCode: string): void { + this.todoItems = []; + + comments.forEach(comment => { + if (!comment.loc) return; + + const commentText = comment.value.toLowerCase(); + if (commentText.includes('todo')) { + try { + // Find the nearest node after the comment + const nearestNode = this.findNearestNode(ast, comment.loc.end.line); + if (nearestNode && nearestNode.loc) { + // Find the containing function/class/block + const containingBlock = this.findContainingBlock(nearestNode); + + // Extract the actual code associated with the TODO + const code = this.extractNodeCode(sourceCode, nearestNode); + + // Extract the full context (entire function/class/block) + const fullContext = containingBlock && containingBlock.loc + ? this.extractNodeCode(sourceCode, containingBlock) + : code; + + this.todoItems.push({ + comment: comment.value.trim(), + code, + fullContext, + node: nearestNode, + location: comment.loc, + contextLocation: containingBlock?.loc || comment.loc + }); + } + } catch (error) { + console.error('Error processing TODO comment:', error); + // Continue processing other comments even if one fails + } + } + }); +} + +/** + * Finds the containing block (function/class/interface declaration) for a node + */ +private findContainingBlock(node: TSESTree.Node): TSESTree.Node | undefined { + let current = node; + while (current.parent) { + if ( + current.parent.type === 'FunctionDeclaration' || + current.parent.type === 'ClassDeclaration' || + current.parent.type === 'TSInterfaceDeclaration' || + current.parent.type === 'MethodDefinition' || + current.parent.type === 'ArrowFunctionExpression' || + current.parent.type === 'FunctionExpression' + ) { + return current.parent; + } + current = current.parent; + } + return undefined; +} + +/** + * Finds environment variable usage in the code + * @param ast - The AST to analyze + * @param sourceCode - The original source code + */ +public findEnvUsages(ast: TSESTree.Program, sourceCode: string): void { + this.envUsages = []; + + const findEnvReferences = (node: TSESTree.Node) => { + if (!node.loc) return; + + // Check for process.env + if ( + node.type === 'MemberExpression' && + node.object.type === 'Identifier' && + node.object.name === 'process' && + node.property.type === 'Identifier' && + node.property.name === 'env' + ) { + // Get the parent statement/expression for context + const contextNode = this.findParentStatement(node); + // Get the containing function/block for full context + const containingBlock = this.findContainingBlock(node); + + // Get just the process.env reference + const code = this.extractNodeCode(sourceCode, node); + + // Get the full line by using the line number directly + const lines = sourceCode.split('\n'); + const context = lines[node.loc.start.line - 1]; + + // Get the entire function/block containing this env usage + const fullContext = containingBlock ? this.extractFullContext(sourceCode, containingBlock) : context; + + this.envUsages.push({ + code, + context, + fullContext, + node, + location: node.loc, + contextLocation: containingBlock?.loc || node.loc + }); + } + + // Continue traversing + Object.keys(node).forEach(key => { + const child = node[key as keyof TSESTree.Node]; + if (child && typeof child === 'object') { + if (Array.isArray(child)) { + child.forEach(item => { + if (item && typeof item === 'object') { + findEnvReferences(item as TSESTree.Node); + } + }); + } else { + findEnvReferences(child as TSESTree.Node); + } + } + }); + }; + + findEnvReferences(ast); +} + +/** + * Extracts the actual source code for a given node + */ +private extractNodeCode(sourceCode: string, node: TSESTree.Node): string { + if (!node.loc) { + return ''; + } + + const lines = sourceCode.split('\n'); + const startLine = node.loc.start.line - 1; + const endLine = node.loc.end.line; + + if (startLine < 0 || endLine > lines.length) { + return ''; + } + + // Handle single-line case + if (startLine === endLine - 1) { + const line = lines[startLine]; + return line.slice(node.loc.start.column, node.loc.end.column); + } + + // Handle multi-line case + const result = []; + for (let i = startLine; i < endLine; i++) { + let line = lines[i]; + if (i === startLine) { + line = line.slice(node.loc.start.column); + } else if (i === endLine - 1) { + line = line.slice(0, node.loc.end.column); + } + result.push(line); + } + return result.join('\n'); +} + +/** + * Extracts the full context including any variable declarations and surrounding code + */ +private extractFullContext(sourceCode: string, node: TSESTree.Node): string { + if (!node.loc) return ''; + + const lines = sourceCode.split('\n'); + const startLine = node.loc.start.line - 1; + const endLine = node.loc.end.line; + + if (startLine < 0 || endLine > lines.length) { + return ''; + } + + // Get the complete lines for the entire block/function + return lines.slice(startLine, endLine).join('\n'); +} + +/** + * Finds the parent statement or expression node + */ +// prettyr sure this isnt needed, directly access code rather +private findParentStatement(node: TSESTree.Node): TSESTree.Node | undefined { + let current = node; + while (current.parent) { + // Add more statement types that could contain process.env + if ( + current.parent.type === 'VariableDeclaration' || + current.parent.type === 'ExpressionStatement' || + current.parent.type === 'AssignmentExpression' || + current.parent.type === 'ReturnStatement' || + current.parent.type === 'IfStatement' || + current.parent.type === 'LogicalExpression' || + current.parent.type === 'BinaryExpression' || + current.parent.type === 'Property' || + current.parent.type === 'ObjectExpression' || + current.parent.type === 'MemberExpression' + ) { + return current.parent; + } + // Add logging to see what types we're encountering + console.log('Parent node type:', current.parent.type); + current = current.parent; + } + return undefined; +} + +/** + * Finds the nearest node after a specific line number + */ +private findNearestNode(ast: TSESTree.Program, lineNumber: number): TSESTree.Node | undefined { + let nearestNode: TSESTree.Node | undefined; + let smallestDistance = Infinity; + + const traverse = (node: TSESTree.Node | null) => { + if (!node) return; + + // Check if the node has a location + if (node.loc) { + const distance = node.loc.start.line - lineNumber; + if (distance > 0 && distance < smallestDistance) { + smallestDistance = distance; + nearestNode = node; + } + } + + // Safely traverse child nodes + if ('body' in node) { + const body = Array.isArray(node.body) ? node.body : [node.body]; + body.forEach((child: TSESTree.Node) => { + if (child && typeof child === 'object') { + traverse(child as TSESTree.Node); + } + }); + } + + // Handle specific node types + if ('declarations' in node && Array.isArray(node.declarations)) { + node.declarations.forEach((decl: TSESTree.Node) => traverse(decl)); + } + + if ('declaration' in node && node.declaration) { + traverse(node.declaration); + } + + // Handle other properties that might contain nodes + ['consequent', 'alternate', 'init', 'test', 'update'].forEach(prop => { + if (prop in node && node[prop as keyof typeof node]) { + traverse(node[prop as keyof typeof node] as TSESTree.Node); + } + }); + }; + + traverse(ast); + return nearestNode; +} } \ No newline at end of file diff --git a/scripts/jsdoc-automation/src/PluginDocumentationGenerator.ts b/scripts/jsdoc-automation/src/PluginDocumentationGenerator.ts new file mode 100644 index 0000000000..ac9f4dd95a --- /dev/null +++ b/scripts/jsdoc-automation/src/PluginDocumentationGenerator.ts @@ -0,0 +1,105 @@ +import { ASTQueueItem, PluginDocumentation, TodoItem, EnvUsage } from './types/index.js'; +import { AIService } from './AIService.js'; +import { GitManager } from './GitManager.js'; +import { Configuration } from './Configuration.js'; +import fs from 'fs'; +import path from 'path'; + +/** + * Generates comprehensive plugin documentation based on existing JSDoc comments + */ +export class PluginDocumentationGenerator { + constructor( + private aiService: AIService, + private gitManager: GitManager, + private configuration: Configuration + ) { } + + /** + * Generates comprehensive plugin documentation + * @param {ASTQueueItem[]} existingDocs - Queue of documented items + * @param {string} branchName - Current git branch name + * @param {TodoItem[]} todoItems - List of TODO items found in the codebase + * @param {EnvUsage[]} envUsages - List of environment variable usages + */ + public async generate( + existingDocs: ASTQueueItem[], + branchName?: string, + todoItems: TodoItem[] = [], + envUsages: EnvUsage[] = [] + ): Promise { + // Read package.json + const packageJsonPath = path.join(this.configuration.absolutePath, 'package.json'); + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); + if (!packageJson) { + console.error('package.json not found'); + } + + // Read existing README if it exists + const readmePath = path.join(this.configuration.absolutePath, 'README-automated.md'); + const readmeContent = fs.existsSync(readmePath) + ? fs.readFileSync(readmePath, 'utf-8') + : undefined; + + // Generate documentation + const documentation = await this.aiService.generatePluginDocumentation({ + existingDocs, + packageJson, + readmeContent, + todoItems, + envUsages + }); + + // Generate and write markdown + const markdownContent = this.generateMarkdownContent(documentation, packageJson); + fs.writeFileSync(readmePath, markdownContent); + + // Commit if we're in a branch + if (branchName) { + await this.gitManager.commitFile( + branchName, + 'README.md', + markdownContent, + 'docs: Update plugin documentation' + ); + } + } + + private generateMarkdownContent(docs: PluginDocumentation, packageJson: any): string { + return `# ${packageJson.name} Documentation + +## Overview +${docs.overview} + +## Installation +${docs.installation} + +## Configuration +${docs.configuration} + +## Features + +### Actions +${docs.actionsDocumentation} + +### Providers +${docs.providersDocumentation} + +### Evaluators +${docs.evaluatorsDocumentation} + +## Usage Examples +${docs.usage} + +## API Reference +${docs.apiReference} + +## Development + +### TODO Items +${docs.todos} + +### Troubleshooting +${docs.troubleshooting}`; +} +} \ No newline at end of file diff --git a/scripts/jsdoc-automation/src/TypeScriptParser.ts b/scripts/jsdoc-automation/src/TypeScriptParser.ts index 2d40963042..ee781fda33 100644 --- a/scripts/jsdoc-automation/src/TypeScriptParser.ts +++ b/scripts/jsdoc-automation/src/TypeScriptParser.ts @@ -1,5 +1,6 @@ import * as fs from 'fs'; import { parse, ParserOptions } from '@typescript-eslint/parser'; +import { ActionBounds, ActionMetadata } from './types'; /** * A class for parsing TypeScript files. @@ -7,7 +8,7 @@ import { parse, ParserOptions } from '@typescript-eslint/parser'; export class TypeScriptParser { /** * Parses the content of a file using the given file path. - * + * * @param {string} file - The file path containing the content to be parsed. * @returns {any} The abstract syntax tree (AST) representation of the parsed content. */ @@ -44,13 +45,80 @@ export class TypeScriptParser { } } - /** - * Handles a parse error that occurs during TypeScript parsing. - * - * @param {Error} error - The error that occurred during parsing - * @returns {void} - */ - public handleParseError(error: Error): void { - console.error('TypeScript Parsing Error:', error); + public extractExports(file: string): { actions: string[], providers: string[], evaluators: string[] } { + //const content = fs.readFileSync(file, 'utf-8'); + const ast = this.parse(file); + + const exports: { actions: string[], providers: string[], evaluators: string[] } = { + actions: [], + providers: [], + evaluators: [], + }; + + if (ast) { + // Traverse the AST to find export declarations + ast.body.forEach((node: any) => { + if (node.type === 'ImportDeclaration') { + const source = node.source.value; + if (source.startsWith('./actions/')) { + exports.actions.push(source); + } else if (source.startsWith('./providers/')) { + exports.providers.push(source); + } else if (source.startsWith('./evaluators/')) { + exports.evaluators.push(source); + } + } + }); + } + + return exports; + } + + public findActionBounds(ast: any): ActionBounds | null { + let startLine: number | null = null; + let endLine: number | null = null; + + const findActionTypeAnnotation = (node: any) => { + // Look for Action type annotation + if (node?.typeAnnotation?.typeAnnotation?.typeName?.name === 'Action') { + startLine = node.loc.start.line; + } + + // Look for ActionExample type annotation to find the end + if (node?.typeAnnotation?.elementType?.elementType?.typeName?.name === 'ActionExample') { + endLine = node.loc.end.line; + } + + // Recursively search in child nodes + for (const key in node) { + if (node[key] && typeof node[key] === 'object') { + if (Array.isArray(node[key])) { + node[key].forEach(findActionTypeAnnotation); + } else { + findActionTypeAnnotation(node[key]); + } + } + } + }; + + findActionTypeAnnotation(ast); + + if (startLine && endLine) { + return { startLine, endLine }; + } + + return null; + } + + public extractActionCode(filePath: string, bounds: ActionBounds): string { + const fileContent = fs.readFileSync(filePath, 'utf-8'); + const lines = fileContent.split('\n'); + + // Extract lines from start to end (inclusive) + return lines.slice(bounds.startLine - 1, bounds.endLine).join('\n'); + } + + private handleParseError(error: Error): void { + console.error('Error parsing TypeScript file:', error.message); } -} \ No newline at end of file +} diff --git a/scripts/jsdoc-automation/src/index.ts b/scripts/jsdoc-automation/src/index.ts index b3156e0608..b94cfa9dab 100644 --- a/scripts/jsdoc-automation/src/index.ts +++ b/scripts/jsdoc-automation/src/index.ts @@ -6,6 +6,7 @@ import { DocumentationGenerator } from './DocumentationGenerator.js'; import { Configuration } from './Configuration.js'; import { AIService } from './AIService.js'; import { GitManager } from './GitManager.js'; +import { PluginDocumentationGenerator } from './PluginDocumentationGenerator.js'; /** * Main function for generating documentation. @@ -46,7 +47,7 @@ async function main() { ); const typeScriptParser = new TypeScriptParser(); const jsDocAnalyzer = new JsDocAnalyzer(typeScriptParser); - const aiService = new AIService(); + const aiService = new AIService(configuration); const jsDocGenerator = new JsDocGenerator(aiService); const documentationGenerator = new DocumentationGenerator( @@ -59,8 +60,54 @@ async function main() { aiService ); - // Generate documentation - await documentationGenerator.generate(configuration.repository.pullNumber); + const pluginDocGenerator = new PluginDocumentationGenerator( + aiService, + gitManager, + configuration + ); + + const { todoItems, envUsages } = await documentationGenerator.analyzeCodebase(); + + // Generate JSDoc documentation first + const { documentedItems, branchName } = await documentationGenerator.generate( + configuration.repository.pullNumber + ); + + // If both are true, use JSDoc branch for README + // If only README is true, create new branch + if (configuration.generateReadme) { + const targetBranch = (configuration.generateJsDoc && branchName) + ? branchName + : `docs-update-readme-${Date.now()}`; + + if (!configuration.generateJsDoc) { + await gitManager.createBranch(targetBranch, configuration.branch); + } + + await pluginDocGenerator.generate( + documentedItems, + targetBranch, + todoItems, + envUsages + ); + + // Only create PR if we're not also generating JSDoc (otherwise changes go in JSDoc PR) + if (!configuration.generateJsDoc) { + const prContent = { + title: "docs: Update plugin documentation", + body: "Updates plugin documentation with latest changes" + }; + + await gitManager.createPullRequest({ + title: prContent.title, + body: prContent.body, + head: targetBranch, + base: configuration.branch, + labels: ['documentation', 'automated-pr'], + reviewers: configuration.pullRequestReviewers || [] + }); + } + } } catch (error) { console.error('Error during documentation generation:', { message: error instanceof Error ? error.message : String(error), diff --git a/scripts/jsdoc-automation/src/types/index.ts b/scripts/jsdoc-automation/src/types/index.ts index 238403b4ae..2762f850d1 100644 --- a/scripts/jsdoc-automation/src/types/index.ts +++ b/scripts/jsdoc-automation/src/types/index.ts @@ -1,3 +1,7 @@ +import { TSESTree } from "@typescript-eslint/types"; + +import { TSESTree } from "@typescript-eslint/types"; + export interface ASTQueueItem { name: string; filePath: string; @@ -26,4 +30,74 @@ export interface PrModeFileChange extends FullModeFileChange { deletions: number; changes: number; contents_url: string; -} \ No newline at end of file +} + +export interface OrganizedDocs { + classes: ASTQueueItem[]; + methods: ASTQueueItem[]; + interfaces: ASTQueueItem[]; + types: ASTQueueItem[]; + functions: ASTQueueItem[]; +} + +export interface TodoSection { + todos: string; + todoCount: number; +} + +export interface TodoItem { + comment: string; + code: string; + fullContext: string; + node: TSESTree.Node; + location: { + start: { line: number; column: number }; + end: { line: number; column: number }; + }; + contextLocation: { + start: { line: number; column: number }; + end: { line: number; column: number }; + }; +} + +export interface EnvUsage { + code: string; + context: string; + fullContext: string; + node: TSESTree.Node; + location: { + start: { line: number; column: number }; + end: { line: number; column: number }; + }; + contextLocation: { + start: { line: number; column: number }; + end: { line: number; column: number }; + }; +} + +export interface PluginDocumentation { + overview: string; + installation: string; + configuration: string; + usage: string; + apiReference: string; + troubleshooting: string; + todos: string; + actionsDocumentation: string; + providersDocumentation: string; + evaluatorsDocumentation: string; +} + +export interface ActionMetadata { + name: string; + similes: string[]; + validate: string; + handler: string; + examples: string[]; + description: string; +} + +export interface ActionBounds { + startLine: number; + endLine: number; +} diff --git a/scripts/jsdoc-automation/src/utils/prompts.ts b/scripts/jsdoc-automation/src/utils/prompts.ts new file mode 100644 index 0000000000..54e1ad10a8 --- /dev/null +++ b/scripts/jsdoc-automation/src/utils/prompts.ts @@ -0,0 +1,177 @@ +import { OrganizedDocs } from "../types"; + +export const PROMPT_TEMPLATES = { + overview: (packageJson: any, docs: OrganizedDocs) => ` + Create an overview for ${packageJson.name} with the following structure and details: + +### Purpose +[Write a comprehensive paragraph explaining the main purpose based on the package details below] + +Package Information: +- Name: ${packageJson.name} +- Description: ${packageJson.description || 'N/A'} +- Version: ${packageJson.version || 'N/A'} +- Keywords: ${(packageJson.keywords || []).join(', ')} + +### Key Features + +Code Components: +${docs.classes.length > 0 ? ` +Classes: +${docs.classes.map(c => `- ${c.name}: ${c.jsDoc}`).join('\n')}` : ''} + +${docs.interfaces.length > 0 ? ` +Interfaces: +${docs.interfaces.map(i => `- ${i.name}: ${i.jsDoc}`).join('\n')}` : ''} + +${docs.types.length > 0 ? ` +Types: +${docs.types.map(t => `- ${t.name}: ${t.jsDoc}`).join('\n')}` : ''} + +${docs.functions.length > 0 ? ` +Functions: +${docs.functions.map(f => `- ${f.name}: ${f.jsDoc}`).join('\n')}` : ''} + +Based on the above components, list the key features and capabilities of this plugin: +- Feature 1: Brief description +- Feature 2: Brief description +[List key features with brief descriptions] + +Format in markdown without adding any additional headers.`, + + installation: `Create installation instructions with the following structure: + +### Prerequisites +[List any prerequisites] + +### Steps +1. [First step with code example if needed] +2. [Second step with code example if needed] +[Number each step clearly] + +### Verification +[How to verify successful installation] + +Format in markdown without adding any additional headers.`, + + configuration: `Create configuration documentation with the following structure: + +### Environment Variables +[Table or list of all environment variables with descriptions] + +### Example Configuration +\`\`\`env +[Example .env file] +\`\`\` + +### Important Notes +[Any important notes about configuration] + +Format in markdown without adding any additional headers.`, + + actionDoc: `Generate documentation for this action with the following structure: + +### [action name] +[Brief description of the action] + +#### Properties +- Name: [action name] +- Similes: [list of similes] + +#### Handler +[Description of what the handler does] + +#### Examples +[Use Examples object in Action code to give a Natural language example replace {{user2}} with "Agent" and {{user1}} with "User"] + +Format in markdown without adding any additional headers.`, + + providerDoc: `Generate documentation for this provider with the following structure: + +### [Provider Name] +[Brief description of the provider] + +#### Methods +[Focus on the get() method and its functionality.] + +#### Usage +\`\`\`typescript +[Example usage code] +\`\`\` + +Format in markdown without adding any additional headers.`, + + fileUsageDoc: `Determine multiple use cases for the provided code, and give examples of how to use the code: + +### Common Use Cases +1. [First use case with code example] +2. [Second use case with code example] + +### Best Practices +- [Best practice 1] +- [Best practice 2] + +Format in markdown without adding any additional headers.`, + + fileApiDoc: `Generate API reference documentation with the following structure: + +### Classes +\`\`\`typescript +[List each class with its methods and properties] +\`\`\` +### Interfaces +\`\`\`typescript +[List each interface with its properties] +\`\`\` + +### Types +\`\`\`typescript +[List each type with its definition] +\`\`\` + +### Functions +\`\`\`typescript +[List each function with its parameters and return type] +\`\`\` + + +Create a comprehensive API reference including: +1. Class descriptions and methods +2. Method signatures and parameters +3. Return types and values +4. Interface definitions +5. Type definitions +6. Examples for complex APIs + +Format the response in markdown with proper headings and code blocks.`, + + todos: `Generate TODO documentation with the following structure: + +### Items +1. [First TODO item] + - Context: [describe the TODO] + - Type: [bug/feature/enhancement] +2. [Second TODO item] + - Context: [describe the TODO] + - Type: [bug/feature/enhancement] + +Format in markdown without adding any additional headers.`, + + troubleshooting: `Generate troubleshooting guide with the following structure: + +### Common Issues +1. [First issue] + - Cause: [cause of the issue] + - Solution: [how to solve it] + +### Debugging Tips +- [First debugging tip] +- [Second debugging tip] +- Ask your questions at https://eliza.gg/ 🚀 or in our discord + +### FAQ +Q: [Common question] +A: [Answer with example if applicable] + +Format in markdown without adding any additional headers.` +}; \ No newline at end of file diff --git a/scripts/jsdoc-automation/tsconfig.json b/scripts/jsdoc-automation/tsconfig.json index 777a040a61..704e32bf4d 100644 --- a/scripts/jsdoc-automation/tsconfig.json +++ b/scripts/jsdoc-automation/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "module": "node16", + "strict": true, "esModuleInterop": true, + "skipLibCheck": true, "target": "ES2020", - "moduleResolution": "node16", - "outDir": "dist", - "baseUrl": ".", - "sourceMap": true, - "strict": true + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true }, "include": [ - "**/*.ts" + "src/**/*.ts" ], "exclude": [ - "node_modules" + "node_modules", + "dist" ] } \ No newline at end of file diff --git a/scripts/jsdoc-automation/tsup.config.ts b/scripts/jsdoc-automation/tsup.config.ts new file mode 100644 index 0000000000..6713123597 --- /dev/null +++ b/scripts/jsdoc-automation/tsup.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from 'tsup' + +export default defineConfig({ + entry: ['src/index.ts'], + format: ['cjs', 'esm'], + dts: true, + splitting: false, + sourcemap: true, + clean: true, + target: 'node16', + outDir: 'dist', + treeshake: true, + }) \ No newline at end of file