From 2c3810662ec13de8b8c6efd53e2cac924c071814 Mon Sep 17 00:00:00 2001 From: indexzero Date: Wed, 1 Apr 2026 02:55:27 -0400 Subject: [PATCH 1/2] build(lint) replace xo with biome xo pulls in 340+ transitive deps and fights the codebase on camelCase and await-in-loop. Biome gives the same formatting and lint coverage with a single native binary, no eslint-disable comments, and faster check times. - Add biome.json adapted from ecosystems-rebuilder.js config - Remove xo devDependency and xo.config.js - Strip all eslint-disable comments from src/ and test/ - Auto-fix formatting (spacing, template literals, hook deps) - Update CLAUDE.md linting section - All 90 tests pass, 0 lint errors Co-Authored-By: Claude Opus 4.6 --- biome.json | 63 + package.json | 8 +- pnpm-lock.yaml | 3666 ++-------------------------------- src/catalog-diff.js | 62 +- src/catalog.js | 30 +- src/cli.js | 129 +- src/commands/batch.js | 134 +- src/commands/catalog-diff.js | 37 +- src/commands/catalog.js | 33 +- src/commands/diff.js | 62 +- src/commands/fetch.js | 127 +- src/commands/outdated.js | 78 +- src/commands/pin.js | 58 +- src/commands/scan.js | 118 +- src/commands/upgrade.js | 261 +-- src/commands/verify.js | 70 +- src/detector.js | 4 +- src/index.js | 38 +- src/lineage.js | 49 +- src/presets.js | 17 +- src/remote.js | 103 +- src/scanner.js | 165 +- src/tree.js | 24 +- src/vlurpfile.js | 6 +- test/catalog-diff.test.js | 58 +- test/cli.test.js | 14 +- test/lineage.test.js | 148 +- test/remote.test.js | 49 +- test/scanner.test.js | 9 +- test/tree.test.js | 27 +- test/upgrade.test.js | 66 +- test/vlurpfile.test.js | 9 +- xo.config.js | 23 - 33 files changed, 1367 insertions(+), 4378 deletions(-) create mode 100644 biome.json delete mode 100644 xo.config.js diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..c2cf7f9 --- /dev/null +++ b/biome.json @@ -0,0 +1,63 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.4.10/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false, + "includes": ["**", "!**/scratch", "!**/node_modules", "!**/output", "!**/coverage"] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 100 + }, + "assist": { "actions": { "source": { "organizeImports": "on" } } }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "correctness": { + "noUnusedFunctionParameters": "warn", + "noUnusedVariables": "warn", + "noUnusedImports": "warn", + "noUnsafeFinally": "warn", + "useYield": "warn", + "noInvalidUseBeforeDeclaration": "warn" + }, + "complexity": { + "useLiteralKeys": "warn", + "useOptionalChain": "warn", + "noStaticOnlyClass": "warn" + }, + "style": { + "useBlockStatements": "off", + "useTemplate": "warn", + "useConst": "warn" + }, + "suspicious": { + "noAssignInExpressions": "warn", + "noAsyncPromiseExecutor": "warn", + "noTemplateCurlyInString": "warn", + "noControlCharactersInRegex": "warn", + "useIterableCallbackReturn": "warn", + "useAdjacentOverloadSignatures": "warn", + "noShadowRestrictedNames": "warn" + }, + "performance": { + "noDynamicNamespaceImportAccess": "warn" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "semicolons": "always", + "trailingCommas": "none", + "arrowParentheses": "asNeeded" + } + } +} diff --git a/package.json b/package.json index 70d8041..764946c 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ }, "scripts": { "test": "node --test test/*.test.js", - "lint": "xo", - "lint:fix": "xo --fix", + "lint": "biome check", + "lint:fix": "biome check --fix", "changeset": "changeset" }, "keywords": [ @@ -41,7 +41,7 @@ "undici": "^7.13.0" }, "devDependencies": { - "@changesets/cli": "^2.29.5", - "xo": "^1.2.1" + "@biomejs/biome": "^2.4.10", + "@changesets/cli": "^2.29.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3cfec7f..ecffee1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,12 +39,12 @@ importers: specifier: ^7.13.0 version: 7.13.0 devDependencies: + '@biomejs/biome': + specifier: ^2.4.10 + version: 2.4.10 '@changesets/cli': specifier: ^2.29.5 version: 2.29.5 - xo: - specifier: ^1.2.1 - version: 1.2.1(@types/eslint@8.56.12)(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(typescript@5.8.3) packages: @@ -52,18 +52,63 @@ packages: resolution: {integrity: sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw==} engines: {node: '>=14.13.1'} - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.2': resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==} engines: {node: '>=6.9.0'} + '@biomejs/biome@2.4.10': + resolution: {integrity: sha512-xxA3AphFQ1geij4JTHXv4EeSTda1IFn22ye9LdyVPoJU19fNVl0uzfEuhsfQ4Yue/0FaLs2/ccVi4UDiE7R30w==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.4.10': + resolution: {integrity: sha512-vuzzI1cWqDVzOMIkYyHbKqp+AkQq4K7k+UCXWpkYcY/HDn1UxdsbsfgtVpa40shem8Kax4TLDLlx8kMAecgqiw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.4.10': + resolution: {integrity: sha512-14fzASRo+BPotwp7nWULy2W5xeUyFnTaq1V13Etrrxkrih+ez/2QfgFm5Ehtf5vSjtgx/IJycMMpn5kPd5ZNaA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.4.10': + resolution: {integrity: sha512-WrJY6UuiSD/Dh+nwK2qOTu8kdMDlLV3dLMmychIghHPAysWFq1/DGC1pVZx8POE3ZkzKR3PUUnVrtZfMfaJjyQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@2.4.10': + resolution: {integrity: sha512-7MH1CMW5uuxQ/s7FLST63qF8B3Hgu2HRdZ7tA1X1+mk+St4JOuIrqdhIBnnyqeyWJNI+Bww7Es5QZ0wIc1Cmkw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@2.4.10': + resolution: {integrity: sha512-kDTi3pI6PBN6CiczsWYOyP2zk0IJI08EWEQyDMQWW221rPaaEz6FvjLhnU07KMzLv8q3qSuoB93ua6inSQ55Tw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@2.4.10': + resolution: {integrity: sha512-tZLvEEi2u9Xu1zAqRjTcpIDGVtldigVvzug2fTuPG0ME/g8/mXpRPcNgLB22bGn6FvLJpHHnqLnwliOu8xjYrg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@2.4.10': + resolution: {integrity: sha512-umwQU6qPzH+ISTf/eHyJ/QoQnJs3V9Vpjz2OjZXe9MVBZ7prgGafMy7yYeRGnlmDAn87AKTF3Q6weLoMGpeqdQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.4.10': + resolution: {integrity: sha512-aW/JU5GuyH4uxMrNYpoC2kjaHlyJGLgIa3XkhPEZI0uKhZhJZU8BuEyJmvgzSPQNGozBwWjC972RaNdcJ9KyJg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + '@changesets/apply-release-plan@7.0.12': resolution: {integrity: sha512-EaET7As5CeuhTzvXTQCRZeBUcisoYPDDcXvgTE/2jmmypKp0RC7LxKj/yzqeh/1qFTZI7oDGFcL1PHRuQuketQ==} @@ -119,87 +164,6 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} - '@emnapi/core@1.4.5': - resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} - - '@emnapi/runtime@1.4.5': - resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} - - '@emnapi/wasi-threads@1.0.4': - resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} - - '@eslint-community/eslint-plugin-eslint-comments@4.5.0': - resolution: {integrity: sha512-MAhuTKlr4y/CE3WYX26raZjy+I/kS2PLKSzvfmDCGrBLTFHOYwqROZdr4XwPgXwX3K9rjzMr4pSmUWGnzsUyMg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.3.0': - resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.13.0': - resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.15.1': - resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.32.0': - resolution: {integrity: sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.2.8': - resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.3.4': - resolution: {integrity: sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} @@ -222,9 +186,6 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -237,227 +198,13 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@pkgr/core@0.2.9': - resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - - '@sec-ant/readable-stream@0.4.1': - resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - - '@sindresorhus/merge-streams@2.3.0': - resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} - engines: {node: '>=18'} - - '@sindresorhus/merge-streams@4.0.0': - resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} - engines: {node: '>=18'} - - '@sindresorhus/tsconfig@7.0.0': - resolution: {integrity: sha512-i5K04hLAP44Af16zmDjG07E1NHuDgCM07SJAT4gY0LZSRrWYzwt4qkLem6TIbIVh0k51RkN2bF+lP+lM5eC9fw==} - engines: {node: '>=18'} - - '@stylistic/eslint-plugin@2.13.0': - resolution: {integrity: sha512-RnO1SaiCFHn666wNz2QfZEFxvmiNRqhzaMXHXxXXKt+MEP7aajlPxUSMIQpKAaJfverpovEYqjBOXDq6dDcaOQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: '>=8.40.0' - - '@stylistic/eslint-plugin@4.4.1': - resolution: {integrity: sha512-CEigAk7eOLyHvdgmpZsKFwtiqS2wFwI1fn4j09IU9GmD4euFM4jEBAViWeCqaNLlbX2k2+A/Fq9cje4HQBXuJQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: '>=9.0.0' - - '@tybys/wasm-util@0.10.0': - resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} - - '@types/eslint@8.56.12': - resolution: {integrity: sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@typescript-eslint/eslint-plugin@8.38.0': - resolution: {integrity: sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.38.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/parser@8.38.0': - resolution: {integrity: sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/project-service@8.38.0': - resolution: {integrity: sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/scope-manager@8.38.0': - resolution: {integrity: sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.38.0': - resolution: {integrity: sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/type-utils@8.38.0': - resolution: {integrity: sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/types@8.38.0': - resolution: {integrity: sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.38.0': - resolution: {integrity: sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/utils@8.38.0': - resolution: {integrity: sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/visitor-keys@8.38.0': - resolution: {integrity: sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} - cpu: [arm] - os: [android] - - '@unrs/resolver-binding-android-arm64@1.11.1': - resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} - cpu: [arm64] - os: [android] - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} - cpu: [arm64] - os: [darwin] - - '@unrs/resolver-binding-darwin-x64@1.11.1': - resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} - cpu: [x64] - os: [darwin] - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} - cpu: [x64] - os: [freebsd] - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} - cpu: [ppc64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} - cpu: [s390x] - os: [linux] - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} - cpu: [arm64] - os: [win32] - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} - cpu: [ia32] - os: [win32] - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} - cpu: [x64] - os: [win32] - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} - ansi-escapes@6.2.1: - resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} - engines: {node: '>=14.16'} - ansi-escapes@7.0.0: resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} engines: {node: '>=18'} @@ -484,110 +231,22 @@ packages: argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} - - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} - array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} - - array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} - - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} - - arrify@3.0.0: - resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} - engines: {node: '>=12'} - - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} - auto-bind@5.0.1: resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.25.1: - resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - builtin-modules@5.0.0: - resolution: {integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==} - engines: {node: '>=18.20'} - - bundle-name@4.1.0: - resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} - engines: {node: '>=18'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - caniuse-lite@1.0.30001731: - resolution: {integrity: sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - chalk@5.4.1: resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} @@ -603,14 +262,6 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - ci-info@4.3.0: - resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==} - engines: {node: '>=8'} - - clean-regexp@1.0.0: - resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} - engines: {node: '>=4'} - cli-boxes@3.0.0: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} @@ -638,83 +289,14 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - comment-parser@1.4.1: - resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} - engines: {node: '>= 12.0.0'} - - common-path-prefix@3.0.0: - resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - confusing-browser-globals@1.0.11: - resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} - convert-to-spaces@2.0.1: resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - core-js-compat@3.44.0: - resolution: {integrity: sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==} - - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true - cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} - - data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} - - data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} - - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - default-browser-id@5.0.0: - resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} - engines: {node: '>=18'} - - default-browser@5.2.1: - resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} - engines: {node: '>=18'} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} - engines: {node: '>=12'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -723,20 +305,9 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.5.194: - resolution: {integrity: sha512-SdnWJwSUot04UR51I2oPD8kuP2VI37/CADR1OHsFOUzZIvfWJBO6q11k5P/uKNyTT3cdOsnyjkrZ+DDShqYqJA==} - emoji-regex@10.4.0: resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} @@ -746,342 +317,51 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - enhance-visitors@1.0.0: - resolution: {integrity: sha512-+29eJLiUixTEDRaZ35Vu8jP3gPLNcQQkQkOQjLp2X+6cZGGPDD/uasbFzvLsJKnGZnvmyZ0srxudwOtskHeIDA==} - engines: {node: '>=4.0.0'} - - enhanced-resolve@5.18.2: - resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} - engines: {node: '>=10.13.0'} - enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} - env-editor@1.1.0: - resolution: {integrity: sha512-7AXskzN6T7Q9TFcKAGJprUbpQa4i1VsAetO9rdBqbGMGlragTziBgWt4pVYJMBWHQlLoX0buy6WFikzPH4Qjpw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - - es-abstract@1.24.0: - resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} - engines: {node: '>= 0.4'} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} - es-toolkit@1.39.8: resolution: {integrity: sha512-A8QO9TfF+rltS8BXpdu8OS+rpGgEdnRhqIVxO/ZmNvnXBYgOdSsxukT55ELyP94gZIntWJ+Li9QRrT2u1Kitpg==} - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-compat-utils@0.5.1: - resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} - engines: {node: '>=12'} - peerDependencies: - eslint: '>=6.0.0' - - eslint-config-prettier@10.1.8: - resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} hasBin: true - peerDependencies: - eslint: '>=7.0.0' - eslint-config-xo-react@0.28.0: - resolution: {integrity: sha512-dKvxB9kxMNLhWKsh6yiptACet+/WwKcN7ID2hIBAmjH6le4tt8um4sJ0/aAH6y+xle9tPrasX1Wnz90muCoz9A==} - engines: {node: '>=18.18'} - peerDependencies: - eslint: '>=9.18.0' + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} - eslint-config-xo-typescript@7.0.0: - resolution: {integrity: sha512-Mvy5eo6PW2BWPpxLsG7Y28LciZhLhiXFZAw/H3kdia34Efudk2aWMWwAKqkEFamo/SHiyMYkqUx6DYO+YJeVVg==} - engines: {node: '>=18.18'} - peerDependencies: - eslint: '>=9.8.0' - typescript: '>=5.5.0' + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} - eslint-config-xo@0.46.0: - resolution: {integrity: sha512-mjQUhdTCLQwHUFKf1hhSx1FFhm2jllr4uG2KjaW7gZHGAbjKoSypvo1eQvFk17lHx3bztYjZDDXQmkAZyaSlAg==} - engines: {node: '>=18.18'} - peerDependencies: - eslint: '>=9.8.0' + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} - eslint-formatter-pretty@6.0.1: - resolution: {integrity: sha512-znAUcXmBthdIUmlnRkPSxz3zSJHFUhfHF/nJPcCMVKg/mOa4yUie2Olqg1Ghbi5JJRBZVU3rIgzWSObvIspxMA==} - engines: {node: '>=18'} + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - eslint-import-context@0.1.9: - resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - peerDependencies: - unrs-resolver: ^1.0.0 - peerDependenciesMeta: - unrs-resolver: - optional: true + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} - eslint-plugin-ava@15.1.0: - resolution: {integrity: sha512-+6Zxk1uYW3mf7lxCLWIQsFYgn3hfuCMbsKc0MtqfloOz1F6fiV5/PaWEaLgkL1egrSQmnyR7vOFP1wSPJbVUbw==} - engines: {node: ^18.18 || >=20} - peerDependencies: - eslint: '>=9' + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} - eslint-plugin-es-x@7.8.0: - resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '>=8' - - eslint-plugin-import-x@4.16.1: - resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/utils': ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 - eslint-import-resolver-node: '*' - peerDependenciesMeta: - '@typescript-eslint/utils': - optional: true - eslint-import-resolver-node: - optional: true - - eslint-plugin-n@17.21.3: - resolution: {integrity: sha512-MtxYjDZhMQgsWRm/4xYLL0i2EhusWT7itDxlJ80l1NND2AL2Vi5Mvneqv/ikG9+zpran0VsVRXTEHrpLmUZRNw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: '>=8.23.0' - - eslint-plugin-no-use-extend-native@0.7.2: - resolution: {integrity: sha512-hUBlwaTXIO1GzTwPT6pAjvYwmSHe4XduDhAiQvur4RUujmBUFjd8Nb2+e7WQdsQ+nGHWGRlogcUWXJRGqizTWw==} - engines: {node: '>=18.18.0'} - peerDependencies: - eslint: ^9.3.0 - - eslint-plugin-prettier@5.5.3: - resolution: {integrity: sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-plugin-promise@7.2.1: - resolution: {integrity: sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - - eslint-plugin-react-hooks@5.2.0: - resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - - eslint-plugin-react@7.37.5: - resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - - eslint-plugin-unicorn@59.0.1: - resolution: {integrity: sha512-EtNXYuWPUmkgSU2E7Ttn57LbRREQesIP1BiLn7OZLKodopKfDXfBUkC/0j6mpw2JExwf43Uf3qLSvrSvppgy8Q==} - engines: {node: ^18.20.0 || ^20.10.0 || >=21.0.0} - peerDependencies: - eslint: '>=9.22.0' - - eslint-rule-docs@1.1.235: - resolution: {integrity: sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==} - - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-utils@3.0.0: - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} - peerDependencies: - eslint: '>=5' - - eslint-visitor-keys@2.1.0: - resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} - engines: {node: '>=10'} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@9.32.0: - resolution: {integrity: sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - espurify@2.1.1: - resolution: {integrity: sha512-zttWvnkhcDyGOhSH4vO2qCBILpdCMv/MX8lp4cqgRkQoDRGK2oZxi2GfWhlP2dIXmk7BaKeOTuzbHhyC68o8XQ==} - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - execa@9.6.0: - resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} - engines: {node: ^18.19.0 || >=20.5.0} - - extendable-error@0.1.7: - resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} - - external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - - figures@6.1.0: - resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} - engines: {node: '>=18'} - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-cache-directory@6.0.0: - resolution: {integrity: sha512-CvFd5ivA6HcSHbD+59P7CyzINHXzwhuQK8RY7CxJZtgDSAtRlHiCaQpZQ2lMR/WRyUIEmzUvL6G2AGurMfegZA==} - engines: {node: '>=20'} - - find-up-simple@1.0.1: - resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} - engines: {node: '>=18'} - - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} - - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} @@ -1091,124 +371,26 @@ packages: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} - - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - get-east-asian-width@1.3.0: resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} engines: {node: '>=18'} - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-set-props@0.2.0: - resolution: {integrity: sha512-YCmOj+4YAeEB5Dd9jfp6ETdejMet4zSxXjNkgaa4npBEKRI9uDOGB5MmAdAgi2OoFGAKshYhCbmLq2DS03CgVA==} - engines: {node: '>=18.0.0'} - - get-stdin@9.0.0: - resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} - engines: {node: '>=12'} - - get-stream@9.0.1: - resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} - engines: {node: '>=18'} - - get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} - - get-tsconfig@4.10.1: - resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - glob@11.0.3: resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} engines: {node: 20 || >=22} hasBin: true - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - globals@15.15.0: - resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} - engines: {node: '>=18'} - - globals@16.3.0: - resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} - engines: {node: '>=18'} - - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - globby@14.1.0: - resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} - engines: {node: '>=18'} - - globrex@0.1.2: - resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - hosted-git-info@9.0.0: resolution: {integrity: sha512-gEf705MZLrDPkbbhi8PnoO4ZwYgKoNL+ISZ3AjZMht2r3N5tuTwncyDi6Fv2/qDnMmZxgs0yI8WDOyR8q3G+SQ==} engines: {node: ^20.17.0 || >=22.9.0} @@ -1217,10 +399,6 @@ packages: resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} hasBin: true - human-signals@8.0.1: - resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} - engines: {node: '>=18.18.0'} - iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -1229,22 +407,6 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - import-modules@2.1.0: - resolution: {integrity: sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==} - engines: {node: '>=8'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - indent-string@5.0.0: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} @@ -1269,66 +431,10 @@ packages: react-devtools-core: optional: true - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} - - irregular-plurals@3.5.0: - resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==} - engines: {node: '>=8'} - - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} - - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - - is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} - - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} - - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} - - is-builtin-module@5.0.0: - resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==} - engines: {node: '>=18.20'} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - - is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} - - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} - - is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} - is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -1341,14 +447,6 @@ packages: resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} engines: {node: '>=18'} - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} - engines: {node: '>= 0.4'} - - is-get-set-prop@2.0.0: - resolution: {integrity: sha512-C32bqXfHJfRwa0U5UIMqSGziZhALszXDJZ8n8mz8WZ6c6V7oYGHEWwJvftliBswypY3P3EQqdY5lpDSEKvTS1Q==} - engines: {node: '> 18.0.0'} - is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -1358,113 +456,21 @@ packages: engines: {node: '>=18'} hasBin: true - is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true - - is-js-type@3.0.0: - resolution: {integrity: sha512-IbPf3g3vxm1D902xaBaYp2TUHiXZWwWRu5bM9hgKN9oAQcFaKALV6Gd13PGhXjKE5u2n8s1PhLhdke/E1fchxQ==} - engines: {node: '>=18.0.0'} - - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - - is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} - - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-obj-prop@2.0.0: - resolution: {integrity: sha512-2/VFrbzXSZVJIscazpxoB+pOQx2jBOAAL9Gui4cRKxflznUNBpsr8IDvBA4UGol3e40sltLNiY3qnZv/7qSUxA==} - engines: {node: '>=18.0.0'} - - is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - - is-proto-prop@3.0.1: - resolution: {integrity: sha512-S8xSxNMGJO4eZD86kO46zrq2gLIhA+rN9443lQEvt8Mz/l8cxk72p/AWFmofY6uL9g9ILD6cXW6j8QQj4F3Hcw==} - engines: {node: '>=18.0.0'} - - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} - - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} - - is-stream@4.0.1: - resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} - engines: {node: '>=18'} - - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} - is-subdir@1.2.0: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - - is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - - is-unicode-supported@2.1.0: - resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} - engines: {node: '>=18'} - - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - - is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} - - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} - is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} - is-wsl@3.1.0: - resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} - engines: {node: '>=16'} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - iterator.prototype@1.1.5: - resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} - engines: {node: '>= 0.4'} - jackspeak@4.1.1: resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} engines: {node: 20 || >=22} @@ -1472,109 +478,32 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-types@4.0.0: - resolution: {integrity: sha512-/c+n06zvqFQGxdz1BbElF7S3nEghjNchLN1TjQnk2j10HYDaUc57rcvl6BbnziTx8NQmrg0JOs/iwRpvcYaxjQ==} - engines: {node: '>=18.20'} - js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - jsesc@3.0.2: - resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} - engines: {node: '>=6'} - hasBin: true - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - line-column-path@3.0.0: - resolution: {integrity: sha512-Atocnm7Wr9nuvAn97yEPQa3pcQI5eLQGBz+m6iTb+CVw+IOzYB9MrYK7jI7BfC9ISnT4Fu0eiwhAScV//rp4Hw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - log-symbols@6.0.0: - resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} - engines: {node: '>=18'} - loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - lowercase-keys@3.0.0: - resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lru-cache@11.1.0: resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} engines: {node: 20 || >=22} - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - meow@13.2.0: - resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} - engines: {node: '>=18'} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micro-spelling-correcter@1.1.1: - resolution: {integrity: sha512-lkJ3Rj/mtjlRcHk6YyCbvZhyWTOzdBvTHsxMmZSk5jxN1YyVSQ+JETAom55mdzfcyDrY/49Z7UCW760BK30crg==} - micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -1583,21 +512,10 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - min-indent@1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} - minimatch@10.0.3: resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} engines: {node: 20 || >=22} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - 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'} @@ -1615,72 +533,10 @@ packages: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - napi-postinstall@0.3.2: - resolution: {integrity: sha512-tWVJxJHmBWLy69PvO96TZMZDrzmw5KeiZBz3RHmiM2XZ9grBJ2WgMAFVVg25nqp3ZjTFUs2Ftw1JhscL3Teliw==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - - npm-run-path@6.0.0: - resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} - engines: {node: '>=18'} - - obj-props@2.0.0: - resolution: {integrity: sha512-Q/uLAAfjdhrzQWN2czRNh3fDCgXjh7yRIkdHjDgIHTwpFP0BsshxTA3HRNffHR7Iw/XGTH30u8vdMXQ+079urA==} - engines: {node: '>=18.0.0'} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - open-editor@5.1.0: - resolution: {integrity: sha512-KkNqM6FdoegD6WhY2YXmWcovOux45NV+zBped2+G3+V74zkDPkIl4cqh6hte2zNDojtwO2nBOV8U+sgziWfPrg==} - engines: {node: '>=18'} - - open@10.2.0: - resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} - engines: {node: '>=18'} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -1688,10 +544,6 @@ packages: outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} - p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} engines: {node: '>=8'} @@ -1700,18 +552,10 @@ packages: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - p-map@2.1.0: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} engines: {node: '>=6'} @@ -1726,41 +570,18 @@ packages: package-manager-detector@0.2.11: resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - - parse-ms@4.0.0: - resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} - engines: {node: '>=18'} - - patch-console@2.0.0: - resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + patch-console@2.0.0: + resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@2.0.0: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} @@ -1769,10 +590,6 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - path-type@6.0.0: - resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} - engines: {node: '>=18'} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1780,76 +597,21 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - pkg-dir@5.0.0: - resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} - engines: {node: '>=10'} - - pkg-dir@8.0.0: - resolution: {integrity: sha512-4peoBq4Wks0riS0z8741NVv+/8IiTvqnZAr8QGgtdifrtpdXbNw/FxRS1l6NFqm4EMzuS0EDqNNx4XGaz8cuyQ==} - engines: {node: '>=18'} - - plur@5.1.0: - resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} hasBin: true - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} - engines: {node: '>=14'} - hasBin: true - - pretty-ms@9.2.0: - resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} - engines: {node: '>=18'} - - prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - - prototype-properties@5.0.0: - resolution: {integrity: sha512-uCWE2QqnGlwvvJXTwiHTPTyHE62+zORO5hpFWhAwBGDtEtTmNZZleNLJDoFsqHCL4p/CeAP2Q1uMKFUKALuRGQ==} - engines: {node: '>=18.20'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - quansync@0.2.10: resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-reconciler@0.32.0: resolution: {integrity: sha512-2NPMOzgTlG0ZWdIf3qG+dcbLSoAc/uLfOwckc3ofy5sSK0pLJqnQLpUFxvGcN2rlXSjnVtGeeFLNimCQEj5gOQ==} engines: {node: '>=0.10.0'} @@ -1864,37 +626,10 @@ packages: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} - - regexp-tree@0.1.27: - resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} - hasBin: true - - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} - - regjsparser@0.12.0: - resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} - hasBin: true - - 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'} - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} - hasBin: true - restore-cursor@4.0.0: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1903,25 +638,9 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - run-applescript@7.0.0: - resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} - engines: {node: '>=18'} - run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - safe-array-concat@1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} - - safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} - - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} - safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -1931,27 +650,11 @@ packages: scheduler@0.26.0: resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - semver@7.7.2: resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} hasBin: true - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1960,22 +663,6 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -1987,10 +674,6 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slash@5.1.0: - resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} - engines: {node: '>=14.16'} - slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} @@ -2005,18 +688,10 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - stable-hash-x@0.2.0: - resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} - engines: {node: '>=12.0.0'} - stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} - stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2029,25 +704,6 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} - string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} - - string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} - - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} - - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} - - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} - strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -2060,38 +716,6 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} - strip-final-newline@4.0.0: - resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} - engines: {node: '>=18'} - - strip-indent@4.0.0: - resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} - engines: {node: '>=12'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-hyperlinks@3.2.0: - resolution: {integrity: sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==} - engines: {node: '>=14.18'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - synckit@0.11.11: - resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} - engines: {node: ^14.18.0 || >=16.0.0} - - tapable@2.2.2: - resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} - engines: {node: '>=6'} - tar@7.4.3: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} @@ -2108,104 +732,18 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - ts-declaration-location@1.0.7: - resolution: {integrity: sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==} - peerDependencies: - typescript: '>=4.0.0' - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - type-fest@4.41.0: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - - typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} - - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} - - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} - - typescript-eslint@8.38.0: - resolution: {integrity: sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} - engines: {node: '>=14.17'} - hasBin: true - - unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} - undici@7.13.0: resolution: {integrity: sha512-l+zSMssRqrzDcb3fjMkjjLGmuiiK2pMIcV++mJaAc9vhjSGpvM7h43QgP+OAMb1GImHmbPyG2tBXeuyG5iY4gA==} engines: {node: '>=20.18.1'} - unicorn-magic@0.3.0: - resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} - engines: {node: '>=18'} - universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} - - which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} - - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} - engines: {node: '>= 0.4'} - which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -2215,10 +753,6 @@ packages: resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} engines: {node: '>=18'} - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -2243,32 +777,10 @@ packages: utf-8-validate: optional: true - wsl-utils@0.1.0: - resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} - engines: {node: '>=18'} - - xo@1.2.1: - resolution: {integrity: sha512-CPv9yCCa8WkS8JMME5igrBQhqwOlQ+YFFsF2JP0vjQjuGdme5PLYgnDu8LnawMahtDq2PzpOWbMu2EEIxrOfBA==} - engines: {node: '>=20.17'} - hasBin: true - peerDependencies: - webpack: '>=1.11.0' - peerDependenciesMeta: - webpack: - optional: true - yallist@5.0.0: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - yoctocolors@2.1.1: - resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} - engines: {node: '>=18'} - yoga-layout@3.2.1: resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} @@ -2279,15 +791,42 @@ snapshots: ansi-styles: 6.2.1 is-fullwidth-code-point: 4.0.0 - '@babel/code-frame@7.27.1': - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 + '@babel/runtime@7.28.2': {} - '@babel/helper-validator-identifier@7.27.1': {} + '@biomejs/biome@2.4.10': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.4.10 + '@biomejs/cli-darwin-x64': 2.4.10 + '@biomejs/cli-linux-arm64': 2.4.10 + '@biomejs/cli-linux-arm64-musl': 2.4.10 + '@biomejs/cli-linux-x64': 2.4.10 + '@biomejs/cli-linux-x64-musl': 2.4.10 + '@biomejs/cli-win32-arm64': 2.4.10 + '@biomejs/cli-win32-x64': 2.4.10 + + '@biomejs/cli-darwin-arm64@2.4.10': + optional: true - '@babel/runtime@7.28.2': {} + '@biomejs/cli-darwin-x64@2.4.10': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.4.10': + optional: true + + '@biomejs/cli-linux-arm64@2.4.10': + optional: true + + '@biomejs/cli-linux-x64-musl@2.4.10': + optional: true + + '@biomejs/cli-linux-x64@2.4.10': + optional: true + + '@biomejs/cli-win32-arm64@2.4.10': + optional: true + + '@biomejs/cli-win32-x64@2.4.10': + optional: true '@changesets/apply-release-plan@7.0.12': dependencies: @@ -2431,94 +970,6 @@ snapshots: human-id: 4.1.1 prettier: 2.8.8 - '@emnapi/core@1.4.5': - dependencies: - '@emnapi/wasi-threads': 1.0.4 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.4.5': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.0.4': - dependencies: - tslib: 2.8.1 - optional: true - - '@eslint-community/eslint-plugin-eslint-comments@4.5.0(eslint@9.32.0)': - dependencies: - escape-string-regexp: 4.0.0 - eslint: 9.32.0 - ignore: 5.3.2 - - '@eslint-community/eslint-utils@4.7.0(eslint@9.32.0)': - dependencies: - eslint: 9.32.0 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} - - '@eslint/config-array@0.21.0': - dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.1 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.3.0': {} - - '@eslint/core@0.13.0': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/core@0.15.1': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.1': - dependencies: - ajv: 6.12.6 - debug: 4.4.1 - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.32.0': {} - - '@eslint/object-schema@2.1.6': {} - - '@eslint/plugin-kit@0.2.8': - dependencies: - '@eslint/core': 0.13.0 - levn: 0.4.1 - - '@eslint/plugin-kit@0.3.4': - dependencies: - '@eslint/core': 0.15.1 - levn: 0.4.1 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.6': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.3.1': {} - - '@humanwhocodes/retry@0.4.3': {} - '@isaacs/balanced-match@4.0.1': {} '@isaacs/brace-expansion@5.0.0': @@ -2554,13 +1005,6 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 - '@napi-rs/wasm-runtime@0.2.12': - dependencies: - '@emnapi/core': 1.4.5 - '@emnapi/runtime': 1.4.5 - '@tybys/wasm-util': 0.10.0 - optional: true - '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -2573,921 +1017,108 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@pkgr/core@0.2.9': {} + '@types/node@12.20.55': {} - '@sec-ant/readable-stream@0.4.1': {} + ansi-colors@4.1.3: {} - '@sindresorhus/merge-streams@2.3.0': {} + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 - '@sindresorhus/merge-streams@4.0.0': {} + ansi-regex@5.0.1: {} - '@sindresorhus/tsconfig@7.0.0': {} + ansi-regex@6.1.0: {} - '@stylistic/eslint-plugin@2.13.0(eslint@9.32.0)(typescript@5.8.3)': + ansi-styles@4.3.0: dependencies: - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - eslint: 9.32.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - estraverse: 5.3.0 - picomatch: 4.0.3 - transitivePeerDependencies: - - supports-color - - typescript + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + archy@1.0.0: {} - '@stylistic/eslint-plugin@4.4.1(eslint@9.32.0)(typescript@5.8.3)': + argparse@1.0.10: dependencies: - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - eslint: 9.32.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - estraverse: 5.3.0 - picomatch: 4.0.3 - transitivePeerDependencies: - - supports-color - - typescript + sprintf-js: 1.0.3 + + array-union@2.1.0: {} + + auto-bind@5.0.1: {} - '@tybys/wasm-util@0.10.0': + better-path-resolve@1.0.0: dependencies: - tslib: 2.8.1 - optional: true + is-windows: 1.0.2 - '@types/eslint@8.56.12': + braces@3.0.3: dependencies: - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 + fill-range: 7.1.1 - '@types/estree@1.0.8': {} + chalk@5.4.1: {} - '@types/json-schema@7.0.15': {} + chardet@0.7.0: {} - '@types/node@12.20.55': {} + chownr@3.0.0: {} - '@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(typescript@5.8.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/type-utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.38.0 - eslint: 9.32.0 - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color + ci-info@3.9.0: {} - '@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.38.0 - debug: 4.4.1 - eslint: 9.32.0 - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color + cli-boxes@3.0.0: {} - '@typescript-eslint/project-service@8.38.0(typescript@5.8.3)': + cli-cursor@4.0.0: dependencies: - '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3) - '@typescript-eslint/types': 8.38.0 - debug: 4.4.1 - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color + restore-cursor: 4.0.0 + + cli-spinners@2.9.2: {} - '@typescript-eslint/scope-manager@8.38.0': + cli-truncate@4.0.0: dependencies: - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/visitor-keys': 8.38.0 + slice-ansi: 5.0.0 + string-width: 7.2.0 - '@typescript-eslint/tsconfig-utils@8.38.0(typescript@5.8.3)': + code-excerpt@4.0.0: dependencies: - typescript: 5.8.3 + convert-to-spaces: 2.0.1 - '@typescript-eslint/type-utils@8.38.0(eslint@9.32.0)(typescript@5.8.3)': + color-convert@2.0.1: dependencies: - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - debug: 4.4.1 - eslint: 9.32.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color + color-name: 1.1.4 - '@typescript-eslint/types@8.38.0': {} + color-name@1.1.4: {} - '@typescript-eslint/typescript-estree@8.38.0(typescript@5.8.3)': - dependencies: - '@typescript-eslint/project-service': 8.38.0(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3) - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/visitor-keys': 8.38.0 - debug: 4.4.1 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color + convert-to-spaces@2.0.1: {} - '@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3)': + cross-spawn@7.0.6: dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - eslint: 9.32.0 - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + detect-indent@6.1.0: {} - '@typescript-eslint/visitor-keys@8.38.0': + dir-glob@3.0.1: dependencies: - '@typescript-eslint/types': 8.38.0 - eslint-visitor-keys: 4.2.1 + path-type: 4.0.0 - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - optional: true + eastasianwidth@0.2.0: {} - '@unrs/resolver-binding-android-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - dependencies: - '@napi-rs/wasm-runtime': 0.2.12 - optional: true - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - optional: true - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-colors@4.1.3: {} - - ansi-escapes@6.2.1: {} - - ansi-escapes@7.0.0: - dependencies: - environment: 1.1.0 - - ansi-regex@5.0.1: {} - - ansi-regex@6.1.0: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - archy@1.0.0: {} - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - - array-buffer-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - is-array-buffer: 3.0.5 - - array-includes@3.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - is-string: 1.1.1 - math-intrinsics: 1.1.0 - - array-union@2.1.0: {} - - array.prototype.findlast@1.2.5: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.flat@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.flatmap@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.tosorted@1.1.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-shim-unscopables: 1.1.0 - - arraybuffer.prototype.slice@1.0.4: - dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - is-array-buffer: 3.0.5 - - arrify@3.0.0: {} - - async-function@1.0.0: {} - - auto-bind@5.0.1: {} - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.1.0 - - balanced-match@1.0.2: {} - - better-path-resolve@1.0.0: - dependencies: - is-windows: 1.0.2 - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browserslist@4.25.1: - dependencies: - caniuse-lite: 1.0.30001731 - electron-to-chromium: 1.5.194 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.1) - - builtin-modules@5.0.0: {} - - bundle-name@4.1.0: - dependencies: - run-applescript: 7.0.0 - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.8: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - callsites@3.1.0: {} - - caniuse-lite@1.0.30001731: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chalk@5.4.1: {} - - chardet@0.7.0: {} - - chownr@3.0.0: {} - - ci-info@3.9.0: {} - - ci-info@4.3.0: {} - - clean-regexp@1.0.0: - dependencies: - escape-string-regexp: 1.0.5 - - cli-boxes@3.0.0: {} - - cli-cursor@4.0.0: - dependencies: - restore-cursor: 4.0.0 - - cli-spinners@2.9.2: {} - - cli-truncate@4.0.0: - dependencies: - slice-ansi: 5.0.0 - string-width: 7.2.0 - - code-excerpt@4.0.0: - dependencies: - convert-to-spaces: 2.0.1 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - comment-parser@1.4.1: {} - - common-path-prefix@3.0.0: {} - - concat-map@0.0.1: {} - - confusing-browser-globals@1.0.11: {} - - convert-to-spaces@2.0.1: {} - - core-js-compat@3.44.0: - dependencies: - browserslist: 4.25.1 - - cosmiconfig@9.0.0(typescript@5.8.3): - dependencies: - env-paths: 2.2.1 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - parse-json: 5.2.0 - optionalDependencies: - typescript: 5.8.3 - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - data-view-buffer@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-offset@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - debug@4.4.1: - dependencies: - ms: 2.1.3 - - deep-is@0.1.4: {} - - default-browser-id@5.0.0: {} - - default-browser@5.2.1: - dependencies: - bundle-name: 4.1.0 - default-browser-id: 5.0.0 - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - define-lazy-prop@3.0.0: {} - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - - detect-indent@6.1.0: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - eastasianwidth@0.2.0: {} - - electron-to-chromium@1.5.194: {} - - emoji-regex@10.4.0: {} + emoji-regex@10.4.0: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} - enhance-visitors@1.0.0: - dependencies: - lodash: 4.17.21 - - enhanced-resolve@5.18.2: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.2.2 - enquirer@2.4.1: dependencies: ansi-colors: 4.1.3 strip-ansi: 6.0.1 - env-editor@1.1.0: {} - - env-paths@2.2.1: {} - environment@1.1.0: {} - error-ex@1.3.2: - dependencies: - is-arrayish: 0.2.1 - - es-abstract@1.24.0: - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-negative-zero: 2.0.3 - is-regex: 1.2.1 - is-set: 2.0.3 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 - math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.3 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.19 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-iterator-helpers@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-set-tostringtag: 2.1.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - iterator.prototype: 1.1.5 - safe-array-concat: 1.1.3 - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.2 - - es-to-primitive@1.3.0: - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - es-toolkit@1.39.8: {} - escalade@3.2.0: {} - - escape-string-regexp@1.0.5: {} - escape-string-regexp@2.0.0: {} - escape-string-regexp@4.0.0: {} - - eslint-compat-utils@0.5.1(eslint@9.32.0): - dependencies: - eslint: 9.32.0 - semver: 7.7.2 - - eslint-config-prettier@10.1.8(eslint@9.32.0): - dependencies: - eslint: 9.32.0 - - eslint-config-xo-react@0.28.0(eslint@9.32.0): - dependencies: - eslint: 9.32.0 - eslint-plugin-react: 7.37.5(eslint@9.32.0) - eslint-plugin-react-hooks: 5.2.0(eslint@9.32.0) - - eslint-config-xo-typescript@7.0.0(eslint@9.32.0)(typescript@5.8.3): - dependencies: - '@stylistic/eslint-plugin': 2.13.0(eslint@9.32.0)(typescript@5.8.3) - eslint: 9.32.0 - eslint-config-xo: 0.46.0(eslint@9.32.0)(typescript@5.8.3) - typescript: 5.8.3 - typescript-eslint: 8.38.0(eslint@9.32.0)(typescript@5.8.3) - transitivePeerDependencies: - - supports-color - - eslint-config-xo@0.46.0(eslint@9.32.0)(typescript@5.8.3): - dependencies: - '@stylistic/eslint-plugin': 2.13.0(eslint@9.32.0)(typescript@5.8.3) - confusing-browser-globals: 1.0.11 - eslint: 9.32.0 - globals: 15.15.0 - transitivePeerDependencies: - - supports-color - - typescript - - eslint-formatter-pretty@6.0.1: - dependencies: - '@types/eslint': 8.56.12 - ansi-escapes: 6.2.1 - chalk: 5.4.1 - eslint-rule-docs: 1.1.235 - log-symbols: 6.0.0 - plur: 5.1.0 - string-width: 7.2.0 - supports-hyperlinks: 3.2.0 - - eslint-import-context@0.1.9(unrs-resolver@1.11.1): - dependencies: - get-tsconfig: 4.10.1 - stable-hash-x: 0.2.0 - optionalDependencies: - unrs-resolver: 1.11.1 - - eslint-plugin-ava@15.1.0(eslint@9.32.0): - dependencies: - enhance-visitors: 1.0.0 - eslint: 9.32.0 - eslint-utils: 3.0.0(eslint@9.32.0) - espree: 9.6.1 - espurify: 2.1.1 - import-modules: 2.1.0 - micro-spelling-correcter: 1.1.1 - pkg-dir: 5.0.0 - resolve-from: 5.0.0 - - eslint-plugin-es-x@7.8.0(eslint@9.32.0): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - '@eslint-community/regexpp': 4.12.1 - eslint: 9.32.0 - eslint-compat-utils: 0.5.1(eslint@9.32.0) - - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0): - dependencies: - '@typescript-eslint/types': 8.38.0 - comment-parser: 1.4.1 - debug: 4.4.1 - eslint: 9.32.0 - eslint-import-context: 0.1.9(unrs-resolver@1.11.1) - is-glob: 4.0.3 - minimatch: 10.0.3 - semver: 7.7.2 - stable-hash-x: 0.2.0 - unrs-resolver: 1.11.1 - optionalDependencies: - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - transitivePeerDependencies: - - supports-color - - eslint-plugin-n@17.21.3(eslint@9.32.0)(typescript@5.8.3): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - enhanced-resolve: 5.18.2 - eslint: 9.32.0 - eslint-plugin-es-x: 7.8.0(eslint@9.32.0) - get-tsconfig: 4.10.1 - globals: 15.15.0 - globrex: 0.1.2 - ignore: 5.3.2 - semver: 7.7.2 - ts-declaration-location: 1.0.7(typescript@5.8.3) - transitivePeerDependencies: - - typescript - - eslint-plugin-no-use-extend-native@0.7.2(eslint@9.32.0): - dependencies: - eslint: 9.32.0 - is-get-set-prop: 2.0.0 - is-js-type: 3.0.0 - is-obj-prop: 2.0.0 - is-proto-prop: 3.0.1 - - eslint-plugin-prettier@5.5.3(@types/eslint@8.56.12)(eslint-config-prettier@10.1.8(eslint@9.32.0))(eslint@9.32.0)(prettier@3.6.2): - dependencies: - eslint: 9.32.0 - prettier: 3.6.2 - prettier-linter-helpers: 1.0.0 - synckit: 0.11.11 - optionalDependencies: - '@types/eslint': 8.56.12 - eslint-config-prettier: 10.1.8(eslint@9.32.0) - - eslint-plugin-promise@7.2.1(eslint@9.32.0): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - eslint: 9.32.0 - - eslint-plugin-react-hooks@5.2.0(eslint@9.32.0): - dependencies: - eslint: 9.32.0 - - eslint-plugin-react@7.37.5(eslint@9.32.0): - dependencies: - array-includes: 3.1.9 - array.prototype.findlast: 1.2.5 - array.prototype.flatmap: 1.3.3 - array.prototype.tosorted: 1.1.4 - doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 - eslint: 9.32.0 - estraverse: 5.3.0 - hasown: 2.0.2 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.9 - object.fromentries: 2.0.8 - object.values: 1.2.1 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 - string.prototype.matchall: 4.0.12 - string.prototype.repeat: 1.0.0 - - eslint-plugin-unicorn@59.0.1(eslint@9.32.0): - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - '@eslint/plugin-kit': 0.2.8 - ci-info: 4.3.0 - clean-regexp: 1.0.0 - core-js-compat: 3.44.0 - eslint: 9.32.0 - esquery: 1.6.0 - find-up-simple: 1.0.1 - globals: 16.3.0 - indent-string: 5.0.0 - is-builtin-module: 5.0.0 - jsesc: 3.1.0 - pluralize: 8.0.0 - regexp-tree: 0.1.27 - regjsparser: 0.12.0 - semver: 7.7.2 - strip-indent: 4.0.0 - - eslint-rule-docs@1.1.235: {} - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-utils@3.0.0(eslint@9.32.0): - dependencies: - eslint: 9.32.0 - eslint-visitor-keys: 2.1.0 - - eslint-visitor-keys@2.1.0: {} - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@9.32.0: - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.0 - '@eslint/core': 0.15.1 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.32.0 - '@eslint/plugin-kit': 0.3.4 - '@humanfs/node': 0.16.6 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.1 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - transitivePeerDependencies: - - supports-color - - espree@10.4.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 4.2.1 - - espree@9.6.1: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 3.4.3 - esprima@4.0.1: {} - espurify@2.1.1: {} - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - esutils@2.0.3: {} - - execa@9.6.0: - dependencies: - '@sindresorhus/merge-streams': 4.0.0 - cross-spawn: 7.0.6 - figures: 6.1.0 - get-stream: 9.0.1 - human-signals: 8.0.1 - is-plain-obj: 4.1.0 - is-stream: 4.0.1 - npm-run-path: 6.0.0 - pretty-ms: 9.2.0 - signal-exit: 4.1.0 - strip-final-newline: 4.0.0 - yoctocolors: 2.1.1 - extendable-error@0.1.7: {} external-editor@3.1.0: @@ -3496,10 +1127,6 @@ snapshots: iconv-lite: 0.4.24 tmp: 0.0.33 - fast-deep-equal@3.1.3: {} - - fast-diff@1.3.0: {} - fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3508,54 +1135,19 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - fastq@1.19.1: dependencies: reusify: 1.1.0 - figures@6.1.0: - dependencies: - is-unicode-supported: 2.1.0 - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - find-cache-directory@6.0.0: - dependencies: - common-path-prefix: 3.0.0 - pkg-dir: 8.0.0 - - find-up-simple@1.0.1: {} - find-up@4.1.0: dependencies: locate-path: 5.0.0 path-exists: 4.0.0 - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - - flatted@3.3.3: {} - - for-each@0.3.5: - dependencies: - is-callable: 1.2.7 - foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -3573,66 +1165,12 @@ snapshots: jsonfile: 4.0.0 universalify: 0.1.2 - function-bind@1.1.2: {} - - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.2 - is-callable: 1.2.7 - - functions-have-names@1.2.3: {} - get-east-asian-width@1.3.0: {} - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-set-props@0.2.0: {} - - get-stdin@9.0.0: {} - - get-stream@9.0.1: - dependencies: - '@sec-ant/readable-stream': 0.4.1 - is-stream: 4.0.1 - - get-symbol-description@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - - get-tsconfig@4.10.1: - dependencies: - resolve-pkg-maps: 1.0.0 - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - glob@11.0.3: dependencies: foreground-child: 3.3.1 @@ -3642,17 +1180,6 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 2.0.0 - globals@14.0.0: {} - - globals@15.15.0: {} - - globals@16.3.0: {} - - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 - globby@11.1.0: dependencies: array-union: 2.1.0 @@ -3662,70 +1189,20 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 - globby@14.1.0: - dependencies: - '@sindresorhus/merge-streams': 2.3.0 - fast-glob: 3.3.3 - ignore: 7.0.5 - path-type: 6.0.0 - slash: 5.1.0 - unicorn-magic: 0.3.0 - - globrex@0.1.2: {} - - gopd@1.2.0: {} - graceful-fs@4.2.11: {} - graphemer@1.4.0: {} - - has-bigints@1.1.0: {} - - has-flag@4.0.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-proto@1.2.0: - dependencies: - dunder-proto: 1.0.1 - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - hosted-git-info@9.0.0: dependencies: lru-cache: 11.1.0 human-id@4.1.1: {} - human-signals@8.0.1: {} - iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 ignore@5.3.2: {} - ignore@7.0.5: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - import-modules@2.1.0: {} - - imurmurhash@0.1.4: {} - indent-string@5.0.0: {} ink-spinner@5.0.0(ink@6.1.0(react@19.1.1))(react@19.1.1): @@ -3743,90 +1220,30 @@ snapshots: chalk: 5.4.1 cli-boxes: 3.0.0 cli-cursor: 4.0.0 - cli-truncate: 4.0.0 - code-excerpt: 4.0.0 - es-toolkit: 1.39.8 - indent-string: 5.0.0 - is-in-ci: 1.0.0 - patch-console: 2.0.0 - react: 19.1.1 - react-reconciler: 0.32.0(react@19.1.1) - scheduler: 0.23.2 - signal-exit: 3.0.7 - slice-ansi: 7.1.0 - stack-utils: 2.0.6 - string-width: 7.2.0 - type-fest: 4.41.0 - widest-line: 5.0.0 - wrap-ansi: 9.0.0 - ws: 8.18.3 - yoga-layout: 3.2.1 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - internal-slot@1.1.0: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 - - irregular-plurals@3.5.0: {} - - is-array-buffer@3.0.5: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - is-arrayish@0.2.1: {} - - is-async-function@2.1.1: - dependencies: - async-function: 1.0.0 - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-bigint@1.1.0: - dependencies: - has-bigints: 1.1.0 - - is-boolean-object@1.2.2: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-builtin-module@5.0.0: - dependencies: - builtin-modules: 5.0.0 - - is-callable@1.2.7: {} - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - - is-data-view@1.0.2: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-typed-array: 1.1.15 - - is-date-object@1.1.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-docker@3.0.0: {} + cli-truncate: 4.0.0 + code-excerpt: 4.0.0 + es-toolkit: 1.39.8 + indent-string: 5.0.0 + is-in-ci: 1.0.0 + patch-console: 2.0.0 + react: 19.1.1 + react-reconciler: 0.32.0(react@19.1.1) + scheduler: 0.23.2 + signal-exit: 3.0.7 + slice-ansi: 7.1.0 + stack-utils: 2.0.6 + string-width: 7.2.0 + type-fest: 4.41.0 + widest-line: 5.0.0 + wrap-ansi: 9.0.0 + ws: 8.18.3 + yoga-layout: 3.2.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate is-extglob@2.1.1: {} - is-finalizationregistry@1.1.1: - dependencies: - call-bound: 1.0.4 - is-fullwidth-code-point@3.0.0: {} is-fullwidth-code-point@4.0.0: {} @@ -3835,213 +1252,51 @@ snapshots: dependencies: get-east-asian-width: 1.3.0 - is-generator-function@1.1.0: - dependencies: - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-get-set-prop@2.0.0: - dependencies: - get-set-props: 0.2.0 - lowercase-keys: 3.0.0 - is-glob@4.0.3: dependencies: is-extglob: 2.1.1 is-in-ci@1.0.0: {} - is-inside-container@1.0.0: - dependencies: - is-docker: 3.0.0 - - is-js-type@3.0.0: - dependencies: - js-types: 4.0.0 - - is-map@2.0.3: {} - - is-negative-zero@2.0.3: {} - - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - is-number@7.0.0: {} - is-obj-prop@2.0.0: - dependencies: - lowercase-keys: 3.0.0 - obj-props: 2.0.0 - - is-plain-obj@4.1.0: {} - - is-proto-prop@3.0.1: - dependencies: - lowercase-keys: 3.0.0 - prototype-properties: 5.0.0 - - is-regex@1.2.1: - dependencies: - call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - is-set@2.0.3: {} - - is-shared-array-buffer@1.0.4: - dependencies: - call-bound: 1.0.4 - - is-stream@4.0.1: {} - - is-string@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - is-subdir@1.2.0: dependencies: better-path-resolve: 1.0.0 - is-symbol@1.1.1: - dependencies: - call-bound: 1.0.4 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.19 - - is-unicode-supported@1.3.0: {} - - is-unicode-supported@2.1.0: {} - - is-weakmap@2.0.2: {} - - is-weakref@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-weakset@2.0.4: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-windows@1.0.2: {} - is-wsl@3.1.0: - dependencies: - is-inside-container: 1.0.0 - - isarray@2.0.5: {} - isexe@2.0.0: {} - iterator.prototype@1.1.5: - dependencies: - define-data-property: 1.1.4 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - has-symbols: 1.1.0 - set-function-name: 2.0.2 - jackspeak@4.1.1: dependencies: '@isaacs/cliui': 8.0.2 js-tokens@4.0.0: {} - js-types@4.0.0: {} - js-yaml@3.14.1: dependencies: argparse: 1.0.10 esprima: 4.0.1 - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - jsesc@3.0.2: {} - - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - - json-parse-even-better-errors@2.3.1: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 - jsx-ast-utils@3.3.5: - dependencies: - array-includes: 3.1.9 - array.prototype.flat: 1.3.3 - object.assign: 4.1.7 - object.values: 1.2.1 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - line-column-path@3.0.0: - dependencies: - type-fest: 2.19.0 - - lines-and-columns@1.2.4: {} - locate-path@5.0.0: dependencies: p-locate: 4.1.0 - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - lodash.startcase@4.4.0: {} - lodash@4.17.21: {} - - log-symbols@6.0.0: - dependencies: - chalk: 5.4.1 - is-unicode-supported: 1.3.0 - loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 - lowercase-keys@3.0.0: {} - lru-cache@11.1.0: {} - math-intrinsics@1.1.0: {} - - meow@13.2.0: {} - merge2@1.4.1: {} - micro-spelling-correcter@1.1.1: {} - micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -4049,20 +1304,10 @@ snapshots: mimic-fn@2.1.0: {} - min-indent@1.0.1: {} - minimatch@10.0.3: dependencies: '@isaacs/brace-expansion': 5.0.0 - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - minipass@7.1.2: {} minizlib@3.0.2: @@ -4073,94 +1318,14 @@ snapshots: mri@1.2.0: {} - ms@2.1.3: {} - - napi-postinstall@0.3.2: {} - - natural-compare@1.4.0: {} - - node-releases@2.0.19: {} - - npm-run-path@6.0.0: - dependencies: - path-key: 4.0.0 - unicorn-magic: 0.3.0 - - obj-props@2.0.0: {} - - object-assign@4.1.1: {} - - object-inspect@1.13.4: {} - - object-keys@1.1.1: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - object.entries@1.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - object.fromentries@2.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - - object.values@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - onetime@5.1.2: dependencies: mimic-fn: 2.1.0 - open-editor@5.1.0: - dependencies: - env-editor: 1.1.0 - execa: 9.6.0 - line-column-path: 3.0.0 - open: 10.2.0 - - open@10.2.0: - dependencies: - default-browser: 5.2.1 - define-lazy-prop: 3.0.0 - is-inside-container: 1.0.0 - wsl-utils: 0.1.0 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - os-tmpdir@1.0.2: {} outdent@0.5.0: {} - own-keys@1.0.1: - dependencies: - get-intrinsic: 1.3.0 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 - p-filter@2.1.0: dependencies: p-map: 2.1.0 @@ -4169,18 +1334,10 @@ snapshots: dependencies: p-try: 2.2.0 - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - p-locate@4.1.0: dependencies: p-limit: 2.3.0 - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - p-map@2.1.0: {} p-try@2.2.0: {} @@ -4191,31 +1348,12 @@ snapshots: dependencies: quansync: 0.2.10 - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse-json@5.2.0: - dependencies: - '@babel/code-frame': 7.27.1 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - - parse-ms@4.0.0: {} - patch-console@2.0.0: {} path-exists@4.0.0: {} - path-exists@5.0.0: {} - path-key@3.1.1: {} - path-key@4.0.0: {} - - path-parse@1.0.7: {} - path-scurry@2.0.0: dependencies: lru-cache: 11.1.0 @@ -4223,62 +1361,18 @@ snapshots: path-type@4.0.0: {} - path-type@6.0.0: {} - picocolors@1.1.1: {} picomatch@2.3.1: {} - picomatch@4.0.3: {} - pify@4.0.1: {} - pkg-dir@5.0.0: - dependencies: - find-up: 5.0.0 - - pkg-dir@8.0.0: - dependencies: - find-up-simple: 1.0.1 - - plur@5.1.0: - dependencies: - irregular-plurals: 3.5.0 - - pluralize@8.0.0: {} - - possible-typed-array-names@1.1.0: {} - - prelude-ls@1.2.1: {} - - prettier-linter-helpers@1.0.0: - dependencies: - fast-diff: 1.3.0 - prettier@2.8.8: {} - prettier@3.6.2: {} - - pretty-ms@9.2.0: - dependencies: - parse-ms: 4.0.0 - - prop-types@15.8.1: - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - react-is: 16.13.1 - - prototype-properties@5.0.0: {} - - punycode@2.3.1: {} - quansync@0.2.10: {} queue-microtask@1.2.3: {} - react-is@16.13.1: {} - react-reconciler@0.32.0(react@19.1.1): dependencies: react: 19.1.1 @@ -4293,44 +1387,8 @@ snapshots: pify: 4.0.1 strip-bom: 3.0.0 - reflect.getprototypeof@1.0.10: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - which-builtin-type: 1.2.1 - - regexp-tree@0.1.27: {} - - regexp.prototype.flags@1.5.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-errors: 1.3.0 - get-proto: 1.0.1 - gopd: 1.2.0 - set-function-name: 2.0.2 - - regjsparser@0.12.0: - dependencies: - jsesc: 3.0.2 - - resolve-from@4.0.0: {} - resolve-from@5.0.0: {} - resolve-pkg-maps@1.0.0: {} - - resolve@2.0.0-next.5: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@4.0.0: dependencies: onetime: 5.1.2 @@ -4338,31 +1396,10 @@ snapshots: reusify@1.1.0: {} - run-applescript@7.0.0: {} - run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - safe-array-concat@1.1.3: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - isarray: 2.0.5 - - safe-push-apply@1.0.0: - dependencies: - es-errors: 1.3.0 - isarray: 2.0.5 - - safe-regex-test@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-regex: 1.2.1 - safer-buffer@2.1.2: {} scheduler@0.23.2: @@ -4371,74 +1408,20 @@ snapshots: scheduler@0.26.0: {} - semver@6.3.1: {} - semver@7.7.2: {} - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-proto@1.0.0: - dependencies: - dunder-proto: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} - side-channel-list@1.0.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - signal-exit@3.0.7: {} signal-exit@4.1.0: {} slash@3.0.0: {} - slash@5.1.0: {} - slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.1 @@ -4456,17 +1439,10 @@ snapshots: sprintf-js@1.0.3: {} - stable-hash-x@0.2.0: {} - stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 - stop-iteration-iterator@1.1.0: - dependencies: - es-errors: 1.3.0 - internal-slot: 1.1.0 - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -4485,50 +1461,6 @@ snapshots: get-east-asian-width: 1.3.0 strip-ansi: 7.1.0 - string.prototype.matchall@4.0.12: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - regexp.prototype.flags: 1.5.4 - set-function-name: 2.0.2 - side-channel: 1.1.0 - - string.prototype.repeat@1.0.0: - dependencies: - define-properties: 1.2.1 - es-abstract: 1.24.0 - - string.prototype.trim@1.2.10: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - has-property-descriptors: 1.0.2 - - string.prototype.trimend@1.0.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string.prototype.trimstart@1.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -4539,31 +1471,6 @@ snapshots: strip-bom@3.0.0: {} - strip-final-newline@4.0.0: {} - - strip-indent@4.0.0: - dependencies: - min-indent: 1.0.1 - - strip-json-comments@3.1.1: {} - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-hyperlinks@3.2.0: - dependencies: - has-flag: 4.0.0 - supports-color: 7.2.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - synckit@0.11.11: - dependencies: - '@pkgr/core': 0.2.9 - - tapable@2.2.2: {} - tar@7.4.3: dependencies: '@isaacs/fs-minipass': 4.0.1 @@ -4583,160 +1490,12 @@ snapshots: dependencies: is-number: 7.0.0 - ts-api-utils@2.1.0(typescript@5.8.3): - dependencies: - typescript: 5.8.3 - - ts-declaration-location@1.0.7(typescript@5.8.3): - dependencies: - picomatch: 4.0.3 - typescript: 5.8.3 - - tslib@2.8.1: - optional: true - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-fest@2.19.0: {} - type-fest@4.41.0: {} - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - - typed-array-byte-length@1.0.3: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - - typed-array-byte-offset@1.0.4: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.10 - - typed-array-length@1.0.7: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.1.0 - reflect.getprototypeof: 1.0.10 - - typescript-eslint@8.38.0(eslint@9.32.0)(typescript@5.8.3): - dependencies: - '@typescript-eslint/eslint-plugin': 8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - eslint: 9.32.0 - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - typescript@5.8.3: {} - - unbox-primitive@1.1.0: - dependencies: - call-bound: 1.0.4 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 - undici@7.13.0: {} - unicorn-magic@0.3.0: {} - universalify@0.1.2: {} - unrs-resolver@1.11.1: - dependencies: - napi-postinstall: 0.3.2 - optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.11.1 - '@unrs/resolver-binding-android-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-x64': 1.11.1 - '@unrs/resolver-binding-freebsd-x64': 1.11.1 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 - '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-musl': 1.11.1 - '@unrs/resolver-binding-wasm32-wasi': 1.11.1 - '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 - '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 - '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - - update-browserslist-db@1.1.3(browserslist@4.25.1): - dependencies: - browserslist: 4.25.1 - escalade: 3.2.0 - picocolors: 1.1.1 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - which-boxed-primitive@1.1.1: - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.2 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 - - which-builtin-type@1.2.1: - dependencies: - call-bound: 1.0.4 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.1.1 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 - is-regex: 1.2.1 - is-weakref: 1.1.1 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.19 - - which-collection@1.0.2: - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 - - which-typed-array@1.1.19: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - which@2.0.2: dependencies: isexe: 2.0.0 @@ -4745,8 +1504,6 @@ snapshots: dependencies: string-width: 7.2.0 - word-wrap@1.2.5: {} - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -4767,55 +1524,6 @@ snapshots: ws@8.18.3: {} - wsl-utils@0.1.0: - dependencies: - is-wsl: 3.1.0 - - xo@1.2.1(@types/eslint@8.56.12)(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(typescript@5.8.3): - dependencies: - '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.32.0) - '@sindresorhus/tsconfig': 7.0.0 - '@stylistic/eslint-plugin': 4.4.1(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - arrify: 3.0.0 - cosmiconfig: 9.0.0(typescript@5.8.3) - define-lazy-prop: 3.0.0 - eslint: 9.32.0 - eslint-config-prettier: 10.1.8(eslint@9.32.0) - eslint-config-xo-react: 0.28.0(eslint@9.32.0) - eslint-config-xo-typescript: 7.0.0(eslint@9.32.0)(typescript@5.8.3) - eslint-formatter-pretty: 6.0.1 - eslint-plugin-ava: 15.1.0(eslint@9.32.0) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0) - eslint-plugin-n: 17.21.3(eslint@9.32.0)(typescript@5.8.3) - eslint-plugin-no-use-extend-native: 0.7.2(eslint@9.32.0) - eslint-plugin-prettier: 5.5.3(@types/eslint@8.56.12)(eslint-config-prettier@10.1.8(eslint@9.32.0))(eslint@9.32.0)(prettier@3.6.2) - eslint-plugin-promise: 7.2.1(eslint@9.32.0) - eslint-plugin-unicorn: 59.0.1(eslint@9.32.0) - find-cache-directory: 6.0.0 - get-stdin: 9.0.0 - get-tsconfig: 4.10.1 - globals: 16.3.0 - globby: 14.1.0 - meow: 13.2.0 - micromatch: 4.0.8 - open-editor: 5.1.0 - path-exists: 5.0.0 - prettier: 3.6.2 - type-fest: 4.41.0 - typescript-eslint: 8.38.0(eslint@9.32.0)(typescript@5.8.3) - transitivePeerDependencies: - - '@types/eslint' - - '@typescript-eslint/utils' - - eslint-import-resolver-node - - jiti - - supports-color - - typescript - yallist@5.0.0: {} - yocto-queue@0.1.0: {} - - yoctocolors@2.1.1: {} - yoga-layout@3.2.1: {} diff --git a/src/catalog-diff.js b/src/catalog-diff.js index b2cf386..9c3e5cd 100644 --- a/src/catalog-diff.js +++ b/src/catalog-diff.js @@ -21,16 +21,16 @@ export function diffCatalogs(oldCatalog, newCatalog) { if (skill?.source) { const src = skill.source; sources[src] ||= { - old_ref: null, // eslint-disable-line camelcase - new_ref: null // eslint-disable-line camelcase + old_ref: null, + new_ref: null }; if (oldSkill?.ref) { - sources[src].old_ref = oldSkill.ref; // eslint-disable-line camelcase + sources[src].old_ref = oldSkill.ref; } if (newSkill?.ref) { - sources[src].new_ref = newSkill.ref; // eslint-disable-line camelcase + sources[src].new_ref = newSkill.ref; } } } @@ -38,7 +38,11 @@ export function diffCatalogs(oldCatalog, newCatalog) { // Diff each skill const skills = {}; const counts = { - total: 0, new: 0, removed: 0, changed: 0, unchanged: 0 + total: 0, + new: 0, + removed: 0, + changed: 0, + unchanged: 0 }; for (const name of [...allNames].sort()) { @@ -63,30 +67,26 @@ export function diffCatalogs(oldCatalog, newCatalog) { } } - return {sources, skills, summary: counts}; + return { sources, skills, summary: counts }; } function buildNewSkillDiff(skill) { return { status: 'new', - version: {old: null, new: skill.version || null}, - /* eslint-disable camelcase -- SPEC.4 JSON schema */ - tool_surface: {added: [...(skill.tool_surface || [])], removed: []}, - command_surface: {added: [...(skill.command_surface || [])], removed: []}, - supporting_files: {added: [...(skill.supporting_files || [])], removed: []} - /* eslint-enable camelcase */ + version: { old: null, new: skill.version || null }, + tool_surface: { added: [...(skill.tool_surface || [])], removed: [] }, + command_surface: { added: [...(skill.command_surface || [])], removed: [] }, + supporting_files: { added: [...(skill.supporting_files || [])], removed: [] } }; } function buildRemovedSkillDiff(skill) { return { status: 'removed', - version: {old: skill.version || null, new: null}, - /* eslint-disable camelcase -- SPEC.4 JSON schema */ - tool_surface: {added: [], removed: [...(skill.tool_surface || [])]}, - command_surface: {added: [], removed: [...(skill.command_surface || [])]}, - supporting_files: {added: [], removed: [...(skill.supporting_files || [])]} - /* eslint-enable camelcase */ + version: { old: skill.version || null, new: null }, + tool_surface: { added: [], removed: [...(skill.tool_surface || [])] }, + command_surface: { added: [], removed: [...(skill.command_surface || [])] }, + supporting_files: { added: [], removed: [...(skill.supporting_files || [])] } }; } @@ -96,15 +96,18 @@ function buildChangedSkillDiff(oldSkill, newSkill) { new: newSkill.version || null }; - /* eslint-disable camelcase -- SPEC.4 JSON schema */ const toolDiff = diffArrays(oldSkill.tool_surface || [], newSkill.tool_surface || []); const commandDiff = diffArrays(oldSkill.command_surface || [], newSkill.command_surface || []); const fileDiff = diffArrays(oldSkill.supporting_files || [], newSkill.supporting_files || []); - const hasChanges = versionDiff.old !== versionDiff.new - || toolDiff.added.length > 0 || toolDiff.removed.length > 0 - || commandDiff.added.length > 0 || commandDiff.removed.length > 0 - || fileDiff.added.length > 0 || fileDiff.removed.length > 0; + const hasChanges = + versionDiff.old !== versionDiff.new || + toolDiff.added.length > 0 || + toolDiff.removed.length > 0 || + commandDiff.added.length > 0 || + commandDiff.removed.length > 0 || + fileDiff.added.length > 0 || + fileDiff.removed.length > 0; return { status: hasChanges ? 'changed' : 'unchanged', @@ -113,7 +116,6 @@ function buildChangedSkillDiff(oldSkill, newSkill) { command_surface: commandDiff, supporting_files: fileDiff }; - /* eslint-enable camelcase */ } function diffArrays(oldArray, newArray) { @@ -167,9 +169,10 @@ export function formatCatalogDiff(diff) { } // Changed - const versionStr = skillDiff.version.old === skillDiff.version.new - ? (skillDiff.version.new || '') - : `${skillDiff.version.old || '?'} -> ${skillDiff.version.new || '?'}`; + const versionStr = + skillDiff.version.old === skillDiff.version.new + ? skillDiff.version.new || '' + : `${skillDiff.version.old || '?'} -> ${skillDiff.version.new || '?'}`; lines.push(` ${name} ${versionStr}`); formatSurfaceDelta(lines, 'tools', skillDiff.tool_surface); formatSurfaceDelta(lines, 'commands', skillDiff.command_surface); @@ -179,8 +182,9 @@ export function formatCatalogDiff(diff) { // Summary const s = diff.summary; - const summaryText = `Summary: ${s.total} skills` - + ` (${s.new} new, ${s.removed} removed, ${s.changed} changed, ${s.unchanged} unchanged)`; + const summaryText = + `Summary: ${s.total} skills` + + ` (${s.new} new, ${s.removed} removed, ${s.changed} changed, ${s.unchanged} unchanged)`; lines.push(summaryText); return lines.join('\n'); diff --git a/src/catalog.js b/src/catalog.js index f2cd96c..a7b1a30 100644 --- a/src/catalog.js +++ b/src/catalog.js @@ -1,7 +1,7 @@ -import {join, basename} from 'node:path'; -import {readFile} from 'node:fs/promises'; -import {readLineage} from './lineage.js'; -import {scanDirectory, summarizeScan} from './scanner.js'; +import { readFile } from 'node:fs/promises'; +import { basename, join } from 'node:path'; +import { readLineage } from './lineage.js'; +import { scanDirectory, summarizeScan } from './scanner.js'; /** * Build a catalog from content on disk. @@ -25,8 +25,10 @@ export async function buildCatalog(resolvedPath) { continue; } - // eslint-disable-next-line no-await-in-loop - const skillEntry = await buildSkillEntry(resolvedPath, record, prefix, {filePath, scanSummary}); + const skillEntry = await buildSkillEntry(resolvedPath, record, prefix, { + filePath, + scanSummary + }); if (skillEntry) { skills[skillEntry.name] = skillEntry.data; } @@ -34,13 +36,14 @@ export async function buildCatalog(resolvedPath) { } return { - generated_at: new Date().toISOString(), // eslint-disable-line camelcase + generated_at: new Date().toISOString(), skills }; } -async function buildSkillEntry(resolvedPath, record, prefix, {filePath, scanSummary}) { - const skillDir = filePath === 'SKILL.md' ? prefix : join(prefix, filePath.replace(/\/SKILL\.md$/, '')); +async function buildSkillEntry(resolvedPath, record, prefix, { filePath, scanSummary }) { + const skillDir = + filePath === 'SKILL.md' ? prefix : join(prefix, filePath.replace(/\/SKILL\.md$/, '')); const skillName = basename(skillDir); const fullSkillPath = join(resolvedPath, prefix, filePath); @@ -71,12 +74,10 @@ async function buildSkillEntry(resolvedPath, record, prefix, {filePath, scanSumm name: frontmatter?.name || skillName, version: frontmatter?.version || null, description, - /* eslint-disable camelcase -- SPEC.3 JSON schema */ tool_surface: Object.keys(fileScan.tool_refs || {}), command_surface: fileScan.command_refs || [], supporting_files: supportingFiles, - /* eslint-enable camelcase */ - fetched_at: record.fetched_at // eslint-disable-line camelcase + fetched_at: record.fetched_at } }; } @@ -97,7 +98,10 @@ export function extractFrontmatter(content) { const colonIndex = line.indexOf(':'); if (colonIndex > 0) { const key = line.slice(0, colonIndex).trim(); - const value = line.slice(colonIndex + 1).trim().replaceAll(/^["']|["']$/g, ''); + const value = line + .slice(colonIndex + 1) + .trim() + .replaceAll(/^["']|["']$/g, ''); result[key] = value; } } diff --git a/src/cli.js b/src/cli.js index b74f253..fd59c40 100644 --- a/src/cli.js +++ b/src/cli.js @@ -1,18 +1,18 @@ import process from 'node:process'; -import {jack} from 'jackspeak'; -import {render} from 'ink'; +import { render } from 'ink'; +import { jack } from 'jackspeak'; import React from 'react'; -import {FetchCommand} from './commands/fetch.js'; -import {BatchCommand} from './commands/batch.js'; -import {VerifyCommand} from './commands/verify.js'; -import {PinCommand} from './commands/pin.js'; -import {OutdatedCommand} from './commands/outdated.js'; -import {DiffCommand} from './commands/diff.js'; -import {ScanCommand} from './commands/scan.js'; -import {CatalogCommand} from './commands/catalog.js'; -import {UpgradeCommand} from './commands/upgrade.js'; -import {CatalogDiffCommand} from './commands/catalog-diff.js'; -import {PRESETS} from './presets.js'; +import { BatchCommand } from './commands/batch.js'; +import { CatalogCommand } from './commands/catalog.js'; +import { CatalogDiffCommand } from './commands/catalog-diff.js'; +import { DiffCommand } from './commands/diff.js'; +import { FetchCommand } from './commands/fetch.js'; +import { OutdatedCommand } from './commands/outdated.js'; +import { PinCommand } from './commands/pin.js'; +import { ScanCommand } from './commands/scan.js'; +import { UpgradeCommand } from './commands/upgrade.js'; +import { VerifyCommand } from './commands/verify.js'; +import { PRESETS } from './presets.js'; const j = jack({ usage: 'vlurp [command] [source] [options]' @@ -24,7 +24,8 @@ const j = jack({ short: 'd' }, preset: { - description: 'Use a preset filter configuration (claude, skills, agents, docs, all-md, minimal)', + description: + 'Use a preset filter configuration (claude, skills, agents, docs, all-md, minimal)', hint: 'name' }, ref: { @@ -43,7 +44,19 @@ const j = jack({ .optList({ filter: { description: 'Glob patterns to filter files (see defaults in help)', - default: ['.claude/**', 'CLAUDE.md', '*.md', '**/*.md', '!README.md', '!CONTRIBUTING.md', '!LICENSE.md', '!CHANGELOG.md', '!CODE_OF_CONDUCT.md', 'agents/**', 'commands/**'] + default: [ + '.claude/**', + 'CLAUDE.md', + '*.md', + '**/*.md', + '!README.md', + '!CONTRIBUTING.md', + '!LICENSE.md', + '!CHANGELOG.md', + '!CODE_OF_CONDUCT.md', + 'agents/**', + 'commands/**' + ] } }) .flag({ @@ -72,7 +85,7 @@ const j = jack({ } }); -const {values, positionals} = j.parse(); +const { values, positionals } = j.parse(); if (values.help) { console.log(`vlurp - A fun CLI tool to quickly fetch GitHub repositories and gists @@ -103,8 +116,9 @@ Usage: vlurp diff user/repo -d ./skills Show diff against upstream Presets: -${Object.entries(PRESETS).map(([name, config]) => - ` ${name.padEnd(10)} ${config.description}`).join('\n')} +${Object.entries(PRESETS) + .map(([name, config]) => ` ${name.padEnd(10)} ${config.description}`) + .join('\n')} Examples: vlurp user/repo --ref abc1234 Fetch pinned to commit @@ -144,8 +158,8 @@ if (positionals.length === 0) { const command = positionals[0]; const rootDir = values.d; -const {force, auto, preset, quiet} = values; -const {ref} = values; +const { force, auto, preset, quiet } = values; +const { ref } = values; const asName = values.as; const dryRun = values['dry-run']; @@ -159,16 +173,21 @@ switch (command) { process.exit(1); } - render(React.createElement(BatchCommand, { - vlurpfile, dryRun, force, quiet - })); + render( + React.createElement(BatchCommand, { + vlurpfile, + dryRun, + force, + quiet + }) + ); break; } case 'verify': { const targetPath = positionals[1] || '.'; - render(React.createElement(VerifyCommand, {targetPath})); + render(React.createElement(VerifyCommand, { targetPath })); break; } @@ -176,39 +195,41 @@ switch (command) { case 'pin': { const source = positionals[1] || null; const vlurpfilePath = positionals[2] || null; - render(React.createElement(PinCommand, {source, vlurpfilePath})); + render(React.createElement(PinCommand, { source, vlurpfilePath })); break; } case 'outdated': { const vlurpfileArg = positionals[1] || null; - render(React.createElement(OutdatedCommand, {vlurpfilePath: vlurpfileArg})); + render(React.createElement(OutdatedCommand, { vlurpfilePath: vlurpfileArg })); break; } case 'upgrade': { const upgradeSource = positionals[1] || null; - render(React.createElement(UpgradeCommand, { - vlurpfilePath: values.vlurpfile || null, - source: upgradeSource, - dryRun - })); + render( + React.createElement(UpgradeCommand, { + vlurpfilePath: values.vlurpfile || null, + source: upgradeSource, + dryRun + }) + ); break; } case 'scan': { const scanPath = positionals[1] || '.'; - render(React.createElement(ScanCommand, {targetPath: scanPath})); + render(React.createElement(ScanCommand, { targetPath: scanPath })); break; } case 'catalog': { const catalogPath = positionals[1] || '.'; - render(React.createElement(CatalogCommand, {targetPath: catalogPath})); + render(React.createElement(CatalogCommand, { targetPath: catalogPath })); break; } @@ -216,11 +237,13 @@ switch (command) { case 'catalog-diff': { const cdOldPath = positionals[1] || null; const cdNewPath = positionals[2] || null; - render(React.createElement(CatalogDiffCommand, { - oldPath: cdOldPath, - newPath: cdNewPath, - json: values.json - })); + render( + React.createElement(CatalogDiffCommand, { + oldPath: cdOldPath, + newPath: cdNewPath, + json: values.json + }) + ); break; } @@ -233,13 +256,13 @@ switch (command) { process.exit(1); } - render(React.createElement(DiffCommand, {source: diffSource, rootDir})); + render(React.createElement(DiffCommand, { source: diffSource, rootDir })); break; } default: { - // Regular fetch command + // Regular fetch command const source = command; // Resolve filters from preset or explicit filters @@ -248,17 +271,19 @@ switch (command) { filters = PRESETS[preset].filters; } - render(React.createElement(FetchCommand, { - source, - rootDir, - filters, - force, - auto, - dryRun, - quiet, - ref, - asName, - preset - })); + render( + React.createElement(FetchCommand, { + source, + rootDir, + filters, + force, + auto, + dryRun, + quiet, + ref, + asName, + preset + }) + ); } } diff --git a/src/commands/batch.js b/src/commands/batch.js index cdc447c..a99dd12 100644 --- a/src/commands/batch.js +++ b/src/commands/batch.js @@ -1,14 +1,14 @@ +import { readFile } from 'node:fs/promises'; +import { join, resolve } from 'node:path'; import process from 'node:process'; -import {readFile} from 'node:fs/promises'; -import {resolve, join} from 'node:path'; -import React, {useState, useEffect} from 'react'; -import {Box, Text} from 'ink'; +import { Box, Text } from 'ink'; import Spinner from 'ink-spinner'; -import {parseVlurpfile} from '../vlurpfile.js'; -import {parseSource, fetchRepository} from '../remote.js'; -import {hashDirectory, createLineageRecord, appendLineage} from '../lineage.js'; +import React, { useEffect, useState } from 'react'; +import { appendLineage, createLineageRecord, hashDirectory } from '../lineage.js'; +import { fetchRepository, parseSource } from '../remote.js'; +import { parseVlurpfile } from '../vlurpfile.js'; -export function BatchCommand({vlurpfile, dryRun, force, quiet: _quiet}) { +export function BatchCommand({ vlurpfile, dryRun, force, quiet: _quiet }) { const [status, setStatus] = useState('parsing'); const [error, setError] = useState(null); const [entries, setEntries] = useState([]); @@ -30,8 +30,10 @@ export function BatchCommand({vlurpfile, dryRun, force, quiet: _quiet}) { setStatus('dry-run'); const dryResults = parsed.map(entry => { try { - const parsedSource = parseSource(entry.source, {ref: entry.ref}); - const targetPath = entry.targetPath || resolve(entry.rootDir || '.', parsedSource.user, parsedSource.repo); + const parsedSource = parseSource(entry.source, { ref: entry.ref }); + const targetPath = + entry.targetPath || + resolve(entry.rootDir || '.', parsedSource.user, parsedSource.repo); return { ...entry, status: 'would-fetch', @@ -58,19 +60,16 @@ export function BatchCommand({vlurpfile, dryRun, force, quiet: _quiet}) { setCurrentIndex(i); try { - const parsedSource = parseSource(entry.source, {ref: entry.ref}); - const targetPath = entry.targetPath || resolve(entry.rootDir || '.', parsedSource.user, parsedSource.repo); + const parsedSource = parseSource(entry.source, { ref: entry.ref }); + const targetPath = + entry.targetPath || + resolve(entry.rootDir || '.', parsedSource.user, parsedSource.repo); - // eslint-disable-next-line no-await-in-loop -- Sequential batch processing is intentional - await fetchRepository( - parsedSource.tarballUrl, - targetPath, - entry.filters, - {force: force || entry.force} - ); + await fetchRepository(parsedSource.tarballUrl, targetPath, entry.filters, { + force: force || entry.force + }); // Generate lineage record - // eslint-disable-next-line no-await-in-loop const files = await hashDirectory(targetPath); const lineageRecord = createLineageRecord({ source: `${parsedSource.user}/${parsedSource.repo}`, @@ -85,7 +84,6 @@ export function BatchCommand({vlurpfile, dryRun, force, quiet: _quiet}) { // Write lineage at the rootDir level const lineageDir = entry.rootDir ? resolve(entry.rootDir) : process.cwd(); const lineagePath = join(lineageDir, '.vlurp.jsonl'); - // eslint-disable-next-line no-await-in-loop await appendLineage(lineagePath, lineageRecord); batchResults.push({ @@ -118,8 +116,8 @@ export function BatchCommand({vlurpfile, dryRun, force, quiet: _quiet}) { if (status === 'error') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'red'}, `Error: ${error}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'red' }, `Error: ${error}`) ); } @@ -127,7 +125,7 @@ export function BatchCommand({vlurpfile, dryRun, force, quiet: _quiet}) { return React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement(Text, null, ' Parsing .vlurpfile...') ); } @@ -136,39 +134,45 @@ export function BatchCommand({vlurpfile, dryRun, force, quiet: _quiet}) { const unpinnedCount = results.filter(r => !r.ref && r.status !== 'error').length; return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'yellow', bold: true}, `Dry run - would process ${results.length} entries:\n`), - unpinnedCount > 0 && React.createElement( + { flexDirection: 'column' }, + React.createElement( Text, - {color: 'yellow'}, - ` Warning: ${unpinnedCount} source(s) not pinned (mutable upstream)\n` + { color: 'yellow', bold: true }, + `Dry run - would process ${results.length} entries:\n` ), + unpinnedCount > 0 && + React.createElement( + Text, + { color: 'yellow' }, + ` Warning: ${unpinnedCount} source(s) not pinned (mutable upstream)\n` + ), ...results.map((result, i) => React.createElement( Box, - {key: i, flexDirection: 'column', marginBottom: 1}, + { key: i, flexDirection: 'column', marginBottom: 1 }, React.createElement( Text, - {color: result.status === 'error' ? 'red' : 'gray'}, + { color: result.status === 'error' ? 'red' : 'gray' }, ` ${i + 1}. ${result.source}${result.ref ? ` @${result.ref}` : ''}` ), - !result.ref && result.status !== 'error' && React.createElement( - Text, - {color: 'yellow'}, - ' (not pinned)' - ), - result.targetPath && React.createElement( - Text, - {color: 'cyan'}, - ` -> ${result.targetPath}` - ), - result.filters?.length > 0 && React.createElement( - Text, - {color: 'gray', dimColor: true}, - ` filters: ${result.filters.slice(0, 3).join(', ')}${result.filters.length > 3 ? '...' : ''}` - ) - )), - React.createElement(Text, {color: 'gray', marginTop: 1}, '\nRun without --dry-run to execute.') + !result.ref && + result.status !== 'error' && + React.createElement(Text, { color: 'yellow' }, ' (not pinned)'), + result.targetPath && + React.createElement(Text, { color: 'cyan' }, ` -> ${result.targetPath}`), + result.filters?.length > 0 && + React.createElement( + Text, + { color: 'gray', dimColor: true }, + ` filters: ${result.filters.slice(0, 3).join(', ')}${result.filters.length > 3 ? '...' : ''}` + ) + ) + ), + React.createElement( + Text, + { color: 'gray', marginTop: 1 }, + '\nRun without --dry-run to execute.' + ) ); } @@ -179,20 +183,27 @@ export function BatchCommand({vlurpfile, dryRun, force, quiet: _quiet}) { return React.createElement( Box, - {flexDirection: 'column'}, + { flexDirection: 'column' }, React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), - React.createElement(Text, null, ` [${completed + 1}/${total}] Fetching ${current?.source}...`) - ), - results.length > 0 && React.createElement(Box, {marginTop: 1}), - ...results.slice(-5).map((result, i) => + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement( Text, - {key: i, color: result.status === 'success' ? 'green' : 'red'}, - ` ${result.status === 'success' ? 'ok' : 'ERR'} ${result.message}` - )) + null, + ` [${completed + 1}/${total}] Fetching ${current?.source}...` + ) + ), + results.length > 0 && React.createElement(Box, { marginTop: 1 }), + ...results + .slice(-5) + .map((result, i) => + React.createElement( + Text, + { key: i, color: result.status === 'success' ? 'green' : 'red' }, + ` ${result.status === 'success' ? 'ok' : 'ERR'} ${result.message}` + ) + ) ); } @@ -202,18 +213,19 @@ export function BatchCommand({vlurpfile, dryRun, force, quiet: _quiet}) { return React.createElement( Box, - {flexDirection: 'column'}, + { flexDirection: 'column' }, React.createElement( Text, - {color: errorCount > 0 ? 'yellow' : 'green', bold: true}, + { color: errorCount > 0 ? 'yellow' : 'green', bold: true }, `Batch complete: ${successCount} succeeded${errorCount > 0 ? `, ${errorCount} failed` : ''}` ), React.createElement(Text, null, ''), ...results.map((result, i) => React.createElement( Text, - {key: i, color: result.status === 'success' ? 'green' : 'red'}, + { key: i, color: result.status === 'success' ? 'green' : 'red' }, ` ${result.status === 'success' ? 'ok' : 'ERR'} ${result.message}` - )) + ) + ) ); } diff --git a/src/commands/catalog-diff.js b/src/commands/catalog-diff.js index 5d5eea9..f4ebe34 100644 --- a/src/commands/catalog-diff.js +++ b/src/commands/catalog-diff.js @@ -1,11 +1,11 @@ -import {resolve} from 'node:path'; -import {readFile} from 'node:fs/promises'; -import React, {useState, useEffect} from 'react'; -import {Box, Text} from 'ink'; +import { readFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { Box, Text } from 'ink'; import Spinner from 'ink-spinner'; -import {diffCatalogs, formatCatalogDiff} from '../catalog-diff.js'; +import React, { useEffect, useState } from 'react'; +import { diffCatalogs, formatCatalogDiff } from '../catalog-diff.js'; -export function CatalogDiffCommand({oldPath, newPath, json}) { +export function CatalogDiffCommand({ oldPath, newPath, json }) { const [status, setStatus] = useState('diffing'); const [error, setError] = useState(null); const [result, setResult] = useState(null); @@ -38,7 +38,7 @@ export function CatalogDiffCommand({oldPath, newPath, json}) { } const diff = diffCatalogs(oldCatalog, newCatalog); - setResult({diff, oldPath: resolvedOld, newPath: resolvedNew}); + setResult({ diff, oldPath: resolvedOld, newPath: resolvedNew }); setStatus('complete'); } catch (err) { setError(err.message); @@ -47,13 +47,13 @@ export function CatalogDiffCommand({oldPath, newPath, json}) { } performDiff(); - }, [oldPath, newPath, json]); + }, [oldPath, newPath]); if (status === 'error') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'red'}, `Error: ${error}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'red' }, `Error: ${error}`) ); } @@ -61,18 +61,14 @@ export function CatalogDiffCommand({oldPath, newPath, json}) { return React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement(Text, null, ' Comparing catalogs...') ); } // JSON output if (json) { - return React.createElement( - Text, - null, - JSON.stringify(result.diff, null, 2) - ); + return React.createElement(Text, null, JSON.stringify(result.diff, null, 2)); } // Human-readable output @@ -82,12 +78,9 @@ export function CatalogDiffCommand({oldPath, newPath, json}) { return React.createElement( Box, - {flexDirection: 'column'}, + { flexDirection: 'column' }, React.createElement(Text, null, formatted), - !hasChanges && React.createElement( - Text, - {color: 'green', marginTop: 1}, - 'No changes between catalogs.' - ) + !hasChanges && + React.createElement(Text, { color: 'green', marginTop: 1 }, 'No changes between catalogs.') ); } diff --git a/src/commands/catalog.js b/src/commands/catalog.js index 306088f..eaae75f 100644 --- a/src/commands/catalog.js +++ b/src/commands/catalog.js @@ -1,11 +1,11 @@ -import {resolve, join} from 'node:path'; -import {writeFile} from 'node:fs/promises'; -import React, {useState, useEffect} from 'react'; -import {Box, Text} from 'ink'; +import { writeFile } from 'node:fs/promises'; +import { join, resolve } from 'node:path'; +import { Box, Text } from 'ink'; import Spinner from 'ink-spinner'; -import {buildCatalog} from '../catalog.js'; +import React, { useEffect, useState } from 'react'; +import { buildCatalog } from '../catalog.js'; -export function CatalogCommand({targetPath, outputFile}) { +export function CatalogCommand({ targetPath, outputFile }) { const [status, setStatus] = useState('cataloging'); const [error, setError] = useState(null); const [catalog, setCatalog] = useState(null); @@ -18,9 +18,9 @@ export function CatalogCommand({targetPath, outputFile}) { // Write catalog.json const outPath = outputFile || join(resolvedPath, 'catalog.json'); - await writeFile(outPath, JSON.stringify(catalogData, null, 2) + '\n'); + await writeFile(outPath, `${JSON.stringify(catalogData, null, 2)}\n`); - setCatalog({data: catalogData, path: outPath}); + setCatalog({ data: catalogData, path: outPath }); setStatus('complete'); } catch (err) { setError(err.message); @@ -34,8 +34,8 @@ export function CatalogCommand({targetPath, outputFile}) { if (status === 'error') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'red'}, `Error: ${error}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'red' }, `Error: ${error}`) ); } @@ -43,7 +43,7 @@ export function CatalogCommand({targetPath, outputFile}) { return React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement(Text, null, ' Building catalog...') ); } @@ -52,20 +52,21 @@ export function CatalogCommand({targetPath, outputFile}) { return React.createElement( Box, - {flexDirection: 'column'}, + { flexDirection: 'column' }, React.createElement( Text, - {color: 'green', bold: true}, + { color: 'green', bold: true }, `Catalog: ${skillCount} skill${skillCount === 1 ? '' : 's'} indexed` ), React.createElement(Text, null, ''), ...Object.entries(catalog.data.skills).map(([name, skill]) => React.createElement( Text, - {key: name, color: 'gray'}, + { key: name, color: 'gray' }, ` ${name.padEnd(30)} ${skill.source}${skill.ref ? ` @${skill.ref}` : ''}` - )), + ) + ), React.createElement(Text, null, ''), - React.createElement(Text, {color: 'gray'}, `Written to ${catalog.path}`) + React.createElement(Text, { color: 'gray' }, `Written to ${catalog.path}`) ); } diff --git a/src/commands/diff.js b/src/commands/diff.js index 4bc0e31..d5ab80c 100644 --- a/src/commands/diff.js +++ b/src/commands/diff.js @@ -1,16 +1,16 @@ +import { execSync } from 'node:child_process'; +import { randomBytes } from 'node:crypto'; +import { mkdir, rm } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { join, resolve } from 'node:path'; import process from 'node:process'; -import {resolve, join} from 'node:path'; -import {mkdir, rm} from 'node:fs/promises'; -import {tmpdir} from 'node:os'; -import {randomBytes} from 'node:crypto'; -import {execSync} from 'node:child_process'; -import React, {useState, useEffect} from 'react'; -import {Box, Text} from 'ink'; +import { Box, Text } from 'ink'; import Spinner from 'ink-spinner'; -import {parseSource, fetchRepository} from '../remote.js'; -import {readLineage} from '../lineage.js'; +import React, { useEffect, useState } from 'react'; +import { readLineage } from '../lineage.js'; +import { fetchRepository, parseSource } from '../remote.js'; -export function DiffCommand({source, rootDir}) { +export function DiffCommand({ source, rootDir }) { const [status, setStatus] = useState('diffing'); const [error, setError] = useState(null); const [diffOutput, setDiffOutput] = useState(null); @@ -36,18 +36,18 @@ export function DiffCommand({source, rootDir}) { // Fetch upstream to temp directory setStatus('fetching upstream'); - await mkdir(tempDir, {recursive: true}); + await mkdir(tempDir, { recursive: true }); const tempTarget = join(tempDir, 'upstream'); - await fetchRepository(parsed.tarballUrl, tempTarget, filters, {force: true}); + await fetchRepository(parsed.tarballUrl, tempTarget, filters, { force: true }); // Run diff between local and upstream setStatus('comparing'); let diff = ''; try { - diff = execSync( - `diff -rN --unified=3 "${localDir}" "${tempTarget}"`, - {encoding: 'utf8', maxBuffer: 1024 * 1024 * 10} - ); + diff = execSync(`diff -rN --unified=3 "${localDir}" "${tempTarget}"`, { + encoding: 'utf8', + maxBuffer: 1024 * 1024 * 10 + }); } catch (err) { // Diff exits with code 1 when files differ — that's expected if (err.status === 1) { @@ -65,10 +65,14 @@ export function DiffCommand({source, rootDir}) { // Count changed files const fileChanges = (diff.match(/^diff /gm) || []).length; - setSummary({changed: fileChanges, source: `${parsed.user}/${parsed.repo}`, ref: record?.ref}); + setSummary({ + changed: fileChanges, + source: `${parsed.user}/${parsed.repo}`, + ref: record?.ref + }); setDiffOutput(cleanDiff); } else { - setSummary({changed: 0, source: `${parsed.user}/${parsed.repo}`, ref: record?.ref}); + setSummary({ changed: 0, source: `${parsed.user}/${parsed.repo}`, ref: record?.ref }); setDiffOutput(''); } @@ -79,7 +83,7 @@ export function DiffCommand({source, rootDir}) { } finally { // Clean up temp directory try { - await rm(tempDir, {recursive: true, force: true}); + await rm(tempDir, { recursive: true, force: true }); } catch { // Cleanup failure is non-fatal } @@ -92,8 +96,8 @@ export function DiffCommand({source, rootDir}) { if (status === 'error') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'red'}, `Error: ${error}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'red' }, `Error: ${error}`) ); } @@ -101,18 +105,22 @@ export function DiffCommand({source, rootDir}) { return React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), - React.createElement(Text, null, ` ${status === 'fetching upstream' ? 'Fetching upstream...' : 'Comparing...'}`) + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), + React.createElement( + Text, + null, + ` ${status === 'fetching upstream' ? 'Fetching upstream...' : 'Comparing...'}` + ) ); } if (summary.changed === 0) { return React.createElement( Box, - {flexDirection: 'column'}, + { flexDirection: 'column' }, React.createElement( Text, - {color: 'green'}, + { color: 'green' }, `${summary.source}${summary.ref ? ` (pinned: ${summary.ref})` : ''} No changes` ) ); @@ -120,10 +128,10 @@ export function DiffCommand({source, rootDir}) { return React.createElement( Box, - {flexDirection: 'column'}, + { flexDirection: 'column' }, React.createElement( Text, - {color: 'yellow', bold: true}, + { color: 'yellow', bold: true }, `${summary.source}${summary.ref ? ` (pinned: ${summary.ref})` : ''} ${summary.changed} file(s) differ` ), React.createElement(Text, null, ''), diff --git a/src/commands/fetch.js b/src/commands/fetch.js index 2dadbd0..98bd406 100644 --- a/src/commands/fetch.js +++ b/src/commands/fetch.js @@ -1,14 +1,25 @@ +import { join, resolve } from 'node:path'; import process from 'node:process'; -import {resolve, join} from 'node:path'; -import React, {useState, useEffect} from 'react'; -import {Box, Text} from 'ink'; +import { Box, Text } from 'ink'; import Spinner from 'ink-spinner'; -import {parseSource, validateUrl, fetchRepository} from '../remote.js'; -import {detectStructure} from '../detector.js'; -import {buildTreeString} from '../tree.js'; -import {hashDirectory, createLineageRecord, appendLineage} from '../lineage.js'; - -export function FetchCommand({source, rootDir, filters, force, auto, dryRun, quiet, ref, asName, preset}) { +import React, { useEffect, useState } from 'react'; +import { detectStructure } from '../detector.js'; +import { appendLineage, createLineageRecord, hashDirectory } from '../lineage.js'; +import { fetchRepository, parseSource, validateUrl } from '../remote.js'; +import { buildTreeString } from '../tree.js'; + +export function FetchCommand({ + source, + rootDir, + filters, + force, + auto, + dryRun, + quiet, + ref, + asName, + preset +}) { const [status, setStatus] = useState('locating'); const [error, setError] = useState(null); const [result, setResult] = useState(null); @@ -19,7 +30,7 @@ export function FetchCommand({source, rootDir, filters, force, auto, dryRun, qui try { // Parse the source input setStatus('locating'); - const parsed = parseSource(source, {ref}); + const parsed = parseSource(source, { ref }); // Validate if it's a URL if (parsed.type === 'url') { @@ -68,7 +79,12 @@ export function FetchCommand({source, rootDir, filters, force, auto, dryRun, qui } // Vlurp the repository - const {fileCount} = await fetchRepository(parsed.tarballUrl, targetPath, effectiveFilters, {force}); + const { fileCount } = await fetchRepository( + parsed.tarballUrl, + targetPath, + effectiveFilters, + { force } + ); // Generate lineage record // File paths are relative to targetPath; we store them as-is @@ -114,29 +130,46 @@ export function FetchCommand({source, rootDir, filters, force, auto, dryRun, qui } performFetch(); - }, [source, rootDir, filters, force, auto, dryRun, ref, asName, preset]); + }, [source, rootDir, filters, force, auto, dryRun, ref, asName, preset, quiet]); if (status === 'error') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'red'}, `Error: ${error}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'red' }, `Error: ${error}`) ); } if (status === 'dry-run') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'yellow', bold: true}, `Dry run - would fetch ${result.user}/${result.repo}`), - result.ref && React.createElement(Text, {color: 'green'}, ` Pinned: ${result.ref}`), - !result.ref && React.createElement(Text, {color: 'yellow'}, ' Warning: not pinned (mutable upstream)'), - result.asName && React.createElement(Text, {color: 'cyan'}, ` As: ${result.asName}`), - React.createElement(Text, {color: 'gray'}, ` Target: ${result.path}`), - result.detectedPatterns?.length > 0 - && React.createElement(Text, {color: 'cyan'}, ` Auto-detected: ${result.detectedPatterns.join(', ')}`), - React.createElement(Text, {color: 'gray'}, ` Filters: ${result.filters.slice(0, 5).join(', ')}${result.filters.length > 5 ? '...' : ''}`), - React.createElement(Text, {color: 'gray', marginTop: 1}, '\nRun without --dry-run to execute.') + { flexDirection: 'column' }, + React.createElement( + Text, + { color: 'yellow', bold: true }, + `Dry run - would fetch ${result.user}/${result.repo}` + ), + result.ref && React.createElement(Text, { color: 'green' }, ` Pinned: ${result.ref}`), + !result.ref && + React.createElement(Text, { color: 'yellow' }, ' Warning: not pinned (mutable upstream)'), + result.asName && React.createElement(Text, { color: 'cyan' }, ` As: ${result.asName}`), + React.createElement(Text, { color: 'gray' }, ` Target: ${result.path}`), + result.detectedPatterns?.length > 0 && + React.createElement( + Text, + { color: 'cyan' }, + ` Auto-detected: ${result.detectedPatterns.join(', ')}` + ), + React.createElement( + Text, + { color: 'gray' }, + ` Filters: ${result.filters.slice(0, 5).join(', ')}${result.filters.length > 5 ? '...' : ''}` + ), + React.createElement( + Text, + { color: 'gray', marginTop: 1 }, + '\nRun without --dry-run to execute.' + ) ); } @@ -144,7 +177,7 @@ export function FetchCommand({source, rootDir, filters, force, auto, dryRun, qui return React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement(Text, null, ' Auto-detecting repository structure...') ); } @@ -152,29 +185,45 @@ export function FetchCommand({source, rootDir, filters, force, auto, dryRun, qui if (status === 'complete') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'green'}, `vlurped ${result.user}/${result.repo}`), - result.ref && React.createElement(Text, {color: 'green'}, ` Pinned: ${result.ref}`), - result.unpinned && React.createElement(Text, {color: 'yellow'}, ' Warning: not pinned (mutable upstream)'), - React.createElement(Text, {color: 'gray'}, ` Location: ${result.path}`), - React.createElement(Text, {color: 'gray'}, ` Lineage: ${result.lineagePath}`), - result.detectedPatterns?.length > 0 - && React.createElement(Text, {color: 'cyan'}, ` Auto-detected: ${result.detectedPatterns.join(', ')}`), - result.filterCount > 0 && React.createElement(Text, {color: 'gray'}, ` Filters: ${result.filterCount} pattern(s) applied`), - treeOutput && !quiet && React.createElement(Box, {marginTop: 1}, React.createElement(Text, null, treeOutput)), - React.createElement(Text, {color: 'cyan', marginTop: 1}, `vlurped ${result.fileCount} files to ${result.path}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'green' }, `vlurped ${result.user}/${result.repo}`), + result.ref && React.createElement(Text, { color: 'green' }, ` Pinned: ${result.ref}`), + result.unpinned && + React.createElement(Text, { color: 'yellow' }, ' Warning: not pinned (mutable upstream)'), + React.createElement(Text, { color: 'gray' }, ` Location: ${result.path}`), + React.createElement(Text, { color: 'gray' }, ` Lineage: ${result.lineagePath}`), + result.detectedPatterns?.length > 0 && + React.createElement( + Text, + { color: 'cyan' }, + ` Auto-detected: ${result.detectedPatterns.join(', ')}` + ), + result.filterCount > 0 && + React.createElement( + Text, + { color: 'gray' }, + ` Filters: ${result.filterCount} pattern(s) applied` + ), + treeOutput && + !quiet && + React.createElement(Box, { marginTop: 1 }, React.createElement(Text, null, treeOutput)), + React.createElement( + Text, + { color: 'cyan', marginTop: 1 }, + `vlurped ${result.fileCount} files to ${result.path}` + ) ); } return React.createElement( Box, null, + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement( Text, null, - React.createElement(Spinner, {type: 'dots'}) - ), - React.createElement(Text, null, ` ${status === 'locating' ? 'Locating repository...' : 'vlurping repository...'}`) + ` ${status === 'locating' ? 'Locating repository...' : 'vlurping repository...'}` + ) ); } diff --git a/src/commands/outdated.js b/src/commands/outdated.js index 476d33b..d7fd663 100644 --- a/src/commands/outdated.js +++ b/src/commands/outdated.js @@ -1,13 +1,13 @@ -import {resolve, join} from 'node:path'; -import {readFile} from 'node:fs/promises'; -import React, {useState, useEffect} from 'react'; -import {Box, Text} from 'ink'; +import { readFile } from 'node:fs/promises'; +import { join, resolve } from 'node:path'; +import { Box, Text } from 'ink'; import Spinner from 'ink-spinner'; -import {parseVlurpfile} from '../vlurpfile.js'; -import {Fetcher} from '../remote.js'; -import {readLineage} from '../lineage.js'; +import React, { useEffect, useState } from 'react'; +import { readLineage } from '../lineage.js'; +import { Fetcher } from '../remote.js'; +import { parseVlurpfile } from '../vlurpfile.js'; -export function OutdatedCommand({vlurpfilePath}) { +export function OutdatedCommand({ vlurpfilePath }) { const [status, setStatus] = useState('checking'); const [error, setError] = useState(null); const [results, setResults] = useState([]); @@ -38,7 +38,6 @@ export function OutdatedCommand({vlurpfilePath}) { if (entry.rootDir) { const lineagePath = join(resolve(entry.rootDir), '.vlurp.jsonl'); try { - // eslint-disable-next-line no-await-in-loop const records = await readLineage(lineagePath); lineageRecords.push(...records); } catch { @@ -63,7 +62,6 @@ export function OutdatedCommand({vlurpfilePath}) { const [user, repo] = parts; - // eslint-disable-next-line no-await-in-loop const upstreamSha = await fetcher.resolveHead(user, repo); if (!upstreamSha) { outdatedResults.push({ @@ -83,7 +81,10 @@ export function OutdatedCommand({vlurpfilePath}) { upstream: shortUpstream, message: 'Not pinned — always fetches latest' }); - } else if (upstreamSha.startsWith(entry.ref) || entry.ref.startsWith(upstreamSha.slice(0, entry.ref.length))) { + } else if ( + upstreamSha.startsWith(entry.ref) || + entry.ref.startsWith(upstreamSha.slice(0, entry.ref.length)) + ) { // Compare short SHAs sensibly outdatedResults.push({ source: entry.source, @@ -117,8 +118,8 @@ export function OutdatedCommand({vlurpfilePath}) { if (status === 'error') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'red'}, `Error: ${error}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'red' }, `Error: ${error}`) ); } @@ -126,7 +127,7 @@ export function OutdatedCommand({vlurpfilePath}) { return React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement(Text, null, ' Checking upstream...') ); } @@ -138,31 +139,35 @@ export function OutdatedCommand({vlurpfilePath}) { return React.createElement( Box, - {flexDirection: 'column'}, - ...current.map(r => React.createElement( - Text, - {key: r.source, color: 'green'}, - ` ${r.source} (pinned: ${r.pinned}) ok Up to date` - )), - ...outdated.map(r => React.createElement( - Text, - {key: r.source, color: 'yellow'}, - ` ${r.source} (pinned: ${r.pinned}, upstream: ${r.upstream}) OUTDATED` - )), - ...unpinned.map(r => React.createElement( - Text, - {key: r.source, color: 'yellow'}, - ` ${r.source} (upstream: ${r.upstream}) NOT PINNED` - )), - ...errors.map(r => React.createElement( - Text, - {key: r.source, color: 'red'}, - ` ${r.source} ${r.message}` - )), + { flexDirection: 'column' }, + ...current.map(r => + React.createElement( + Text, + { key: r.source, color: 'green' }, + ` ${r.source} (pinned: ${r.pinned}) ok Up to date` + ) + ), + ...outdated.map(r => + React.createElement( + Text, + { key: r.source, color: 'yellow' }, + ` ${r.source} (pinned: ${r.pinned}, upstream: ${r.upstream}) OUTDATED` + ) + ), + ...unpinned.map(r => + React.createElement( + Text, + { key: r.source, color: 'yellow' }, + ` ${r.source} (upstream: ${r.upstream}) NOT PINNED` + ) + ), + ...errors.map(r => + React.createElement(Text, { key: r.source, color: 'red' }, ` ${r.source} ${r.message}`) + ), React.createElement(Text, null, ''), React.createElement( Text, - {bold: true, color: outdated.length > 0 || unpinned.length > 0 ? 'yellow' : 'green'}, + { bold: true, color: outdated.length > 0 || unpinned.length > 0 ? 'yellow' : 'green' }, `${current.length} current, ${outdated.length} outdated, ${unpinned.length} unpinned${errors.length > 0 ? `, ${errors.length} errors` : ''}` ) ); @@ -177,7 +182,6 @@ async function findVlurpfile(explicitPath) { for (const name of candidates) { try { const path = resolve(name); - // eslint-disable-next-line no-await-in-loop await readFile(path); return path; } catch { diff --git a/src/commands/pin.js b/src/commands/pin.js index e935d1e..ed41ef2 100644 --- a/src/commands/pin.js +++ b/src/commands/pin.js @@ -1,12 +1,12 @@ -import {resolve} from 'node:path'; -import {readFile, writeFile} from 'node:fs/promises'; -import React, {useState, useEffect} from 'react'; -import {Box, Text} from 'ink'; +import { readFile, writeFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { Box, Text } from 'ink'; import Spinner from 'ink-spinner'; -import {Fetcher} from '../remote.js'; -import {parseVlurpfile} from '../vlurpfile.js'; +import React, { useEffect, useState } from 'react'; +import { Fetcher } from '../remote.js'; +import { parseVlurpfile } from '../vlurpfile.js'; -export function PinCommand({source, vlurpfilePath}) { +export function PinCommand({ source, vlurpfilePath }) { const [status, setStatus] = useState('resolving'); const [error, setError] = useState(null); const [results, setResults] = useState([]); @@ -48,16 +48,23 @@ export function PinCommand({source, vlurpfilePath}) { for (const entry of toPin) { const parts = entry.source.split('/'); if (parts.length < 2) { - pinResults.push({source: entry.source, status: 'error', message: 'Invalid source format'}); + pinResults.push({ + source: entry.source, + status: 'error', + message: 'Invalid source format' + }); continue; } const [user, repo] = parts; - // eslint-disable-next-line no-await-in-loop const sha = await fetcher.resolveHead(user, repo); if (!sha) { - pinResults.push({source: entry.source, status: 'error', message: 'Could not resolve HEAD'}); + pinResults.push({ + source: entry.source, + status: 'error', + message: 'Could not resolve HEAD' + }); continue; } @@ -79,7 +86,7 @@ export function PinCommand({source, vlurpfilePath}) { return `${command} --ref ${shortSha}${comment}`; }); - pinResults.push({source: entry.source, status: 'pinned', sha: shortSha}); + pinResults.push({ source: entry.source, status: 'pinned', sha: shortSha }); setResults([...pinResults]); } @@ -100,8 +107,8 @@ export function PinCommand({source, vlurpfilePath}) { if (status === 'error') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'red'}, `Error: ${error}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'red' }, `Error: ${error}`) ); } @@ -109,7 +116,7 @@ export function PinCommand({source, vlurpfilePath}) { return React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement(Text, null, ' Resolving upstream HEAD...') ); } @@ -119,23 +126,19 @@ export function PinCommand({source, vlurpfilePath}) { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {bold: true}, 'Pin results:'), + { flexDirection: 'column' }, + React.createElement(Text, { bold: true }, 'Pin results:'), React.createElement(Text, null, ''), - ...pinned.map(r => React.createElement( - Text, - {key: r.source, color: 'green'}, - ` ${r.source} -> ${r.sha}` - )), - ...errors.map(r => React.createElement( - Text, - {key: r.source, color: 'red'}, - ` ${r.source}: ${r.message}` - )), + ...pinned.map(r => + React.createElement(Text, { key: r.source, color: 'green' }, ` ${r.source} -> ${r.sha}`) + ), + ...errors.map(r => + React.createElement(Text, { key: r.source, color: 'red' }, ` ${r.source}: ${r.message}`) + ), React.createElement(Text, null, ''), React.createElement( Text, - {color: errors.length > 0 ? 'yellow' : 'green'}, + { color: errors.length > 0 ? 'yellow' : 'green' }, `${pinned.length} pinned${errors.length > 0 ? `, ${errors.length} failed` : ''}` ) ); @@ -151,7 +154,6 @@ async function findVlurpfile(explicitPath) { for (const name of candidates) { try { const path = resolve(name); - // eslint-disable-next-line no-await-in-loop await readFile(path); return path; } catch { diff --git a/src/commands/scan.js b/src/commands/scan.js index 0bb0651..f22256f 100644 --- a/src/commands/scan.js +++ b/src/commands/scan.js @@ -1,11 +1,11 @@ -import {resolve, join} from 'node:path'; -import React, {useState, useEffect} from 'react'; -import {Box, Text} from 'ink'; +import { join, resolve } from 'node:path'; +import { Box, Text } from 'ink'; import Spinner from 'ink-spinner'; -import {scanDirectory, summarizeScan} from '../scanner.js'; -import {readLineage} from '../lineage.js'; +import React, { useEffect, useState } from 'react'; +import { readLineage } from '../lineage.js'; +import { scanDirectory, summarizeScan } from '../scanner.js'; -export function ScanCommand({targetPath}) { +export function ScanCommand({ targetPath }) { const [status, setStatus] = useState('scanning'); const [error, setError] = useState(null); const [fileResults, setFileResults] = useState(null); @@ -42,8 +42,8 @@ export function ScanCommand({targetPath}) { if (status === 'error') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'red'}, `Error: ${error}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'red' }, `Error: ${error}`) ); } @@ -51,7 +51,7 @@ export function ScanCommand({targetPath}) { return React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement(Text, null, ' Scanning content...') ); } @@ -62,76 +62,130 @@ export function ScanCommand({targetPath}) { // Lineage context header if (lineageInfo) { for (const record of lineageInfo) { - elements.push(React.createElement( - Text, - {key: `lineage-${record.source}`, color: 'gray'}, - `${record.source}${record.ref ? ` (pinned: ${record.ref})` : ' (not pinned)'}${record.fetched_at ? `, fetched: ${record.fetched_at.slice(0, 10)}` : ''}` - )); + elements.push( + React.createElement( + Text, + { key: `lineage-${record.source}`, color: 'gray' }, + `${record.source}${record.ref ? ` (pinned: ${record.ref})` : ' (not pinned)'}${record.fetched_at ? `, fetched: ${record.fetched_at.slice(0, 10)}` : ''}` + ) + ); } - elements.push(React.createElement(Text, {key: 'spacer-lineage'}, '')); + elements.push(React.createElement(Text, { key: 'spacer-lineage' }, '')); } // Per-file results for (const result of fileResults) { - elements.push(React.createElement(Text, {key: `file-${result.file}`, bold: true}, ` ${result.file}`)); + elements.push( + React.createElement(Text, { key: `file-${result.file}`, bold: true }, ` ${result.file}`) + ); // Injection (high severity) if (result.injection.length > 0) { for (const inj of result.injection) { - elements.push(React.createElement(Text, {key: `inj-${result.file}-${inj.label}`, color: 'red'}, ` ISSUE ${inj.label} (${inj.count} instance${inj.count > 1 ? 's' : ''})`)); + elements.push( + React.createElement( + Text, + { key: `inj-${result.file}-${inj.label}`, color: 'red' }, + ` ISSUE ${inj.label} (${inj.count} instance${inj.count > 1 ? 's' : ''})` + ) + ); } } else { - elements.push(React.createElement(Text, {key: `ok-inj-${result.file}`, color: 'green'}, ' ok No injection patterns detected')); + elements.push( + React.createElement( + Text, + { key: `ok-inj-${result.file}`, color: 'green' }, + ' ok No injection patterns detected' + ) + ); } // Exfiltration for (const exf of result.exfiltration) { - elements.push(React.createElement(Text, {key: `exf-${result.file}-${exf}`, color: 'red'}, ` ISSUE Exfiltration: ${exf}`)); + elements.push( + React.createElement( + Text, + { key: `exf-${result.file}-${exf}`, color: 'red' }, + ` ISSUE Exfiltration: ${exf}` + ) + ); } // Escalation for (const esc of result.escalation) { - elements.push(React.createElement(Text, {key: `esc-${result.file}-${esc}`, color: 'red'}, ` ISSUE Escalation: ${esc}`)); + elements.push( + React.createElement( + Text, + { key: `esc-${result.file}-${esc}`, color: 'red' }, + ` ISSUE Escalation: ${esc}` + ) + ); } // Tool references (warnings) for (const [tool, count] of Object.entries(result.tools)) { - elements.push(React.createElement(Text, {key: `tool-${result.file}-${tool}`, color: 'yellow'}, ` warn References ${tool} tool (${count} instance${count > 1 ? 's' : ''})`)); + elements.push( + React.createElement( + Text, + { key: `tool-${result.file}-${tool}`, color: 'yellow' }, + ` warn References ${tool} tool (${count} instance${count > 1 ? 's' : ''})` + ) + ); } // Persistence (warnings) for (const per of result.persistence) { - elements.push(React.createElement(Text, {key: `per-${result.file}-${per}`, color: 'yellow'}, ` warn Persistence: ${per}`)); + elements.push( + React.createElement( + Text, + { key: `per-${result.file}-${per}`, color: 'yellow' }, + ` warn Persistence: ${per}` + ) + ); } // Commands if (result.commands.size > 0) { - elements.push(React.createElement(Text, {key: `cmd-${result.file}`, color: 'yellow'}, ` warn References external commands: ${[...result.commands].join(', ')}`)); + elements.push( + React.createElement( + Text, + { key: `cmd-${result.file}`, color: 'yellow' }, + ` warn References external commands: ${[...result.commands].join(', ')}` + ) + ); } } // Summary elements.push( - React.createElement(Text, {key: 'spacer-summary'}, ''), + React.createElement(Text, { key: 'spacer-summary' }, ''), React.createElement( Text, - {key: 'summary', bold: true, color: summary.issues > 0 ? 'red' : 'green'}, + { key: 'summary', bold: true, color: summary.issues > 0 ? 'red' : 'green' }, `Summary: ${summary.files_scanned} files, ${summary.issues} issues, ${summary.warnings} warnings` ) ); if (summary.tool_surface.length > 0) { - elements.push(React.createElement(Text, {key: 'tools', color: 'gray'}, `Tool surface: ${summary.tool_surface.join(', ')}`)); + elements.push( + React.createElement( + Text, + { key: 'tools', color: 'gray' }, + `Tool surface: ${summary.tool_surface.join(', ')}` + ) + ); } if (summary.command_surface.length > 0) { - elements.push(React.createElement(Text, {key: 'commands', color: 'gray'}, `Command surface: ${summary.command_surface.join(', ')}`)); + elements.push( + React.createElement( + Text, + { key: 'commands', color: 'gray' }, + `Command surface: ${summary.command_surface.join(', ')}` + ) + ); } - return React.createElement( - Box, - {flexDirection: 'column'}, - ...elements - ); + return React.createElement(Box, { flexDirection: 'column' }, ...elements); } diff --git a/src/commands/upgrade.js b/src/commands/upgrade.js index 1ad67f1..c820a3b 100644 --- a/src/commands/upgrade.js +++ b/src/commands/upgrade.js @@ -1,16 +1,16 @@ +import { readFile, rename, writeFile } from 'node:fs/promises'; +import { join, resolve } from 'node:path'; import process from 'node:process'; -import {readFile, writeFile, rename} from 'node:fs/promises'; -import {resolve, join} from 'node:path'; -import React, {useState, useEffect} from 'react'; -import {Box, Text} from 'ink'; +import { Box, Text } from 'ink'; import Spinner from 'ink-spinner'; -import {parseVlurpfile, updateRefs} from '../vlurpfile.js'; -import {parseSource, fetchRepository, Fetcher} from '../remote.js'; -import {hashDirectory, createLineageRecord, appendLineage} from '../lineage.js'; -import {buildCatalog} from '../catalog.js'; -import {diffCatalogs, formatCatalogDiff} from '../catalog-diff.js'; - -export function UpgradeCommand({vlurpfilePath, source, dryRun}) { +import React, { useEffect, useState } from 'react'; +import { buildCatalog } from '../catalog.js'; +import { diffCatalogs, formatCatalogDiff } from '../catalog-diff.js'; +import { appendLineage, createLineageRecord, hashDirectory } from '../lineage.js'; +import { Fetcher, fetchRepository, parseSource } from '../remote.js'; +import { parseVlurpfile, updateRefs } from '../vlurpfile.js'; + +export function UpgradeCommand({ vlurpfilePath, source, dryRun }) { const [status, setStatus] = useState('resolving'); const [error, setError] = useState(null); const [results, setResults] = useState([]); @@ -21,8 +21,14 @@ export function UpgradeCommand({vlurpfilePath, source, dryRun}) { async function performUpgrade() { try { await runUpgrade({ - vlurpfilePath, source, dryRun, - setStatus, setError, setResults, setCurrentSource, setSummary + vlurpfilePath, + source, + dryRun, + setStatus, + setError, + setResults, + setCurrentSource, + setSummary }); } catch (err) { setError(err.message); @@ -36,8 +42,8 @@ export function UpgradeCommand({vlurpfilePath, source, dryRun}) { if (status === 'error') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'red'}, `Error: ${error}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'red' }, `Error: ${error}`) ); } @@ -45,10 +51,12 @@ export function UpgradeCommand({vlurpfilePath, source, dryRun}) { return React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), - React.createElement(Text, null, currentSource - ? ` Checking ${currentSource}...` - : ' Reading vlurpfile...') + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), + React.createElement( + Text, + null, + currentSource ? ` Checking ${currentSource}...` : ' Reading vlurpfile...' + ) ); } @@ -69,8 +77,14 @@ export function UpgradeCommand({vlurpfilePath, source, dryRun}) { async function runUpgrade(options) { const { - vlurpfilePath, source, dryRun, - setStatus, setError, setResults, setCurrentSource, setSummary + vlurpfilePath, + source, + dryRun, + setStatus, + setError, + setResults, + setCurrentSource, + setSummary } = options; // Step 1: Find and read vlurpfile @@ -91,9 +105,7 @@ async function runUpgrade(options) { } // Filter to specific source if given - const targetEntries = source - ? entries.filter(e => e.source === source) - : entries; + const targetEntries = source ? entries.filter(e => e.source === source) : entries; if (source && targetEntries.length === 0) { setError(`Source "${source}" not found in vlurpfile`); @@ -115,8 +127,13 @@ async function runUpgrade(options) { setStatus('checking'); const fetcher = new Fetcher(); const upgradeResults = await checkAndUpgradeSources({ - sourceMap, fetcher, dryRun, entries, - setCurrentSource, setResults, setStatus + sourceMap, + fetcher, + dryRun, + entries, + setCurrentSource, + setResults, + setStatus }); // Step 5: Rewrite .vlurpfile with new refs @@ -146,10 +163,7 @@ async function runUpgrade(options) { } async function checkAndUpgradeSources(options) { - const { - sourceMap, fetcher, dryRun, entries, - setCurrentSource, setResults, setStatus - } = options; + const { sourceMap, fetcher, dryRun, entries, setCurrentSource, setResults, setStatus } = options; const upgradeResults = []; // Collect rootDirs for catalog snapshot @@ -159,29 +173,36 @@ async function checkAndUpgradeSources(options) { setCurrentSource(src); const parts = src.split('/'); if (parts.length < 2) { - upgradeResults.push({source: src, status: 'error', message: 'Invalid source format'}); + upgradeResults.push({ source: src, status: 'error', message: 'Invalid source format' }); setResults([...upgradeResults]); continue; } const [user, repo] = parts; - // eslint-disable-next-line no-await-in-loop -- Sequential for API rate limits const upstreamSha = await fetcher.resolveHead(user, repo); if (!upstreamSha) { - upgradeResults.push({source: src, status: 'error', message: 'Could not resolve upstream HEAD'}); + upgradeResults.push({ + source: src, + status: 'error', + message: 'Could not resolve upstream HEAD' + }); setResults([...upgradeResults]); continue; } const pinnedRef = srcEntries[0].ref; - const isCurrent = pinnedRef - && (upstreamSha.startsWith(pinnedRef) || pinnedRef.startsWith(upstreamSha.slice(0, pinnedRef.length))); + const isCurrent = + pinnedRef && + (upstreamSha.startsWith(pinnedRef) || + pinnedRef.startsWith(upstreamSha.slice(0, pinnedRef.length))); if (isCurrent) { upgradeResults.push({ - source: src, status: 'current', - ref: pinnedRef, upstream: upstreamSha.slice(0, 7) + source: src, + status: 'current', + ref: pinnedRef, + upstream: upstreamSha.slice(0, 7) }); setResults([...upgradeResults]); continue; @@ -189,8 +210,10 @@ async function checkAndUpgradeSources(options) { if (dryRun) { upgradeResults.push({ - source: src, status: 'outdated', - ref: pinnedRef || null, upstream: upstreamSha.slice(0, 7), + source: src, + status: 'outdated', + ref: pinnedRef || null, + upstream: upstreamSha.slice(0, 7), entries: srcEntries.length }); setResults([...upgradeResults]); @@ -198,22 +221,18 @@ async function checkAndUpgradeSources(options) { } // Step 3: Snapshot pre-upgrade catalog (once, before first fetch) - // eslint-disable-next-line no-await-in-loop const preCatalog = await snapshotCatalogs(rootDirs, setStatus, setCurrentSource); // Fetch each entry for this source with the new ref setStatus('upgrading'); const shortSha = upstreamSha.slice(0, 7); - // eslint-disable-next-line no-await-in-loop const fetchedAll = await fetchSourceEntries(srcEntries, upstreamSha, setCurrentSource); // Step 4: Snapshot post-upgrade catalog and diff - // eslint-disable-next-line no-await-in-loop const postCatalog = await snapshotCatalogs(rootDirs, setStatus, setCurrentSource); const catalogDiff = diffCatalogs(preCatalog, postCatalog); // Save catalog.prev.json and catalog.json - // eslint-disable-next-line no-await-in-loop await saveCatalogs(rootDirs, preCatalog, postCatalog); upgradeResults.push({ @@ -246,10 +265,9 @@ async function snapshotCatalogs(rootDirs, setStatus, setCurrentSource) { setCurrentSource('building catalog...'); // Merge catalogs from all rootDirs into one - const merged = {skills: {}}; + const merged = { skills: {} }; for (const dir of rootDirs) { try { - // eslint-disable-next-line no-await-in-loop const catalog = await buildCatalog(dir); Object.assign(merged.skills, catalog.skills); } catch { @@ -267,13 +285,11 @@ async function saveCatalogs(rootDirs, preCatalog, postCatalog) { // Rotate existing catalog.json to catalog.prev.json try { - // eslint-disable-next-line no-await-in-loop await rename(catalogPath, prevPath); } catch { // No existing catalog.json — write prev from snapshot try { - // eslint-disable-next-line no-await-in-loop - await writeFile(prevPath, JSON.stringify(preCatalog, null, 2) + '\n'); + await writeFile(prevPath, `${JSON.stringify(preCatalog, null, 2)}\n`); } catch { // Write failure is non-fatal } @@ -281,8 +297,7 @@ async function saveCatalogs(rootDirs, preCatalog, postCatalog) { // Write new catalog.json try { - // eslint-disable-next-line no-await-in-loop - await writeFile(catalogPath, JSON.stringify(postCatalog, null, 2) + '\n'); + await writeFile(catalogPath, `${JSON.stringify(postCatalog, null, 2)}\n`); } catch { // Write failure is non-fatal } @@ -295,13 +310,12 @@ async function fetchSourceEntries(srcEntries, upstreamSha, setCurrentSource) { for (const entry of srcEntries) { setCurrentSource(`${entry.source}${entry.as ? ` (${entry.as})` : ''}`); try { - const parsed = parseSource(entry.source, {ref: upstreamSha}); - const targetPath = entry.targetPath || resolve(entry.rootDir || '.', parsed.user, parsed.repo); + const parsed = parseSource(entry.source, { ref: upstreamSha }); + const targetPath = + entry.targetPath || resolve(entry.rootDir || '.', parsed.user, parsed.repo); - // eslint-disable-next-line no-await-in-loop - await fetchRepository(parsed.tarballUrl, targetPath, entry.filters, {force: true}); + await fetchRepository(parsed.tarballUrl, targetPath, entry.filters, { force: true }); - // eslint-disable-next-line no-await-in-loop const files = await hashDirectory(targetPath); const lineageRecord = createLineageRecord({ source: `${parsed.user}/${parsed.repo}`, @@ -315,7 +329,6 @@ async function fetchSourceEntries(srcEntries, upstreamSha, setCurrentSource) { const lineageDir = entry.rootDir ? resolve(entry.rootDir) : process.cwd(); const lineagePath = join(lineageDir, '.vlurp.jsonl'); - // eslint-disable-next-line no-await-in-loop await appendLineage(lineagePath, lineageRecord); } catch { fetchedAll = false; @@ -329,103 +342,124 @@ function renderUpgrading(currentSource, results, status) { const label = status === 'cataloging' ? 'Building catalog...' : `Upgrading ${currentSource}...`; return React.createElement( Box, - {flexDirection: 'column'}, + { flexDirection: 'column' }, React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement(Text, null, ` ${label}`) ), - ...results.filter(r => r.status !== 'current').slice(-5).map((r, i) => - React.createElement( - Text, - {key: i, color: r.status === 'upgraded' ? 'green' : (r.status === 'error' ? 'red' : 'yellow')}, - ` ${statusIcon(r.status)} ${r.source} ${r.ref || ''} -> ${r.upstream || r.newRef || ''}` - )) + ...results + .filter(r => r.status !== 'current') + .slice(-5) + .map((r, i) => + React.createElement( + Text, + { + key: i, + color: r.status === 'upgraded' ? 'green' : r.status === 'error' ? 'red' : 'yellow' + }, + ` ${statusIcon(r.status)} ${r.source} ${r.ref || ''} -> ${r.upstream || r.newRef || ''}` + ) + ) ); } function renderDryRunComplete(summary) { - const {outdated, current, errors} = summary; + const { outdated, current, errors } = summary; const hasChanges = outdated.length > 0; return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'yellow', bold: true}, 'Dry run — would upgrade:\n'), - ...outdated.map(r => React.createElement( - Text, - {key: r.source, color: 'yellow'}, - ` ${r.source} ${r.ref || '(unpinned)'} -> ${r.upstream}${r.entries > 1 ? ` (${r.entries} entries)` : ''}` - )), - ...current.map(r => React.createElement( - Text, - {key: r.source, color: 'green'}, - ` ${r.source} ${r.ref} up to date` - )), - ...errors.map(r => React.createElement( - Text, - {key: r.source, color: 'red'}, - ` ${r.source} ${r.message}` - )), + { flexDirection: 'column' }, + React.createElement(Text, { color: 'yellow', bold: true }, 'Dry run — would upgrade:\n'), + ...outdated.map(r => + React.createElement( + Text, + { key: r.source, color: 'yellow' }, + ` ${r.source} ${r.ref || '(unpinned)'} -> ${r.upstream}${r.entries > 1 ? ` (${r.entries} entries)` : ''}` + ) + ), + ...current.map(r => + React.createElement( + Text, + { key: r.source, color: 'green' }, + ` ${r.source} ${r.ref} up to date` + ) + ), + ...errors.map(r => + React.createElement(Text, { key: r.source, color: 'red' }, ` ${r.source} ${r.message}`) + ), React.createElement(Text, null, ''), React.createElement( Text, - {bold: true, color: hasChanges ? 'yellow' : 'green'}, + { bold: true, color: hasChanges ? 'yellow' : 'green' }, `${outdated.length} to upgrade, ${current.length} current${errors.length > 0 ? `, ${errors.length} errors` : ''}` ), - hasChanges && React.createElement(Text, {color: 'gray', marginTop: 1}, '\nRun without --dry-run to apply.') + hasChanges && + React.createElement( + Text, + { color: 'gray', marginTop: 1 }, + '\nRun without --dry-run to apply.' + ) ); } function renderComplete(summary) { - const {upgraded, current, errors, catalogDiff} = summary; + const { upgraded, current, errors, catalogDiff } = summary; const elements = [ - ...upgraded.map(r => React.createElement( - Text, - {key: r.source, color: 'green'}, - ` ${r.source} ${r.ref || '(unpinned)'} -> ${r.newRef}${r.entries > 1 ? ` (${r.entries} entries)` : ''}` - )), - ...current.map(r => React.createElement( - Text, - {key: r.source, color: 'green'}, - ` ${r.source} ${r.ref} up to date` - )), - ...errors.map(r => React.createElement( - Text, - {key: r.source, color: 'red'}, - ` ${r.source} ${r.message}` - )), - React.createElement(Text, {key: '_blank1'}, ''), + ...upgraded.map(r => + React.createElement( + Text, + { key: r.source, color: 'green' }, + ` ${r.source} ${r.ref || '(unpinned)'} -> ${r.newRef}${r.entries > 1 ? ` (${r.entries} entries)` : ''}` + ) + ), + ...current.map(r => + React.createElement( + Text, + { key: r.source, color: 'green' }, + ` ${r.source} ${r.ref} up to date` + ) + ), + ...errors.map(r => + React.createElement(Text, { key: r.source, color: 'red' }, ` ${r.source} ${r.message}`) + ), + React.createElement(Text, { key: '_blank1' }, ''), React.createElement( Text, - {key: '_summary', bold: true, color: errors.length > 0 ? 'yellow' : 'green'}, + { key: '_summary', bold: true, color: errors.length > 0 ? 'yellow' : 'green' }, `${upgraded.length} upgraded, ${current.length} current${errors.length > 0 ? `, ${errors.length} errors` : ''}` ) ]; // Append catalog diff if available and has changes - const hasSkillChanges = catalogDiff - && (catalogDiff.summary.new > 0 || catalogDiff.summary.removed > 0 || catalogDiff.summary.changed > 0); + const hasSkillChanges = + catalogDiff && + (catalogDiff.summary.new > 0 || + catalogDiff.summary.removed > 0 || + catalogDiff.summary.changed > 0); if (hasSkillChanges) { const diffElements = [ - React.createElement(Text, {key: '_blank2'}, ''), - React.createElement(Text, {key: '_diffheader', bold: true}, 'What changed:'), - React.createElement(Text, {key: '_diff'}, formatCatalogDiff(catalogDiff)) + React.createElement(Text, { key: '_blank2' }, ''), + React.createElement(Text, { key: '_diffheader', bold: true }, 'What changed:'), + React.createElement(Text, { key: '_diff' }, formatCatalogDiff(catalogDiff)) ]; elements.push(...diffElements); } if (upgraded.length > 0) { - elements.push(React.createElement(Text, {key: '_refs', color: 'gray'}, ' .vlurpfile updated with new refs')); + elements.push( + React.createElement( + Text, + { key: '_refs', color: 'gray' }, + ' .vlurpfile updated with new refs' + ) + ); } - return React.createElement( - Box, - {flexDirection: 'column'}, - ...elements - ); + return React.createElement(Box, { flexDirection: 'column' }, ...elements); } function statusIcon(s) { @@ -461,7 +495,6 @@ async function findVlurpfile(explicitPath) { for (const name of candidates) { try { const path = resolve(name); - // eslint-disable-next-line no-await-in-loop await readFile(path); return path; } catch { diff --git a/src/commands/verify.js b/src/commands/verify.js index 18185a6..6c74e69 100644 --- a/src/commands/verify.js +++ b/src/commands/verify.js @@ -1,10 +1,10 @@ -import {resolve, join} from 'node:path'; -import React, {useState, useEffect} from 'react'; -import {Box, Text} from 'ink'; +import { join, resolve } from 'node:path'; +import { Box, Text } from 'ink'; import Spinner from 'ink-spinner'; -import {readLineage, verifyFiles} from '../lineage.js'; +import React, { useEffect, useState } from 'react'; +import { readLineage, verifyFiles } from '../lineage.js'; -export function VerifyCommand({targetPath}) { +export function VerifyCommand({ targetPath }) { const [status, setStatus] = useState('verifying'); const [error, setError] = useState(null); const [results, setResults] = useState(null); @@ -37,8 +37,8 @@ export function VerifyCommand({targetPath}) { if (status === 'error') { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement(Text, {color: 'red'}, `Error: ${error}`) + { flexDirection: 'column' }, + React.createElement(Text, { color: 'red' }, `Error: ${error}`) ); } @@ -46,7 +46,7 @@ export function VerifyCommand({targetPath}) { return React.createElement( Box, null, - React.createElement(Text, null, React.createElement(Spinner, {type: 'dots'})), + React.createElement(Text, null, React.createElement(Spinner, { type: 'dots' })), React.createElement(Text, null, ' Verifying file integrity...') ); } @@ -59,37 +59,37 @@ export function VerifyCommand({targetPath}) { return React.createElement( Box, - {flexDirection: 'column'}, - React.createElement( - Text, - {bold: true}, - `Verify: ${resolve(targetPath)}` - ), + { flexDirection: 'column' }, + React.createElement(Text, { bold: true }, `Verify: ${resolve(targetPath)}`), React.createElement(Text, null, ''), - ...ok.map(r => React.createElement( - Text, - {key: r.file, color: 'green'}, - ` ${r.file.padEnd(50)} ok (sha256: ${r.expected.slice(0, 8)}...)` - )), - ...modified.map(r => React.createElement( - Text, - {key: r.file, color: 'red'}, - ` ${r.file.padEnd(50)} MODIFIED (expected: ${r.expected.slice(0, 8)}..., actual: ${r.actual.slice(0, 8)}...)` - )), - ...missing.map(r => React.createElement( - Text, - {key: r.file, color: 'red'}, - ` ${r.file.padEnd(50)} MISSING` - )), - ...untracked.map(r => React.createElement( - Text, - {key: r.file, color: 'gray'}, - ` ${r.file.padEnd(50)} no lineage (local file)` - )), + ...ok.map(r => + React.createElement( + Text, + { key: r.file, color: 'green' }, + ` ${r.file.padEnd(50)} ok (sha256: ${r.expected.slice(0, 8)}...)` + ) + ), + ...modified.map(r => + React.createElement( + Text, + { key: r.file, color: 'red' }, + ` ${r.file.padEnd(50)} MODIFIED (expected: ${r.expected.slice(0, 8)}..., actual: ${r.actual.slice(0, 8)}...)` + ) + ), + ...missing.map(r => + React.createElement(Text, { key: r.file, color: 'red' }, ` ${r.file.padEnd(50)} MISSING`) + ), + ...untracked.map(r => + React.createElement( + Text, + { key: r.file, color: 'gray' }, + ` ${r.file.padEnd(50)} no lineage (local file)` + ) + ), React.createElement(Text, null, ''), React.createElement( Text, - {color: hasIssues ? 'red' : 'green', bold: true}, + { color: hasIssues ? 'red' : 'green', bold: true }, hasIssues ? `${modified.length} modified, ${missing.length} missing, ${ok.length} ok, ${untracked.length} untracked` : `All ${ok.length} tracked files verified${untracked.length > 0 ? ` (${untracked.length} untracked)` : ''}` diff --git a/src/detector.js b/src/detector.js index 4d12897..d45474b 100644 --- a/src/detector.js +++ b/src/detector.js @@ -1,4 +1,4 @@ -import {request} from 'undici'; +import { request } from 'undici'; /** * Structure detection patterns and their associated filters. @@ -64,7 +64,7 @@ const STRUCTURE_PATTERNS = [ async function fetchRepoTree(user, repo) { try { const url = `https://api.github.com/repos/${user}/${repo}/git/trees/HEAD?recursive=1`; - const {statusCode, body} = await request(url, { + const { statusCode, body } = await request(url, { headers: { 'User-Agent': 'vlurp-cli', Accept: 'application/vnd.github.v3+json' diff --git a/src/index.js b/src/index.js index 2b6cf0e..01421ee 100644 --- a/src/index.js +++ b/src/index.js @@ -1,29 +1,29 @@ +export { buildCatalog } from './catalog.js'; export { - Validator, - validateUrl, - Parser, - parseSource, - Fetcher, - fetchRepository -} from './remote.js'; -export {PRESETS} from './presets.js'; -export {parseVlurpfile, updateRef, updateRefs} from './vlurpfile.js'; -export {detectStructure} from './detector.js'; + diffCatalogs, + formatCatalogDiff +} from './catalog-diff.js'; +export { detectStructure } from './detector.js'; export { - hashFile, - hashDirectory, - createLineageRecord, appendLineage, + createLineageRecord, + hashDirectory, + hashFile, readLineage, verifyFiles } from './lineage.js'; +export { PRESETS } from './presets.js'; +export { + Fetcher, + fetchRepository, + Parser, + parseSource, + Validator, + validateUrl +} from './remote.js'; export { - scanFileContent, scanDirectory, + scanFileContent, summarizeScan } from './scanner.js'; -export {buildCatalog} from './catalog.js'; -export { - diffCatalogs, - formatCatalogDiff -} from './catalog-diff.js'; +export { parseVlurpfile, updateRef, updateRefs } from './vlurpfile.js'; diff --git a/src/lineage.js b/src/lineage.js index 2f1ec97..9862203 100644 --- a/src/lineage.js +++ b/src/lineage.js @@ -1,8 +1,6 @@ -import {createHash} from 'node:crypto'; -import { - readFile, writeFile, readdir -} from 'node:fs/promises'; -import {join, relative} from 'node:path'; +import { createHash } from 'node:crypto'; +import { readdir, readFile, writeFile } from 'node:fs/promises'; +import { join, relative } from 'node:path'; /** * Compute SHA-256 hash of a file's contents. @@ -11,7 +9,7 @@ export async function hashFile(filePath) { const content = await readFile(filePath); const hash = createHash('sha256').update(content).digest('hex'); const size = content.length; - return {sha256: hash, size}; + return { sha256: hash, size }; } /** @@ -22,17 +20,15 @@ export async function hashDirectory(dirPath) { const files = {}; async function walk(dir) { - const entries = await readdir(dir, {withFileTypes: true}); + const entries = await readdir(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = join(dir, entry.name); if (entry.isDirectory()) { - // eslint-disable-next-line no-await-in-loop await walk(fullPath); } else { const relPath = relative(dirPath, fullPath); - // eslint-disable-next-line no-await-in-loop - const {sha256, size} = await hashFile(fullPath); - files[relPath] = {sha256, size}; + const { sha256, size } = await hashFile(fullPath); + files[relPath] = { sha256, size }; } } } @@ -44,12 +40,12 @@ export async function hashDirectory(dirPath) { /** * Create a lineage record for a fetch operation. */ -export function createLineageRecord({source, ref, refType, filters, preset, asName, files}) { +export function createLineageRecord({ source, ref, refType, filters, preset, asName, files }) { return { source: `github:${source}`, ref: ref || null, - ref_type: refType || (ref ? 'commit' : null), // eslint-disable-line camelcase - fetched_at: new Date().toISOString(), // eslint-disable-line camelcase + ref_type: refType || (ref ? 'commit' : null), + fetched_at: new Date().toISOString(), filters: filters || [], preset: preset || null, as: asName || null, @@ -81,7 +77,7 @@ export async function appendLineage(jsonlPath, record) { }); filtered.push(JSON.stringify(record)); - await writeFile(jsonlPath, filtered.join('\n') + '\n'); + await writeFile(jsonlPath, `${filtered.join('\n')}\n`); } /** @@ -144,20 +140,28 @@ export async function verifyFiles(basePath, records) { for (const [relPath, expected] of tracked) { const fullPath = join(basePath, relPath); try { - // eslint-disable-next-line no-await-in-loop - const {sha256} = await hashFile(fullPath); + const { sha256 } = await hashFile(fullPath); if (sha256 === expected.sha256) { results.push({ - file: relPath, status: 'ok', expected: expected.sha256, actual: sha256 + file: relPath, + status: 'ok', + expected: expected.sha256, + actual: sha256 }); } else { results.push({ - file: relPath, status: 'modified', expected: expected.sha256, actual: sha256 + file: relPath, + status: 'modified', + expected: expected.sha256, + actual: sha256 }); } } catch { results.push({ - file: relPath, status: 'missing', expected: expected.sha256, actual: null + file: relPath, + status: 'missing', + expected: expected.sha256, + actual: null }); } } @@ -173,7 +177,10 @@ export async function verifyFiles(basePath, records) { if (!tracked.has(relPath)) { results.push({ - file: relPath, status: 'untracked', expected: null, actual: diskFiles[relPath].sha256 + file: relPath, + status: 'untracked', + expected: null, + actual: diskFiles[relPath].sha256 }); } } diff --git a/src/presets.js b/src/presets.js index 31144b4..e5bddb8 100644 --- a/src/presets.js +++ b/src/presets.js @@ -16,24 +16,11 @@ export const PRESETS = { }, skills: { description: 'Agent skills (skills/**, SKILL.md)', - filters: [ - 'skills/**', - 'SKILL.md', - '**/*.md', - '!README.md', - '!LICENSE*', - '!CONTRIBUTING.md' - ] + filters: ['skills/**', 'SKILL.md', '**/*.md', '!README.md', '!LICENSE*', '!CONTRIBUTING.md'] }, agents: { description: 'Agent definitions (agents/**, commands/**)', - filters: [ - 'agents/**', - 'commands/**', - '**/*.md', - '!README.md', - '!LICENSE*' - ] + filters: ['agents/**', 'commands/**', '**/*.md', '!README.md', '!LICENSE*'] }, docs: { description: 'Documentation only (**/*.md, excluding boilerplate)', diff --git a/src/remote.js b/src/remote.js index be57078..dff8108 100644 --- a/src/remote.js +++ b/src/remote.js @@ -1,22 +1,20 @@ -import { - access, mkdir, readdir, cp, rm -} from 'node:fs/promises'; -import {dirname, join} from 'node:path'; -import {constants, createWriteStream} from 'node:fs'; -import {pipeline} from 'node:stream/promises'; -import {tmpdir} from 'node:os'; -import {randomBytes} from 'node:crypto'; -import {createInterface} from 'node:readline'; +import { randomBytes } from 'node:crypto'; +import { constants, createWriteStream } from 'node:fs'; +import { access, cp, mkdir, readdir, rm } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { dirname, join } from 'node:path'; import process from 'node:process'; -import {extract} from 'tar'; -import {request} from 'undici'; -import {glob} from 'glob'; +import { createInterface } from 'node:readline'; +import { pipeline } from 'node:stream/promises'; +import { glob } from 'glob'; import hostedGitInfo from 'hosted-git-info'; +import { extract } from 'tar'; +import { request } from 'undici'; // --- Parsing --- export class Parser { - parse(source, {ref} = {}) { + parse(source, { ref } = {}) { // Try to parse with hosted-git-info const info = hostedGitInfo.fromUrl(source); @@ -106,7 +104,7 @@ export class Fetcher { try { await access(dir, constants.F_OK); } catch { - await mkdir(dir, {recursive: true}); + await mkdir(dir, { recursive: true }); } } @@ -122,7 +120,7 @@ export class Fetcher { async #downloadTarball(url) { const temporaryFile = join(tmpdir(), `vlurp-${randomBytes(8).toString('hex')}.tar.gz`); - const {statusCode, body} = await request(url, { + const { statusCode, body } = await request(url, { headers: { 'User-Agent': 'vlurp-cli' }, @@ -145,7 +143,7 @@ export class Fetcher { // Extract to a temp directory first const temporaryExtractDir = join(tmpdir(), `vlurp-extract-${randomBytes(8).toString('hex')}`); - await mkdir(temporaryExtractDir, {recursive: true}); + await mkdir(temporaryExtractDir, { recursive: true }); // Extract everything first await extract({ @@ -156,15 +154,12 @@ export class Fetcher { // If no filters provided, copy everything if (!filters || filters.length === 0) { - await cp(temporaryExtractDir, targetPath, {recursive: true}); + await cp(temporaryExtractDir, targetPath, { recursive: true }); } else { // Separate positive and negative patterns - const ignorePatterns = filters - .filter(p => p.startsWith('!')) - .map(p => p.slice(1)); // Remove the ! prefix + const ignorePatterns = filters.filter(p => p.startsWith('!')).map(p => p.slice(1)); // Remove the ! prefix - const includePatterns = filters - .filter(p => !p.startsWith('!')); + const includePatterns = filters.filter(p => !p.startsWith('!')); // If no positive patterns, include everything by default const patterns = includePatterns.length > 0 ? includePatterns : ['**/*']; @@ -178,7 +173,7 @@ export class Fetcher { }); // Create target directory - await mkdir(targetPath, {recursive: true}); + await mkdir(targetPath, { recursive: true }); // Copy matched files maintaining directory structure @@ -187,22 +182,20 @@ export class Fetcher { const destPath = join(targetPath, file); // Ensure parent directory exists - // eslint-disable-next-line no-await-in-loop - await mkdir(dirname(destPath), {recursive: true}); + await mkdir(dirname(destPath), { recursive: true }); // Copy file or directory - // eslint-disable-next-line no-await-in-loop - await cp(sourcePath, destPath, {recursive: true}); + await cp(sourcePath, destPath, { recursive: true }); } } // Clean up temp directory - await rm(temporaryExtractDir, {recursive: true, force: true}); + await rm(temporaryExtractDir, { recursive: true, force: true }); } async countFiles(dir) { try { - const files = await readdir(dir, {recursive: true}); + const files = await readdir(dir, { recursive: true }); return files.length; } catch { return 0; @@ -241,7 +234,7 @@ export class Fetcher { } // Remove existing directory before proceeding - await rm(targetPath, {recursive: true, force: true}); + await rm(targetPath, { recursive: true, force: true }); } let temporaryTarball; @@ -254,8 +247,8 @@ export class Fetcher { } finally { // Clean up temp file if (temporaryTarball) { - const {unlink} = await import('node:fs/promises'); - await unlink(temporaryTarball, {force: true}); + const { unlink } = await import('node:fs/promises'); + await unlink(temporaryTarball, { force: true }); } } } @@ -264,11 +257,14 @@ export class Fetcher { * Resolve the HEAD SHA for a GitHub repository. */ async resolveHead(user, repo) { - const {statusCode, headers, body} = await request(`https://api.github.com/repos/${user}/${repo}/tarball`, { - method: 'HEAD', - headers: {'User-Agent': 'vlurp-cli'}, - maxRedirections: 0 - }); + const { statusCode, headers, body } = await request( + `https://api.github.com/repos/${user}/${repo}/tarball`, + { + method: 'HEAD', + headers: { 'User-Agent': 'vlurp-cli' }, + maxRedirections: 0 + } + ); // Consume body to prevent leak await body.dump(); @@ -277,20 +273,24 @@ export class Fetcher { if (statusCode === 302 || statusCode === 301) { const location = headers.location || ''; // URL format: .../{user}-{repo}-{sha}.tar.gz - const match = /\/([a-f\d]{40}|[a-f\d]{7,})\.tar\.gz/i.exec(location) - || /\/tarball\/([a-f\d]{7,})/i.exec(location); + const match = + /\/([a-f\d]{40}|[a-f\d]{7,})\.tar\.gz/i.exec(location) || + /\/tarball\/([a-f\d]{7,})/i.exec(location); if (match) { return match[1]; } } // Fallback: use the git refs API - const {statusCode: refStatus, body: refBody} = await request(`https://api.github.com/repos/${user}/${repo}/git/ref/heads/main`, { - headers: { - 'User-Agent': 'vlurp-cli', - Accept: 'application/vnd.github.v3+json' + const { statusCode: refStatus, body: refBody } = await request( + `https://api.github.com/repos/${user}/${repo}/git/ref/heads/main`, + { + headers: { + 'User-Agent': 'vlurp-cli', + Accept: 'application/vnd.github.v3+json' + } } - }); + ); if (refStatus === 200) { const data = await refBody.json(); @@ -300,12 +300,15 @@ export class Fetcher { await refBody.dump(); // Try master branch - const {statusCode: masterStatus, body: masterBody} = await request(`https://api.github.com/repos/${user}/${repo}/git/ref/heads/master`, { - headers: { - 'User-Agent': 'vlurp-cli', - Accept: 'application/vnd.github.v3+json' + const { statusCode: masterStatus, body: masterBody } = await request( + `https://api.github.com/repos/${user}/${repo}/git/ref/heads/master`, + { + headers: { + 'User-Agent': 'vlurp-cli', + Accept: 'application/vnd.github.v3+json' + } } - }); + ); if (masterStatus === 200) { const data = await masterBody.json(); @@ -323,5 +326,5 @@ export async function fetchRepository(tarballUrl, targetPath, filters = [], opti // Return file count for the component to display const fileCount = await fetcher.countFiles(targetPath); - return {fileCount}; + return { fileCount }; } diff --git a/src/scanner.js b/src/scanner.js index 8975bb6..2ea61e1 100644 --- a/src/scanner.js +++ b/src/scanner.js @@ -1,69 +1,78 @@ -import {readFile, readdir} from 'node:fs/promises'; -import {join, relative, extname} from 'node:path'; +import { readdir, readFile } from 'node:fs/promises'; +import { extname, join, relative } from 'node:path'; /** * Known prompt injection patterns. */ const INJECTION_PATTERNS = [ - {pattern: /ignore\s+(all\s+)?previous\s+instructions/i, label: 'Prompt override: "ignore previous instructions"'}, - {pattern: /you\s+are\s+now\s+/i, label: 'Prompt override: "you are now"'}, - {pattern: /new\s+instructions?\s*:/i, label: 'Prompt override: "new instructions:"'}, - {pattern: /system\s+prompt\s*:/i, label: 'Prompt override: "system prompt:"'}, - {pattern: /forget\s+(everything|all|your)\s/i, label: 'Prompt override: "forget everything"'}, - {pattern: /disregard\s+(all\s+)?(previous|prior|above)/i, label: 'Prompt override: "disregard previous"'} + { + pattern: /ignore\s+(all\s+)?previous\s+instructions/i, + label: 'Prompt override: "ignore previous instructions"' + }, + { pattern: /you\s+are\s+now\s+/i, label: 'Prompt override: "you are now"' }, + { pattern: /new\s+instructions?\s*:/i, label: 'Prompt override: "new instructions:"' }, + { pattern: /system\s+prompt\s*:/i, label: 'Prompt override: "system prompt:"' }, + { pattern: /forget\s+(everything|all|your)\s/i, label: 'Prompt override: "forget everything"' }, + { + pattern: /disregard\s+(all\s+)?(previous|prior|above)/i, + label: 'Prompt override: "disregard previous"' + } ]; /** * Tool references to detect. */ const TOOL_PATTERNS = [ - {pattern: /\bBash\b/, label: 'Bash'}, - {pattern: /\bRead\b(?=\s+tool|\s+to\s+read)/, label: 'Read'}, - {pattern: /\bWrite\b(?=\s+tool|\s+to\s+write)/, label: 'Write'}, - {pattern: /\bEdit\b(?=\s+tool|\s+to\s+edit)/, label: 'Edit'}, - {pattern: /\bWebFetch\b/, label: 'WebFetch'}, - {pattern: /\bWebSearch\b/, label: 'WebSearch'} + { pattern: /\bBash\b/, label: 'Bash' }, + { pattern: /\bRead\b(?=\s+tool|\s+to\s+read)/, label: 'Read' }, + { pattern: /\bWrite\b(?=\s+tool|\s+to\s+write)/, label: 'Write' }, + { pattern: /\bEdit\b(?=\s+tool|\s+to\s+edit)/, label: 'Edit' }, + { pattern: /\bWebFetch\b/, label: 'WebFetch' }, + { pattern: /\bWebSearch\b/, label: 'WebSearch' } ]; /** * Exfiltration patterns. */ const EXFILTRATION_PATTERNS = [ - {pattern: /curl\s+.*?-d\s/i, label: 'curl POST data'}, - {pattern: /curl\s+.*?--data/i, label: 'curl POST data'}, - {pattern: /wget\s+.*?--post/i, label: 'wget POST'}, - {pattern: /fetch\s*\(.*?method\s*:\s*['"]post/i, label: 'fetch POST'}, - {pattern: /\.env\b/i, label: 'References .env file'}, - {pattern: /credentials?\.(json|yml|yaml|toml)/i, label: 'References credentials file'}, - {pattern: /api[_-]?key/i, label: 'References API key'}, - {pattern: /send\s+(file|content|data)\s+to\s/i, label: 'Instruction to send data externally'} + { pattern: /curl\s+.*?-d\s/i, label: 'curl POST data' }, + { pattern: /curl\s+.*?--data/i, label: 'curl POST data' }, + { pattern: /wget\s+.*?--post/i, label: 'wget POST' }, + { pattern: /fetch\s*\(.*?method\s*:\s*['"]post/i, label: 'fetch POST' }, + { pattern: /\.env\b/i, label: 'References .env file' }, + { pattern: /credentials?\.(json|yml|yaml|toml)/i, label: 'References credentials file' }, + { pattern: /api[_-]?key/i, label: 'References API key' }, + { pattern: /send\s+(file|content|data)\s+to\s/i, label: 'Instruction to send data externally' } ]; /** * Persistence patterns. */ const PERSISTENCE_PATTERNS = [ - {pattern: /claude\.md/i, label: 'References CLAUDE.md'}, - {pattern: /\.claude\/(settings|config)/i, label: 'References .claude config'}, - {pattern: /\.cursor\//i, label: 'References .cursor config'}, - {pattern: /add\s+(this\s+)?to\s+(your\s+)?claude/i, label: 'Instruction to modify CLAUDE.md'}, - {pattern: /cron(tab)?\s/i, label: 'References cron/scheduled tasks'}, - {pattern: /install\s+(additional|more)\s+(tools|skills|plugins)/i, label: 'Instruction to install additional tools'} + { pattern: /claude\.md/i, label: 'References CLAUDE.md' }, + { pattern: /\.claude\/(settings|config)/i, label: 'References .claude config' }, + { pattern: /\.cursor\//i, label: 'References .cursor config' }, + { pattern: /add\s+(this\s+)?to\s+(your\s+)?claude/i, label: 'Instruction to modify CLAUDE.md' }, + { pattern: /cron(tab)?\s/i, label: 'References cron/scheduled tasks' }, + { + pattern: /install\s+(additional|more)\s+(tools|skills|plugins)/i, + label: 'Instruction to install additional tools' + } ]; /** * Tool escalation patterns. */ const ESCALATION_PATTERNS = [ - {pattern: /curl\s+.*?\|\s*sh/i, label: 'curl | sh (remote code execution)'}, - {pattern: /curl\s+.*?\|\s*bash/i, label: 'curl | bash (remote code execution)'}, - {pattern: /wget\s+.*?-o\s*-\s*\|\s*(sh|bash)/i, label: 'wget pipe to shell'}, - {pattern: /npx\s+(?!--)/i, label: 'npx execution'}, - {pattern: /git\s+push\s+--force/i, label: 'git push --force'}, - {pattern: /git\s+reset\s+--hard/i, label: 'git reset --hard'}, - {pattern: /rm\s+-rf\s+\//i, label: 'rm -rf / (destructive)'}, - {pattern: /--no-verify/i, label: 'Skip hooks (--no-verify)'}, - {pattern: /chmod\s+[0-7]*7[0-7]*\s/i, label: 'chmod world-executable'} + { pattern: /curl\s+.*?\|\s*sh/i, label: 'curl | sh (remote code execution)' }, + { pattern: /curl\s+.*?\|\s*bash/i, label: 'curl | bash (remote code execution)' }, + { pattern: /wget\s+.*?-o\s*-\s*\|\s*(sh|bash)/i, label: 'wget pipe to shell' }, + { pattern: /npx\s+(?!--)/i, label: 'npx execution' }, + { pattern: /git\s+push\s+--force/i, label: 'git push --force' }, + { pattern: /git\s+reset\s+--hard/i, label: 'git reset --hard' }, + { pattern: /rm\s+-rf\s+\//i, label: 'rm -rf / (destructive)' }, + { pattern: /--no-verify/i, label: 'Skip hooks (--no-verify)' }, + { pattern: /chmod\s+[0-7]*7[0-7]*\s/i, label: 'chmod world-executable' } ]; /** @@ -87,15 +96,15 @@ export function scanFileContent(content, filePath) { }; // Check injection patterns - for (const {pattern, label} of INJECTION_PATTERNS) { + for (const { pattern, label } of INJECTION_PATTERNS) { const matches = content.match(new RegExp(pattern, 'gi')); if (matches) { - findings.injection.push({label, count: matches.length}); + findings.injection.push({ label, count: matches.length }); } } // Check tool references - for (const {pattern, label} of TOOL_PATTERNS) { + for (const { pattern, label } of TOOL_PATTERNS) { const matches = content.match(new RegExp(pattern, 'g')); if (matches) { findings.tools[label] = matches.length; @@ -103,21 +112,21 @@ export function scanFileContent(content, filePath) { } // Check exfiltration patterns - for (const {pattern, label} of EXFILTRATION_PATTERNS) { + for (const { pattern, label } of EXFILTRATION_PATTERNS) { if (pattern.test(content)) { findings.exfiltration.push(label); } } // Check persistence patterns - for (const {pattern, label} of PERSISTENCE_PATTERNS) { + for (const { pattern, label } of PERSISTENCE_PATTERNS) { if (pattern.test(content)) { findings.persistence.push(label); } } // Check escalation patterns - for (const {pattern, label} of ESCALATION_PATTERNS) { + for (const { pattern, label } of ESCALATION_PATTERNS) { if (pattern.test(content)) { findings.escalation.push(label); } @@ -133,7 +142,24 @@ export function scanFileContent(content, filePath) { while ((cmdMatch = COMMAND_EXTRACT.exec(codeBlock)) !== null) { const cmd = cmdMatch[1]; // Skip very common shell builtins and noise - if (!['echo', 'cd', 'export', 'set', 'if', 'then', 'else', 'fi', 'do', 'done', 'for', 'while', 'case', 'esac'].includes(cmd)) { + if ( + ![ + 'echo', + 'cd', + 'export', + 'set', + 'if', + 'then', + 'else', + 'fi', + 'do', + 'done', + 'for', + 'while', + 'case', + 'esac' + ].includes(cmd) + ) { findings.commands.add(cmd); } } @@ -147,18 +173,32 @@ export function scanFileContent(content, filePath) { */ export async function scanDirectory(dirPath) { const results = []; - const textExtensions = new Set(['.md', '.txt', '.yml', '.yaml', '.json', '.toml', '.sh', '.bash', '.js', '.ts', '.py']); + const textExtensions = new Set([ + '.md', + '.txt', + '.yml', + '.yaml', + '.json', + '.toml', + '.sh', + '.bash', + '.js', + '.ts', + '.py' + ]); async function walk(dir) { - const entries = await readdir(dir, {withFileTypes: true}); + const entries = await readdir(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = join(dir, entry.name); if (entry.isDirectory()) { - // eslint-disable-next-line no-await-in-loop await walk(fullPath); - } else if (textExtensions.has(extname(entry.name).toLowerCase()) || entry.name === 'SKILL.md' || entry.name === 'CLAUDE.md') { + } else if ( + textExtensions.has(extname(entry.name).toLowerCase()) || + entry.name === 'SKILL.md' || + entry.name === 'CLAUDE.md' + ) { const relPath = relative(dirPath, fullPath); - // eslint-disable-next-line no-await-in-loop const content = await readFile(fullPath, 'utf8'); results.push(scanFileContent(content, relPath)); } @@ -204,15 +244,14 @@ export function summarizeScan(fileResults) { // Collect patterns for (const inj of result.injection) { - injectionPatterns.push({file: result.file, ...inj}); + injectionPatterns.push({ file: result.file, ...inj }); } for (const exf of result.exfiltration) { - exfiltrationPatterns.push({file: result.file, label: exf}); + exfiltrationPatterns.push({ file: result.file, label: exf }); } } - /* eslint-disable camelcase -- SPEC.3 JSON schema uses snake_case */ return { files_scanned: fileResults.length, issues: totalIssues, @@ -221,14 +260,18 @@ export function summarizeScan(fileResults) { command_surface: [...allCommands], injection_patterns: injectionPatterns, exfiltration_patterns: exfiltrationPatterns, - details: Object.fromEntries(fileResults.map(r => [r.file, { - tool_refs: r.tools, - command_refs: [...r.commands], - injection: r.injection, - exfiltration: r.exfiltration, - persistence: r.persistence, - escalation: r.escalation - }])) + details: Object.fromEntries( + fileResults.map(r => [ + r.file, + { + tool_refs: r.tools, + command_refs: [...r.commands], + injection: r.injection, + exfiltration: r.exfiltration, + persistence: r.persistence, + escalation: r.escalation + } + ]) + ) }; - /* eslint-enable camelcase */ } diff --git a/src/tree.js b/src/tree.js index 210ec47..b3d30e6 100644 --- a/src/tree.js +++ b/src/tree.js @@ -1,5 +1,5 @@ -import {readdir} from 'node:fs/promises'; -import {join, basename} from 'node:path'; +import { readdir } from 'node:fs/promises'; +import { basename, join } from 'node:path'; import archy from 'archy'; async function buildTree(dir, name = null) { @@ -7,17 +7,19 @@ async function buildTree(dir, name = null) { try { // Use withFileTypes to avoid stat calls - const entries = await readdir(dir, {withFileTypes: true}); + const entries = await readdir(dir, { withFileTypes: true }); - const children = await Promise.all(entries - .sort((a, b) => a.name.localeCompare(b.name)) - .map(async entry => { - if (entry.isDirectory()) { - return buildTree(join(dir, entry.name), entry.name); - } + const children = await Promise.all( + entries + .sort((a, b) => a.name.localeCompare(b.name)) + .map(async entry => { + if (entry.isDirectory()) { + return buildTree(join(dir, entry.name), entry.name); + } - return entry.name; - })); + return entry.name; + }) + ); return { label, diff --git a/src/vlurpfile.js b/src/vlurpfile.js index cc1b9cb..14464c5 100644 --- a/src/vlurpfile.js +++ b/src/vlurpfile.js @@ -1,5 +1,5 @@ -import {resolve} from 'node:path'; -import {PRESETS} from './presets.js'; +import { resolve } from 'node:path'; +import { PRESETS } from './presets.js'; /** * Parses a .vlurpfile and returns an array of vlurp commands. @@ -115,7 +115,7 @@ function replaceRef(line, newRef) { // No existing --ref -- append before trailing newline/whitespace const trimmed = line.trimEnd(); - return trimmed + ` --ref ${newRef}`; + return `${trimmed} --ref ${newRef}`; } /** diff --git a/test/catalog-diff.test.js b/test/catalog-diff.test.js index a645363..2d9c404 100644 --- a/test/catalog-diff.test.js +++ b/test/catalog-diff.test.js @@ -1,9 +1,6 @@ -import {describe, it} from 'node:test'; -import {strict as assert} from 'node:assert'; -import {diffCatalogs, formatCatalogDiff} from '../src/catalog-diff.js'; - -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -- File-wide disable for SPEC.3 snake_case schema -/* eslint-disable camelcase */ +import { strict as assert } from 'node:assert'; +import { describe, it } from 'node:test'; +import { diffCatalogs, formatCatalogDiff } from '../src/catalog-diff.js'; function skill(overrides = {}) { return { @@ -19,7 +16,7 @@ function skill(overrides = {}) { describe('diffCatalogs', () => { it('should detect new skills', () => { - const oldCatalog = {skills: {}}; + const oldCatalog = { skills: {} }; const newCatalog = { skills: { browse: skill({ @@ -31,7 +28,7 @@ describe('diffCatalogs', () => { const diff = diffCatalogs(oldCatalog, newCatalog); assert.equal(diff.skills.browse.status, 'new'); - assert.deepEqual(diff.skills.browse.version, {old: null, new: '1.0.0'}); + assert.deepEqual(diff.skills.browse.version, { old: null, new: '1.0.0' }); assert.deepEqual(diff.skills.browse.tool_surface.added, ['Bash', 'Read']); assert.deepEqual(diff.skills.browse.tool_surface.removed, []); assert.equal(diff.summary.new, 1); @@ -46,30 +43,30 @@ describe('diffCatalogs', () => { }) } }; - const newCatalog = {skills: {}}; + const newCatalog = { skills: {} }; const diff = diffCatalogs(oldCatalog, newCatalog); assert.equal(diff.skills['old-skill'].status, 'removed'); - assert.deepEqual(diff.skills['old-skill'].version, {old: '1.0.0', new: null}); + assert.deepEqual(diff.skills['old-skill'].version, { old: '1.0.0', new: null }); assert.deepEqual(diff.skills['old-skill'].tool_surface.removed, ['Bash']); assert.equal(diff.summary.removed, 1); }); it('should detect changed skills - version bump', () => { - const oldCatalog = {skills: {browse: skill()}}; + const oldCatalog = { skills: { browse: skill() } }; const newCatalog = { - skills: {browse: skill({ref: 'def5678', version: '1.1.0'})} + skills: { browse: skill({ ref: 'def5678', version: '1.1.0' }) } }; const diff = diffCatalogs(oldCatalog, newCatalog); assert.equal(diff.skills.browse.status, 'changed'); - assert.deepEqual(diff.skills.browse.version, {old: '1.0.0', new: '1.1.0'}); + assert.deepEqual(diff.skills.browse.version, { old: '1.0.0', new: '1.1.0' }); assert.equal(diff.summary.changed, 1); }); it('should detect changed skills - tool surface delta', () => { const oldCatalog = { - skills: {review: skill({tool_surface: ['Bash', 'Read']})} + skills: { review: skill({ tool_surface: ['Bash', 'Read'] }) } }; const newCatalog = { skills: { @@ -88,8 +85,8 @@ describe('diffCatalogs', () => { it('should detect unchanged skills', () => { const s = skill(); - const oldCatalog = {skills: {myskill: s}}; - const newCatalog = {skills: {myskill: {...s}}}; + const oldCatalog = { skills: { myskill: s } }; + const newCatalog = { skills: { myskill: { ...s } } }; const diff = diffCatalogs(oldCatalog, newCatalog); assert.equal(diff.skills.myskill.status, 'unchanged'); @@ -97,9 +94,9 @@ describe('diffCatalogs', () => { }); it('should track source-level ref changes', () => { - const oldCatalog = {skills: {browse: skill({ref: 'abc1234'})}}; + const oldCatalog = { skills: { browse: skill({ ref: 'abc1234' }) } }; const newCatalog = { - skills: {browse: skill({ref: 'def5678', version: '1.1.0'})} + skills: { browse: skill({ ref: 'def5678', version: '1.1.0' }) } }; const diff = diffCatalogs(oldCatalog, newCatalog); @@ -115,9 +112,9 @@ describe('diffCatalogs', () => { command_surface: ['browse'], supporting_files: ['find-browse'] }), - review: skill({supporting_files: ['checklist.md']}), + review: skill({ supporting_files: ['checklist.md'] }), ship: skill(), - 'old-skill': skill({tool_surface: []}) + 'old-skill': skill({ tool_surface: [] }) } }; const newCatalog = { @@ -133,7 +130,7 @@ describe('diffCatalogs', () => { ref: 'new456', supporting_files: ['checklist.md', 'greptile-triage.md'] }), - ship: skill({ref: 'new456'}), + ship: skill({ ref: 'new456' }), 'gstack-upgrade': skill({ ref: 'new456', tool_surface: ['Bash', 'Read'] @@ -145,7 +142,7 @@ describe('diffCatalogs', () => { // Browse: changed (version bump + new tool + new file) assert.equal(diff.skills.browse.status, 'changed'); - assert.deepEqual(diff.skills.browse.version, {old: '1.0.0', new: '1.1.0'}); + assert.deepEqual(diff.skills.browse.version, { old: '1.0.0', new: '1.1.0' }); assert.deepEqual(diff.skills.browse.tool_surface.added, ['AskUserQuestion']); assert.deepEqual(diff.skills.browse.supporting_files.added, ['remote-slug']); @@ -171,14 +168,14 @@ describe('diffCatalogs', () => { }); it('should handle empty catalogs', () => { - const diff = diffCatalogs({skills: {}}, {skills: {}}); + const diff = diffCatalogs({ skills: {} }, { skills: {} }); assert.equal(diff.summary.total, 0); assert.deepEqual(diff.skills, {}); assert.deepEqual(diff.sources, {}); }); it('should handle null/undefined catalogs gracefully', () => { - const diff = diffCatalogs(null, {skills: {a: {version: '1.0.0'}}}); + const diff = diffCatalogs(null, { skills: { a: { version: '1.0.0' } } }); assert.equal(diff.summary.new, 1); }); }); @@ -188,8 +185,8 @@ describe('formatCatalogDiff', () => { const diff = diffCatalogs( { skills: { - browse: skill({ref: 'old123'}), - removed: skill({ref: 'old123'}) + browse: skill({ ref: 'old123' }), + removed: skill({ ref: 'old123' }) } }, { @@ -199,7 +196,7 @@ describe('formatCatalogDiff', () => { version: '1.1.0', tool_surface: ['Bash', 'Read'] }), - added: skill({ref: 'new456'}) + added: skill({ ref: 'new456' }) } } ); @@ -228,7 +225,7 @@ describe('formatCatalogDiff', () => { it('should show (none) for new skills with empty surfaces', () => { const diff = diffCatalogs( - {skills: {}}, + { skills: {} }, { skills: { empty: skill({ @@ -246,10 +243,7 @@ describe('formatCatalogDiff', () => { it('should not list unchanged skills in output', () => { const s = skill(); - const diff = diffCatalogs( - {skills: {stable: s}}, - {skills: {stable: {...s}}} - ); + const diff = diffCatalogs({ skills: { stable: s } }, { skills: { stable: { ...s } } }); const output = formatCatalogDiff(diff); // The skill name should not appear in the per-skill section (only in summary) assert.ok(!output.includes(' stable')); diff --git a/test/cli.test.js b/test/cli.test.js index 8816d84..fdb2317 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -1,22 +1,22 @@ -import {describe, it} from 'node:test'; -import {strict as assert} from 'node:assert'; -import {execSync} from 'node:child_process'; -import {join, dirname} from 'node:path'; -import {fileURLToPath} from 'node:url'; +import { strict as assert } from 'node:assert'; +import { execSync } from 'node:child_process'; +import { dirname, join } from 'node:path'; +import { describe, it } from 'node:test'; +import { fileURLToPath } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const binPath = join(__dirname, '..', 'bin', 'vlurp'); describe('CLI', () => { it('should show help with --help', () => { - const output = execSync(`node ${binPath} --help`, {encoding: 'utf8'}); + const output = execSync(`node ${binPath} --help`, { encoding: 'utf8' }); assert.ok(output.includes('vlurp'), 'Help should mention vlurp'); assert.ok(output.includes('--help'), 'Help should show --help option'); }); it('should show usage when called without arguments', () => { try { - execSync(`node ${binPath}`, {encoding: 'utf8', stdio: 'pipe'}); + execSync(`node ${binPath}`, { encoding: 'utf8', stdio: 'pipe' }); assert.fail('Should have exited with error'); } catch (err) { // Expected to fail - no source provided diff --git a/test/lineage.test.js b/test/lineage.test.js index d8112a1..6f38110 100644 --- a/test/lineage.test.js +++ b/test/lineage.test.js @@ -1,17 +1,13 @@ +import { strict as assert } from 'node:assert'; +import { mkdir, rm, writeFile } from 'node:fs/promises'; +import { dirname, join } from 'node:path'; +import { afterEach, beforeEach, describe, it } from 'node:test'; +import { fileURLToPath } from 'node:url'; import { - describe, it, beforeEach, afterEach -} from 'node:test'; -import {strict as assert} from 'node:assert'; -import {join, dirname} from 'node:path'; -import { - mkdir, writeFile, rm -} from 'node:fs/promises'; -import {fileURLToPath} from 'node:url'; -import { - hashFile, - hashDirectory, - createLineageRecord, appendLineage, + createLineageRecord, + hashDirectory, + hashFile, readLineage, verifyFiles } from '../src/lineage.js'; @@ -21,11 +17,11 @@ const fixturesDir = join(__dirname, 'fixtures', 'lineage-test'); describe('lineage', () => { beforeEach(async () => { - await mkdir(fixturesDir, {recursive: true}); + await mkdir(fixturesDir, { recursive: true }); }); afterEach(async () => { - await rm(fixturesDir, {recursive: true, force: true}); + await rm(fixturesDir, { recursive: true, force: true }); }); describe('hashFile', () => { @@ -64,7 +60,7 @@ describe('lineage', () => { describe('hashDirectory', () => { it('should hash all files recursively', async () => { - await mkdir(join(fixturesDir, 'sub'), {recursive: true}); + await mkdir(join(fixturesDir, 'sub'), { recursive: true }); await writeFile(join(fixturesDir, 'root.md'), '# Root'); await writeFile(join(fixturesDir, 'sub', 'nested.md'), '# Nested'); @@ -87,7 +83,7 @@ describe('lineage', () => { preset: 'skills', asName: 'dex', files: { - 'SKILL.md': {sha256: 'abc123', size: 100} + 'SKILL.md': { sha256: 'abc123', size: 100 } } }); @@ -98,7 +94,7 @@ describe('lineage', () => { assert.deepEqual(record.filters, ['skills/**']); assert.equal(record.preset, 'skills'); assert.equal(record.as, 'dex'); - assert.deepEqual(record.files, {'SKILL.md': {sha256: 'abc123', size: 100}}); + assert.deepEqual(record.files, { 'SKILL.md': { sha256: 'abc123', size: 100 } }); }); it('should handle unpinned fetches', () => { @@ -121,13 +117,13 @@ describe('lineage', () => { const record1 = createLineageRecord({ source: 'user/repo1', ref: 'abc1234', - files: {'a.md': {sha256: 'hash1', size: 10}} + files: { 'a.md': { sha256: 'hash1', size: 10 } } }); const record2 = createLineageRecord({ source: 'user/repo2', ref: 'def5678', - files: {'b.md': {sha256: 'hash2', size: 20}} + files: { 'b.md': { sha256: 'hash2', size: 20 } } }); await appendLineage(jsonlPath, record1); @@ -145,7 +141,7 @@ describe('lineage', () => { const record1 = createLineageRecord({ source: 'user/repo', ref: 'old', - files: {'a.md': {sha256: 'old-hash', size: 10}} + files: { 'a.md': { sha256: 'old-hash', size: 10 } } }); await appendLineage(jsonlPath, record1); @@ -153,7 +149,7 @@ describe('lineage', () => { const record2 = createLineageRecord({ source: 'user/repo', ref: 'new', - files: {'a.md': {sha256: 'new-hash', size: 15}} + files: { 'a.md': { sha256: 'new-hash', size: 15 } } }); await appendLineage(jsonlPath, record2); @@ -169,13 +165,13 @@ describe('lineage', () => { const record1 = createLineageRecord({ source: 'user/repo', asName: 'skill-a', - files: {'a.md': {sha256: 'hash1', size: 10}} + files: { 'a.md': { sha256: 'hash1', size: 10 } } }); const record2 = createLineageRecord({ source: 'user/repo', asName: 'skill-b', - files: {'b.md': {sha256: 'hash2', size: 20}} + files: { 'b.md': { sha256: 'hash2', size: 20 } } }); await appendLineage(jsonlPath, record1); @@ -196,16 +192,18 @@ describe('lineage', () => { // Simulate: vlurp user/repo --as myskill -d ./content // Files at content/myskill/SKILL.md, JSONL at content/.vlurp.jsonl const contentDir = join(fixturesDir, 'content'); - await mkdir(join(contentDir, 'myskill'), {recursive: true}); + await mkdir(join(contentDir, 'myskill'), { recursive: true }); await writeFile(join(contentDir, 'myskill', 'SKILL.md'), '# My Skill'); - const {sha256, size} = await hashFile(join(contentDir, 'myskill', 'SKILL.md')); - const records = [{ - source: 'github:user/repo', - ref: 'abc1234', - as: 'myskill', - files: {'SKILL.md': {sha256, size}} - }]; + const { sha256, size } = await hashFile(join(contentDir, 'myskill', 'SKILL.md')); + const records = [ + { + source: 'github:user/repo', + ref: 'abc1234', + as: 'myskill', + files: { 'SKILL.md': { sha256, size } } + } + ]; const results = await verifyFiles(contentDir, records); const skillResult = results.find(r => r.file === 'myskill/SKILL.md'); @@ -216,16 +214,18 @@ describe('lineage', () => { // Simulate: vlurp user/repo -d ./content // Files at content/user/repo/SKILL.md, JSONL at content/.vlurp.jsonl const contentDir = join(fixturesDir, 'content'); - await mkdir(join(contentDir, 'user', 'repo'), {recursive: true}); + await mkdir(join(contentDir, 'user', 'repo'), { recursive: true }); await writeFile(join(contentDir, 'user', 'repo', 'SKILL.md'), '# My Skill'); - const {sha256, size} = await hashFile(join(contentDir, 'user', 'repo', 'SKILL.md')); - const records = [{ - source: 'github:user/repo', - ref: 'abc1234', - as: null, - files: {'SKILL.md': {sha256, size}} - }]; + const { sha256, size } = await hashFile(join(contentDir, 'user', 'repo', 'SKILL.md')); + const records = [ + { + source: 'github:user/repo', + ref: 'abc1234', + as: null, + files: { 'SKILL.md': { sha256, size } } + } + ]; const results = await verifyFiles(contentDir, records); const skillResult = results.find(r => r.file === 'user/repo/SKILL.md'); @@ -234,15 +234,17 @@ describe('lineage', () => { it('should detect modified files', async () => { const contentDir = join(fixturesDir, 'content'); - await mkdir(join(contentDir, 'dex'), {recursive: true}); + await mkdir(join(contentDir, 'dex'), { recursive: true }); await writeFile(join(contentDir, 'dex', 'SKILL.md'), '# My Skill'); - const records = [{ - source: 'github:user/repo', - ref: 'abc1234', - as: 'dex', - files: {'SKILL.md': {sha256: 'wrong-hash', size: 100}} - }]; + const records = [ + { + source: 'github:user/repo', + ref: 'abc1234', + as: 'dex', + files: { 'SKILL.md': { sha256: 'wrong-hash', size: 100 } } + } + ]; const results = await verifyFiles(contentDir, records); const skillResult = results.find(r => r.file === 'dex/SKILL.md'); @@ -251,14 +253,16 @@ describe('lineage', () => { it('should detect missing files', async () => { const contentDir = join(fixturesDir, 'content'); - await mkdir(join(contentDir, 'dex'), {recursive: true}); - - const records = [{ - source: 'github:user/repo', - ref: 'abc1234', - as: 'dex', - files: {'MISSING.md': {sha256: 'some-hash', size: 100}} - }]; + await mkdir(join(contentDir, 'dex'), { recursive: true }); + + const records = [ + { + source: 'github:user/repo', + ref: 'abc1234', + as: 'dex', + files: { 'MISSING.md': { sha256: 'some-hash', size: 100 } } + } + ]; const results = await verifyFiles(contentDir, records); const missingResult = results.find(r => r.file === 'dex/MISSING.md'); @@ -267,17 +271,19 @@ describe('lineage', () => { it('should detect untracked files', async () => { const contentDir = join(fixturesDir, 'content'); - await mkdir(join(contentDir, 'myskill'), {recursive: true}); + await mkdir(join(contentDir, 'myskill'), { recursive: true }); await writeFile(join(contentDir, 'myskill', 'tracked.md'), '# Tracked'); await writeFile(join(contentDir, 'myskill', 'untracked.md'), '# Untracked'); - const {sha256, size} = await hashFile(join(contentDir, 'myskill', 'tracked.md')); - const records = [{ - source: 'github:user/repo', - ref: 'abc1234', - as: 'myskill', - files: {'tracked.md': {sha256, size}} - }]; + const { sha256, size } = await hashFile(join(contentDir, 'myskill', 'tracked.md')); + const records = [ + { + source: 'github:user/repo', + ref: 'abc1234', + as: 'myskill', + files: { 'tracked.md': { sha256, size } } + } + ]; const results = await verifyFiles(contentDir, records); const trackedResult = results.find(r => r.file === 'myskill/tracked.md'); @@ -288,17 +294,19 @@ describe('lineage', () => { it('should skip .vlurp.jsonl in untracked results', async () => { const contentDir = join(fixturesDir, 'content'); - await mkdir(join(contentDir, 'myskill'), {recursive: true}); + await mkdir(join(contentDir, 'myskill'), { recursive: true }); await writeFile(join(contentDir, '.vlurp.jsonl'), '{}'); await writeFile(join(contentDir, 'myskill', 'tracked.md'), '# Tracked'); - const {sha256, size} = await hashFile(join(contentDir, 'myskill', 'tracked.md')); - const records = [{ - source: 'github:user/repo', - ref: 'abc1234', - as: 'myskill', - files: {'tracked.md': {sha256, size}} - }]; + const { sha256, size } = await hashFile(join(contentDir, 'myskill', 'tracked.md')); + const records = [ + { + source: 'github:user/repo', + ref: 'abc1234', + as: 'myskill', + files: { 'tracked.md': { sha256, size } } + } + ]; const results = await verifyFiles(contentDir, records); const jsonlResult = results.find(r => r.file === '.vlurp.jsonl'); diff --git a/test/remote.test.js b/test/remote.test.js index e3731e3..ea3a20c 100644 --- a/test/remote.test.js +++ b/test/remote.test.js @@ -1,10 +1,10 @@ +import { strict as assert } from 'node:assert'; +import { join } from 'node:path'; import process from 'node:process'; -import {describe, it} from 'node:test'; -import {strict as assert} from 'node:assert'; -import {join} from 'node:path'; -import {minimatch} from 'minimatch'; -import {Validator, Parser} from '../src/remote.js'; -import {resolveTargetPath} from '../src/commands/fetch.js'; +import { describe, it } from 'node:test'; +import { minimatch } from 'minimatch'; +import { resolveTargetPath } from '../src/commands/fetch.js'; +import { Parser, Validator } from '../src/remote.js'; describe('Validator', () => { const validator = new Validator(); @@ -63,17 +63,11 @@ describe('Parser', () => { }); it('should throw on invalid format', () => { - assert.throws( - () => parser.parse('invalid-format'), - /Invalid input format/ - ); + assert.throws(() => parser.parse('invalid-format'), /Invalid input format/); }); it('should throw on invalid URL', () => { - assert.throws( - () => parser.parse('https://gitlab.com/user/repo'), - /Invalid input format/ - ); + assert.throws(() => parser.parse('https://gitlab.com/user/repo'), /Invalid input format/); }); }); }); @@ -121,7 +115,8 @@ describe('Filter functionality', () => { ]; const filtered = testFiles.filter(file => - filters.some(pattern => minimatch(file, pattern, {matchBase: true}))); + filters.some(pattern => minimatch(file, pattern, { matchBase: true })) + ); assert.deepEqual(filtered, [ 'README.md', @@ -141,17 +136,12 @@ describe('Filter functionality', () => { '.claude/commands/tm/add-subtask/add-subtask.md' ]; - const otherPaths = [ - 'README.md', - 'CLAUDE.md', - '.taskmaster/CLAUDE.md', - 'src/index.js' - ]; + const otherPaths = ['README.md', 'CLAUDE.md', '.taskmaster/CLAUDE.md', 'src/index.js']; // All .claude paths should match .claude/** for (const path of claudePaths) { assert.ok( - minimatch(path, '.claude/**', {dot: true}), + minimatch(path, '.claude/**', { dot: true }), `Expected ${path} to match .claude/**` ); } @@ -159,7 +149,7 @@ describe('Filter functionality', () => { // Other paths should not match for (const path of otherPaths) { assert.ok( - !minimatch(path, '.claude/**', {dot: true}), + !minimatch(path, '.claude/**', { dot: true }), `Expected ${path} to NOT match .claude/**` ); } @@ -167,7 +157,18 @@ describe('Filter functionality', () => { it('should have correctly formatted default filters for glob', () => { // Default filters as defined in cli.js - const defaultFilters = ['.claude/**', 'CLAUDE.md', '*.md', '!README.md', '!CONTRIBUTING.md', '!LICENSE.md', '!CHANGELOG.md', '!CODE_OF_CONDUCT.md', 'agents/**', 'commands/**']; + const defaultFilters = [ + '.claude/**', + 'CLAUDE.md', + '*.md', + '!README.md', + '!CONTRIBUTING.md', + '!LICENSE.md', + '!CHANGELOG.md', + '!CODE_OF_CONDUCT.md', + 'agents/**', + 'commands/**' + ]; // Simply verify our default filters are properly formatted for glob // We trust glob to handle the actual pattern matching correctly diff --git a/test/scanner.test.js b/test/scanner.test.js index 655408a..0c59762 100644 --- a/test/scanner.test.js +++ b/test/scanner.test.js @@ -1,6 +1,6 @@ -import {describe, it} from 'node:test'; -import {strict as assert} from 'node:assert'; -import {scanFileContent, summarizeScan} from '../src/scanner.js'; +import { strict as assert } from 'node:assert'; +import { describe, it } from 'node:test'; +import { scanFileContent, summarizeScan } from '../src/scanner.js'; describe('scanner', () => { describe('scanFileContent', () => { @@ -47,7 +47,8 @@ This skill helps you write tests. }); it('should count multiple tool references', () => { - const content = 'First, use Bash to run lint. Then use Bash to run tests. Finally, Bash again.'; + const content = + 'First, use Bash to run lint. Then use Bash to run tests. Finally, Bash again.'; const result = scanFileContent(content, 'test.md'); assert.equal(result.tools.Bash, 3); }); diff --git a/test/tree.test.js b/test/tree.test.js index be7bcb3..1481118 100644 --- a/test/tree.test.js +++ b/test/tree.test.js @@ -1,9 +1,9 @@ -import {describe, it} from 'node:test'; -import {strict as assert} from 'node:assert'; -import {join, dirname} from 'node:path'; -import {mkdir, writeFile, rm} from 'node:fs/promises'; -import {fileURLToPath} from 'node:url'; -import {buildTreeString} from '../src/tree.js'; +import { strict as assert } from 'node:assert'; +import { mkdir, rm, writeFile } from 'node:fs/promises'; +import { dirname, join } from 'node:path'; +import { describe, it } from 'node:test'; +import { fileURLToPath } from 'node:url'; +import { buildTreeString } from '../src/tree.js'; describe('Tree display', () => { it('should include hidden directories in tree output', async () => { @@ -13,11 +13,11 @@ describe('Tree display', () => { try { // Ensure fixtures directory exists - await mkdir(testFixturesDir, {recursive: true}); + await mkdir(testFixturesDir, { recursive: true }); // Create test directory structure - await mkdir(testDir, {recursive: true}); - await mkdir(join(testDir, '.claude'), {recursive: true}); - await mkdir(join(testDir, 'visible-dir'), {recursive: true}); + await mkdir(testDir, { recursive: true }); + await mkdir(join(testDir, '.claude'), { recursive: true }); + await mkdir(join(testDir, 'visible-dir'), { recursive: true }); await writeFile(join(testDir, 'README.md'), 'test'); await writeFile(join(testDir, '.hidden-file'), 'test'); await writeFile(join(testDir, '.claude', 'config.json'), 'test'); @@ -32,10 +32,13 @@ describe('Tree display', () => { assert.ok(treeOutput.includes('.hidden-file'), 'Tree should include hidden files'); assert.ok(treeOutput.includes('visible-dir'), 'Tree should include visible directories'); assert.ok(treeOutput.includes('README.md'), 'Tree should include regular files'); - assert.ok(treeOutput.includes('config.json'), 'Tree should include files within hidden directories'); + assert.ok( + treeOutput.includes('config.json'), + 'Tree should include files within hidden directories' + ); } finally { // Clean up test directory only (not the fixtures directory) - await rm(testDir, {recursive: true, force: true}); + await rm(testDir, { recursive: true, force: true }); } }); }); diff --git a/test/upgrade.test.js b/test/upgrade.test.js index 4258d6b..0b914da 100644 --- a/test/upgrade.test.js +++ b/test/upgrade.test.js @@ -1,15 +1,11 @@ -import { - describe, it, beforeEach, afterEach -} from 'node:test'; -import {strict as assert} from 'node:assert'; -import { - mkdtemp, writeFile, readFile, mkdir, rm -} from 'node:fs/promises'; -import {join} from 'node:path'; -import {tmpdir} from 'node:os'; -import {parseVlurpfile, updateRef, updateRefs} from '../src/vlurpfile.js'; -import {buildCatalog} from '../src/catalog.js'; -import {diffCatalogs, formatCatalogDiff} from '../src/catalog-diff.js'; +import { strict as assert } from 'node:assert'; +import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { afterEach, beforeEach, describe, it } from 'node:test'; +import { buildCatalog } from '../src/catalog.js'; +import { diffCatalogs, formatCatalogDiff } from '../src/catalog-diff.js'; +import { parseVlurpfile, updateRef, updateRefs } from '../src/vlurpfile.js'; describe('upgrade - vlurpfile rewriting', () => { let tempDir; @@ -19,7 +15,7 @@ describe('upgrade - vlurpfile rewriting', () => { }); afterEach(async () => { - await rm(tempDir, {recursive: true, force: true}); + await rm(tempDir, { recursive: true, force: true }); }); it('should update --ref in a vlurpfile on disk', async () => { @@ -164,14 +160,16 @@ describe('upgrade - catalog integration', () => { }); afterEach(async () => { - await rm(tempDir, {recursive: true, force: true}); + await rm(tempDir, { recursive: true, force: true }); }); it('should build catalog from lineage and SKILL.md on disk', async () => { // Set up a minimal skills directory with lineage and a SKILL.md const skillDir = join(tempDir, 'myskill'); - await mkdir(skillDir, {recursive: true}); - await writeFile(join(skillDir, 'SKILL.md'), `--- + await mkdir(skillDir, { recursive: true }); + await writeFile( + join(skillDir, 'SKILL.md'), + `--- name: myskill version: 1.0.0 description: A test skill @@ -183,21 +181,22 @@ allowed-tools: # My Skill Use Bash tool to run commands. -`); +` + ); // Write lineage record const lineageRecord = { source: 'github:user/repo', ref: 'abc1234', - fetched_at: '2026-03-15T00:00:00Z', // eslint-disable-line camelcase + fetched_at: '2026-03-15T00:00:00Z', filters: [], preset: null, as: 'myskill', files: { - 'SKILL.md': {sha256: 'fake', size: 100} + 'SKILL.md': { sha256: 'fake', size: 100 } } }; - await writeFile(join(tempDir, '.vlurp.jsonl'), JSON.stringify(lineageRecord) + '\n'); + await writeFile(join(tempDir, '.vlurp.jsonl'), `${JSON.stringify(lineageRecord)}\n`); const catalog = await buildCatalog(tempDir); assert.ok(catalog.skills.myskill); @@ -215,9 +214,9 @@ Use Bash tool to run commands. source: 'github:user/repo', ref: 'old123', version: '1.0.0', - tool_surface: ['Bash'], // eslint-disable-line camelcase - command_surface: [], // eslint-disable-line camelcase - supporting_files: [] // eslint-disable-line camelcase + tool_surface: ['Bash'], + command_surface: [], + supporting_files: [] } } }; @@ -229,16 +228,16 @@ Use Bash tool to run commands. source: 'github:user/repo', ref: 'new456', version: '1.1.0', - tool_surface: ['Bash', 'Read'], // eslint-disable-line camelcase - command_surface: [], // eslint-disable-line camelcase - supporting_files: ['helper.md'] // eslint-disable-line camelcase + tool_surface: ['Bash', 'Read'], + command_surface: [], + supporting_files: ['helper.md'] } } }; const diff = diffCatalogs(preCatalog, postCatalog); assert.equal(diff.skills.myskill.status, 'changed'); - assert.deepEqual(diff.skills.myskill.version, {old: '1.0.0', new: '1.1.0'}); + assert.deepEqual(diff.skills.myskill.version, { old: '1.0.0', new: '1.1.0' }); assert.deepEqual(diff.skills.myskill.tool_surface.added, ['Read']); assert.deepEqual(diff.skills.myskill.supporting_files.added, ['helper.md']); @@ -252,11 +251,11 @@ Use Bash tool to run commands. it('should write catalog.json and catalog.prev.json', async () => { // Write an existing catalog.json - const existingCatalog = {generated_at: '2026-03-14T00:00:00Z', skills: {}}; // eslint-disable-line camelcase - await writeFile(join(tempDir, 'catalog.json'), JSON.stringify(existingCatalog, null, 2) + '\n'); + const existingCatalog = { generated_at: '2026-03-14T00:00:00Z', skills: {} }; + await writeFile(join(tempDir, 'catalog.json'), `${JSON.stringify(existingCatalog, null, 2)}\n`); // Simulate the saveCatalogs pattern from upgrade - const {rename: fsRename} = await import('node:fs/promises'); + const { rename: fsRename } = await import('node:fs/promises'); const catalogPath = join(tempDir, 'catalog.json'); const prevPath = join(tempDir, 'catalog.prev.json'); @@ -264,8 +263,11 @@ Use Bash tool to run commands. await fsRename(catalogPath, prevPath); // Write new - const newCatalog = {generated_at: '2026-03-15T00:00:00Z', skills: {a: {version: '1.0.0'}}}; // eslint-disable-line camelcase - await writeFile(catalogPath, JSON.stringify(newCatalog, null, 2) + '\n'); + const newCatalog = { + generated_at: '2026-03-15T00:00:00Z', + skills: { a: { version: '1.0.0' } } + }; + await writeFile(catalogPath, `${JSON.stringify(newCatalog, null, 2)}\n`); // Verify both files exist const prev = JSON.parse(await readFile(prevPath, 'utf8')); diff --git a/test/vlurpfile.test.js b/test/vlurpfile.test.js index 58be4d6..f2edec1 100644 --- a/test/vlurpfile.test.js +++ b/test/vlurpfile.test.js @@ -1,6 +1,6 @@ -import {describe, it} from 'node:test'; -import {strict as assert} from 'node:assert'; -import {parseVlurpfile, updateRef, updateRefs} from '../src/vlurpfile.js'; +import { strict as assert } from 'node:assert'; +import { describe, it } from 'node:test'; +import { parseVlurpfile, updateRef, updateRefs } from '../src/vlurpfile.js'; describe('vlurpfile parser', () => { it('should parse --ref flag', () => { @@ -24,7 +24,8 @@ describe('vlurpfile parser', () => { }); it('should parse combined --ref and --as', () => { - const content = 'vlurp dcramer/dex -d ./skills --filter "plugins/dex/skills/dex/**" --as dex --ref 939f6cb'; + const content = + 'vlurp dcramer/dex -d ./skills --filter "plugins/dex/skills/dex/**" --as dex --ref 939f6cb'; const entries = parseVlurpfile(content); assert.equal(entries[0].ref, '939f6cb'); assert.equal(entries[0].as, 'dex'); diff --git a/xo.config.js b/xo.config.js deleted file mode 100644 index 7a2b304..0000000 --- a/xo.config.js +++ /dev/null @@ -1,23 +0,0 @@ -export default { - space: 2, - semicolon: true, - prettier: false, - ignores: [ - 'concepts/**', - 'vlurp-new/**', - 'dgm/**', - 'ext/**' - ], - rules: { - 'unicorn/prevent-abbreviations': 'off', - 'import/extensions': 'off', - '@stylistic/comma-dangle': ['error', 'never'], - '@stylistic/indent-binary-ops': ['error', 2], - '@stylistic/object-curly-spacing': 'off', - 'unicorn/no-process-exit': 'off', - 'unicorn/import-style': 'off', - 'no-return-await': 'off', - 'unicorn/catch-error-name': ['error', {name: 'err'}], - 'unicorn/no-array-for-each': 'off' - } -}; From 14c5cad97bc4ddae13ddce703a1ac577178f66f3 Mon Sep 17 00:00:00 2001 From: indexzero Date: Wed, 1 Apr 2026 03:03:21 -0400 Subject: [PATCH 2/2] ci(lint) split biome lint into dedicated CI job Separate linting from the test matrix so format and lint failures surface as their own check badge instead of running redundantly on both Node 20 and 22. Tests no longer block on lint and vice versa. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/test.yml | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a1d6083..a549745 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Test +name: CI on: pull_request: @@ -9,6 +9,31 @@ on: - main jobs: + lint: + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10.14.0 + + - name: Use Node.js 22.x + uses: actions/setup-node@v4 + with: + node-version: 22.x + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Check formatting and linting + run: pnpm lint + test: runs-on: ubuntu-latest strategy: @@ -32,8 +57,5 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Run linter - run: pnpm lint - - name: Run tests run: pnpm test