diff --git a/CHANGELOG.md b/CHANGELOG.md index f843eb9b..76cbcef4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +<<<<<<< HEAD +======= ## [1.64.0](https://github.com/Doist/todoist-cli/compare/v1.63.2...v1.64.0) (2026-05-15) ### Features @@ -16,6 +18,7 @@ * forward arrayBuffer on tracked-fetch wrapper for binary attachments ([#338](https://github.com/Doist/todoist-cli/issues/338)) ([8ca5598](https://github.com/Doist/todoist-cli/commit/8ca559855c0e4d8cfa7f8ede1f6c89324f008f8d)) +>>>>>>> origin/main ## [1.63.0](https://github.com/Doist/todoist-cli/compare/v1.62.2...v1.63.0) (2026-05-12) ### Features diff --git a/CODEBASE.md b/CODEBASE.md index a24edc35..0a3d59a5 100644 --- a/CODEBASE.md +++ b/CODEBASE.md @@ -124,6 +124,18 @@ New subcommand? Copy a sibling in the target group, wire it in that group's - **`auth-flags.ts`** — `buildReloginCommand()` (rebuilds `td auth login` with `--read-only` / `--additional-scopes=...` preserved) - **`config.ts`** — `~/.config/todoist-cli/config.json` read/write, +<<<<<<< HEAD + `AuthMode`, `UpdateChannel`, `AUTH_FLAG_ORDER` +- **`secure-store.ts`** — `@napi-rs/keyring` wrapper (OS credential manager) +- **`auth-provider.ts`** — `createTodoistAuthProvider()`: `@doist/cli-core` + PKCE `AuthProvider` adapter with a Todoist-specific `validateToken` + (calls `getUser`, builds `auth_mode` / `auth_scope` / `auth_flags`) +- **`auth-store.ts`** — `createTodoistTokenStore()`: cli-core + `TokenStore` adapter over `auth.ts`'s multi-user primitives. + Also exports `toTodoistAccount` / `accountToUpsertInput` mappers (shared + account shape) and `getLastStorageResult()` for surfacing keyring-fallback + warnings after `set()`. +======= `stripLegacyAuthFields`, `AuthMode`, `UpdateChannel`, `AUTH_FLAG_ORDER`. - **`auth-provider.ts`** — `createTodoistAuthProvider()`: cli-core PKCE provider with Todoist `validateToken` (builds `auth_mode` / `auth_scope` / @@ -136,6 +148,7 @@ New subcommand? Copy a sibling in the target group, wire it in that group's the config file. REPLACE-not-merge `upsert`; `ensureV2` on every write. - **`migrate-auth.ts`** — postinstall v1 → v2 migration; thin wrapper around cli-core's `migrateLegacyAuth` with the Todoist callbacks. +>>>>>>> origin/main - **`auth-html.ts`** — branded HTML pages for the cli-core OAuth callback (`renderAuthSuccessPage` / `renderAuthErrorPage`) - **`oauth-scopes.ts`** — opt-in OAuth scope registry, `parseScopesOption`, @@ -167,10 +180,13 @@ New subcommand? Copy a sibling in the target group, wire it in that group's - **`permissions.ts`** — collaborator permission parsing - **`help-center.ts`** — Help Center article search/fetch - **`progress.ts`** — `--progress-jsonl` JSONL event writer +<<<<<<< HEAD +======= - **`local-file.ts`** — `openLocalFileAsBlob()`: file-backed `Blob` for multipart uploads (used by `comment add --file`, `template create --file`, `template import-file`). Maps fs errors to `FILE_NOT_FOUND` / `FILE_READ_ERROR` CliErrors. +>>>>>>> origin/main - **`usage-tracking.ts`** — request/session metadata headers, CLI command attribution, tracked fetch wrappers - **`browser.ts` / `stdin.ts` / `update.ts`** — small single-purpose helpers @@ -219,6 +235,17 @@ env `TODOIST_API_TOKEN` first, then a config-derived target user, then either `StoredUser.api_token` (plaintext keyring-offline fallback) or cli-core's `createSecureStore` for the keyring slot. +<<<<<<< HEAD +`td auth login` runs through `@doist/cli-core`'s OAuth runtime +(`attachLoginCommand` → `runOAuthFlow`). The Todoist-local pieces live in +`src/lib/auth-provider.ts` (PKCE provider + `validateToken`) and +`src/lib/auth-store.ts` (multi-user `TokenStore` adapter); the command is +attached in `src/commands/auth/login.ts`. cli-core wires the standard flags +(`--read-only`, `--callback-port`, `--json`, `--ndjson`) and binds the local +callback server on port `8765` with a small fallback range. Scopes are +opt-in: `--read-only` for a read-only token, +`--additional-scopes=app-management,backups` to broaden. +======= Write/clear/list all route through `createTodoistTokenStore()`; commands never write the config directly. `auth logout` and `auth token view` use `withUserRefAware` (`commands/auth/store-wrap.ts`) to substitute the @@ -228,6 +255,7 @@ v1 → v2 migration (`migrate-auth.ts` → cli-core's `migrateLegacyAuth`) runs from `postinstall.ts`. Gate is `config.config_version === CONFIG_VERSION`, which survives logout so a reinstall over a logged-out v2 install can't re-migrate a stale legacy slot. +>>>>>>> origin/main ## Testing diff --git a/package-lock.json b/package-lock.json index c7600946..21f82698 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,30 @@ { "name": "@doist/todoist-cli", +<<<<<<< HEAD + "version": "1.63.0", +======= "version": "1.64.0", +>>>>>>> origin/main "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@doist/todoist-cli", +<<<<<<< HEAD + "version": "1.63.0", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@doist/cli-core": "0.10.0", + "@doist/todoist-sdk": "10.2.0-next.2", +======= "version": "1.64.0", "hasInstallScript": true, "license": "MIT", "dependencies": { "@doist/cli-core": "0.16.1", "@doist/todoist-sdk": "10.1.5", +>>>>>>> origin/main "@napi-rs/keyring": "1.3.0", "@pnpm/tabtab": "0.5.4", "chalk": "5.6.2", @@ -28,11 +41,19 @@ "@semantic-release/changelog": "6.0.3", "@semantic-release/exec": "7.1.0", "@semantic-release/git": "10.0.1", +<<<<<<< HEAD + "@types/node": "25.6.2", + "conventional-changelog-conventionalcommits": "9.3.1", + "lefthook": "2.1.6", + "oxfmt": "0.48.0", + "oxlint": "1.63.0", +======= "@types/node": "25.7.0", "conventional-changelog-conventionalcommits": "9.3.1", "lefthook": "2.1.6", "oxfmt": "0.49.0", "oxlint": "1.64.0", +>>>>>>> origin/main "semantic-release": "25.0.3", "typescript": "6.0.3", "vitest": "4.1.6" @@ -42,9 +63,9 @@ } }, "node_modules/@actions/core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz", - "integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz", + "integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==", "dev": true, "license": "MIT", "dependencies": { @@ -63,9 +84,9 @@ } }, "node_modules/@actions/http-client": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz", - "integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz", + "integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==", "dev": true, "license": "MIT", "dependencies": { @@ -74,9 +95,9 @@ } }, "node_modules/@actions/http-client/node_modules/undici": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz", - "integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==", + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", + "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", "dev": true, "license": "MIT", "engines": { @@ -136,6 +157,15 @@ } }, "node_modules/@doist/cli-core": { +<<<<<<< HEAD + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@doist/cli-core/-/cli-core-0.10.0.tgz", + "integrity": "sha512-ya/+G0fJ8s+KJxIKsftKUAFGSHKFPGSPfNYJY961xoIuz1F+fm575vesPzWxaCRbmD6Z3vaiXUAxxG7SyfmgLQ==", + "license": "MIT", + "dependencies": { + "chalk": "5.6.2", + "yocto-spinner": "1.1.0" +======= "version": "0.16.1", "resolved": "https://registry.npmjs.org/@doist/cli-core/-/cli-core-0.16.1.tgz", "integrity": "sha512-OoHWYM8Rv+eoPhVR1BUMwFIejZGk5Wyxheva4Cp9x3zTh4RURE+OIJ03G95oBegbXCA2O9LRtZZ9Ww0D6vU1dQ==", @@ -143,13 +173,17 @@ "dependencies": { "chalk": "5.6.2", "yocto-spinner": "1.2.0" +>>>>>>> origin/main }, "engines": { "node": ">=20.18.1" }, +<<<<<<< HEAD +======= "optionalDependencies": { "@napi-rs/keyring": "1.3.0" }, +>>>>>>> origin/main "peerDependencies": { "commander": ">=14", "marked": ">=18", @@ -176,9 +210,15 @@ } }, "node_modules/@doist/todoist-sdk": { +<<<<<<< HEAD + "version": "10.2.0-next.2", + "resolved": "https://registry.npmjs.org/@doist/todoist-sdk/-/todoist-sdk-10.2.0-next.2.tgz", + "integrity": "sha512-DuyAeu8tNe8X9xj11aPPkVKcjPKT/1OMR7aeFn+wvqI97nmd8mffObKse1qlAHwQS2/f+Z02gS6L9hWJYjUmWw==", +======= "version": "10.1.5", "resolved": "https://registry.npmjs.org/@doist/todoist-sdk/-/todoist-sdk-10.1.5.tgz", "integrity": "sha512-32e1D4qMRaGsQJt0IPM/X2eTUpjMjQRRHXK/RDSIRVH2015pTo0oakzA+bUcoIRYy+BfWLGw0d9Gowg2oP+EkA==", +>>>>>>> origin/main "license": "MIT", "dependencies": { "camelcase": "6.3.0", @@ -197,9 +237,9 @@ } }, "node_modules/@emnapi/core": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", - "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "dev": true, "license": "MIT", "optional": true, @@ -209,9 +249,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", - "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "dev": true, "license": "MIT", "optional": true, @@ -1031,9 +1071,9 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz", - "integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "dev": true, "license": "MIT", "optional": true, @@ -1166,15 +1206,16 @@ } }, "node_modules/@octokit/request": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.8.tgz", - "integrity": "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.9.tgz", + "integrity": "sha512-o8Bi3f608eyM+7BmBiUWxFsdjLb3/ym1cQek5LZOv9KkZcxRrHCPhhRzm6xjO6HVZ85ItD6+sTsjxo821SVa/A==", "dev": true, "license": "MIT", "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", + "content-type": "^2.0.0", "fast-content-type-parse": "^3.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" @@ -1207,9 +1248,15 @@ } }, "node_modules/@oxc-project/types": { +<<<<<<< HEAD + "version": "0.129.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.129.0.tgz", + "integrity": "sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg==", +======= "version": "0.124.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz", "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "funding": { @@ -1217,9 +1264,15 @@ } }, "node_modules/@oxfmt/binding-android-arm-eabi": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.48.0.tgz", + "integrity": "sha512-uwqk+/KhQvBIpULD8SMM/zAafMRC/+DV/xsEQjkkIsJ/kLmEI/2bxonVowcYTiXqqZ/a0FEW8DPkZY3VvwELDA==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.49.0.tgz", "integrity": "sha512-HbifJ84prIh9+55CTPAU35JdRQrwg47y16cGerCC+iejSKOuHXYo2WDql6l7cQlzrYVtc3f4UWY+dBj2lRmOeA==", +>>>>>>> origin/main "cpu": [ "arm" ], @@ -1234,9 +1287,15 @@ } }, "node_modules/@oxfmt/binding-android-arm64": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.48.0.tgz", + "integrity": "sha512-VUCiKuXK5+McVssgHEJdrcGK7hRJzrRb36zm9/jwzMholyYt4BgXhw5Nm1V1DX6Ce717Zi/1jk432b/tgmQgtQ==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.49.0.tgz", "integrity": "sha512-Ef7SKJqAaH2d7E6eXZZa2OffIShbhFMxnGK0zd93p4qiyTJr75B0qf7lrPD+qQOwcf04BrjYJ0JUxq8d5+yZwg==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1251,9 +1310,15 @@ } }, "node_modules/@oxfmt/binding-darwin-arm64": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.48.0.tgz", + "integrity": "sha512-IkKp8rnIyQLW6Jt+6jragCbUVYSayk55lapiprLjIVvt4NczLyO/nwX2GgefLQ5iaBdfS8UEAFgCs/pLO6Cl0w==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.49.0.tgz", "integrity": "sha512-8x5DN9CsFfb432sHa9NyqX5XisGUdA53LPEGSdv/VniS+v4uEOR8Orv7A9QSB98Xxgp0t6r31DzQA/wpIobGqQ==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1268,9 +1333,15 @@ } }, "node_modules/@oxfmt/binding-darwin-x64": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.48.0.tgz", + "integrity": "sha512-+aFuhsGIuvnoOjXyKVHMhPKJZR1kQkAl8QyrKoMlA7yJsSTC3N0Asl53La8TChSHhW8epToQ/Q0nvLmEmfNmLg==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.49.0.tgz", "integrity": "sha512-e0+DSVzk4ewhMVKNYDaRTmP81jNMBWR1X9al0cVKWS+hDM/dElNqD5zjTOCuLOZc4oOdp2Gx2ldrVL+yYo9TZQ==", +>>>>>>> origin/main "cpu": [ "x64" ], @@ -1285,9 +1356,15 @@ } }, "node_modules/@oxfmt/binding-freebsd-x64": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.48.0.tgz", + "integrity": "sha512-fbqzQL8FjI9gGnktI7RIo0dksDziTAYBy7xlI7jU7eID5fxLF/25fS4Xj6GydD8Y5oWHL83U4NK160QaOAxtyg==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.49.0.tgz", "integrity": "sha512-W+mjtYtrQvFbXT/uNT+221OBhGRZ8UqNsLxjTWsjZ4GsQnRdvRC/N2NCK86BcamWr7lsTxwpwN3PULnr78sgcQ==", +>>>>>>> origin/main "cpu": [ "x64" ], @@ -1302,9 +1379,15 @@ } }, "node_modules/@oxfmt/binding-linux-arm-gnueabihf": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.48.0.tgz", + "integrity": "sha512-hn4i0zhAyTiB3ZHjQfYUZkDvrbVkohw1S7pySWxWUoZ87HnkDoTFThj7QTxk40hNPOTUP0vHbPRNamFIv1HBJQ==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.49.0.tgz", "integrity": "sha512-Rtv6UevV7czDlLqil+NZUe4d8gs8jQo/zScSpumwyf7I+fSdLc+hc8AF3MQC7ymxSMMD9+vfiqQlsIf7wOAzXA==", +>>>>>>> origin/main "cpu": [ "arm" ], @@ -1319,9 +1402,15 @@ } }, "node_modules/@oxfmt/binding-linux-arm-musleabihf": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.48.0.tgz", + "integrity": "sha512-R4WBD9qF3QM9hqgdAa+fBGXmquTvDUujrPQ36t2Sjk8RPOSKGHDeN7l/khr10hqbQaOq9KCgPHG9ubNET/X/RQ==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.49.0.tgz", "integrity": "sha512-sBi+8C/Q/MdKa5FL8ibAUCdhFBGFH7HFN/Qoyd5xQbZ/0ky3NMPpKfIBpaH0lhK2dXkGLczVQUoZ+xuNSerCdQ==", +>>>>>>> origin/main "cpu": [ "arm" ], @@ -1336,9 +1425,15 @@ } }, "node_modules/@oxfmt/binding-linux-arm64-gnu": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.48.0.tgz", + "integrity": "sha512-5bVdwSwlm1M8wbYCorLOxWxUBw/8tBvHYyQNIfwWVPwOJaj5vg1APSGJQVpwJfV5VNE9PSrR91UKEpoNwHhqUA==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.49.0.tgz", "integrity": "sha512-JIfWenFhlzx+O8YygyZhoHFzTsdgDhxhbDRnE2iJLnnM5pWKScFvPECO2vOlA7JqJ/9S1g3uzEKuRCkHFwTjvA==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1353,9 +1448,15 @@ } }, "node_modules/@oxfmt/binding-linux-arm64-musl": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.48.0.tgz", + "integrity": "sha512-vCS3Fk7gFslTqE1lUE2IlroyVV7u/9SmMA/uBqDoshuck2psGWcjW0ePyPZI3rM3+qtf2pDaMVIKMHozraifuw==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.49.0.tgz", "integrity": "sha512-iNzkMPG18jPkwBOZ4/HEjwqfzAjq4RrUQ0CgId/fC1ENvYD5jLVAaU/gWgpiqP1ys07kxSsSggDd1fp3E7mQHw==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1370,9 +1471,15 @@ } }, "node_modules/@oxfmt/binding-linux-ppc64-gnu": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.48.0.tgz", + "integrity": "sha512-gKtfFfueUClXDumyoHUbymqRf7prHejOOyzJK0eIJn93GF9JBdFHdo60TM1ZBHxkEwZvjuOgHmKtneKbEOc/Eg==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.49.0.tgz", "integrity": "sha512-BPHA/NN3LvoIXiid+iz3BHt5V0Rzx0tXAqRUovwE1NsbDaLG9e8mtv7evDGRIkVQacqTDBv0XL25THHsxSJosQ==", +>>>>>>> origin/main "cpu": [ "ppc64" ], @@ -1387,9 +1494,15 @@ } }, "node_modules/@oxfmt/binding-linux-riscv64-gnu": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.48.0.tgz", + "integrity": "sha512-SYt0UhOvZD/UwZz9sXq6J2uAw8o24f5VZpLB2DH01f6MevshmlgakQlZe2lwek2sZJkd07eLu7mZa0g7yeiw7Q==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.49.0.tgz", "integrity": "sha512-3Eroshe+s69htC9JIL0+zLGQczLtRKezkMhwqQC21VC5Z/fuLvzLfbAOLgJLUq601H8gDYjy7deYycfOBjCvWg==", +>>>>>>> origin/main "cpu": [ "riscv64" ], @@ -1404,9 +1517,15 @@ } }, "node_modules/@oxfmt/binding-linux-riscv64-musl": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.48.0.tgz", + "integrity": "sha512-JLbrwck2AopG4ud/XklZO5N+qxGC7cS7ROvXZVNfx0MCLDDL2kGOLvzuWORkVjnjAM0CMAfIMU2zNBtQbM+4dw==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.49.0.tgz", "integrity": "sha512-fnaERGgsxGm0lKAmO72EYR4BA3qBnzBTJBTi6EtUMq1D4R7EexRBMU4voXnx4TXla3SEDl9x4uNp/18SbkPjGg==", +>>>>>>> origin/main "cpu": [ "riscv64" ], @@ -1421,9 +1540,15 @@ } }, "node_modules/@oxfmt/binding-linux-s390x-gnu": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.48.0.tgz", + "integrity": "sha512-mdxt5L8OQLxkQH+JVpdC/lknZNe0lX4hlO3d8+xvw2wToo+iDrid9tiGOd5bmHfUVd5wVhrUry0qlu5vq66NkQ==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.49.0.tgz", "integrity": "sha512-rBwasMl1Uul1MCCeTGEFKnOTL7VUxHf+634jWStrQAbzpBJgd5Yz5m4F7exVCsoI8PHn57dNjssXagXLCLB5yA==", +>>>>>>> origin/main "cpu": [ "s390x" ], @@ -1438,9 +1563,15 @@ } }, "node_modules/@oxfmt/binding-linux-x64-gnu": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.48.0.tgz", + "integrity": "sha512-oEz1BQwMrV7OMEFx/3VPDU3n9TM0AnxpktDYXjEg5i6nTX87wo18wSfBvkl4tzAICdKtoAQAdBIl7Y7hsPlx5w==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.49.0.tgz", "integrity": "sha512-BoC/F9xHe2y/deuBGA5Aw7bes07OD2gcL2wlpzTrfImR92vPP7S/k3LBTyspQZCNIVNdagkELcqKELwMLGIfAg==", +>>>>>>> origin/main "cpu": [ "x64" ], @@ -1455,9 +1586,15 @@ } }, "node_modules/@oxfmt/binding-linux-x64-musl": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.48.0.tgz", + "integrity": "sha512-g2SKTTurP5mWjd8Ecait0erYqmltL4IqW1EwttM25BxM6NiTt4ubobJYMR1uox1V2QgG4UfHH10CGRvWlUixjw==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.49.0.tgz", "integrity": "sha512-umY6jFADAo/oztFKl8D/S6vSrG6oBpEskcentiRuz42kZVU2kfDXMWCYavxyZR2bwPjqkHpcHZ6EZFiH3Qj9ZA==", +>>>>>>> origin/main "cpu": [ "x64" ], @@ -1472,9 +1609,15 @@ } }, "node_modules/@oxfmt/binding-openharmony-arm64": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.48.0.tgz", + "integrity": "sha512-CIg24VgheEpvolHL2gQuax5qcQ602bRMHrJ9g8XsQr3iVj9aSPgopigBKuMqrXsupwkrU+RQCn5cG8PgFntR6w==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.49.0.tgz", "integrity": "sha512-J85zQMiw2pXiGPK+OusmDvSnJ/dgpgN7VgmB2zOBtgS8F+nsOUfSg9ZEBrwbQscjZ7tkPbm38CG4VF5f53MsiA==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1489,9 +1632,15 @@ } }, "node_modules/@oxfmt/binding-win32-arm64-msvc": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.48.0.tgz", + "integrity": "sha512-zeaWkcxcEULwkGF3I/HgEvcDPN8buYDrxibBUa/IFh5Vmwyge+KpLO+hEwSovW349H0O/C0Z2kaFmEzEDm00/Q==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.49.0.tgz", "integrity": "sha512-38K67XR++CoFFORDd4sMFwUVAnD6msYBdGTei+qvKGrRPO6S2PbrYPNL/eQQ1RgnnxOegNba0YQwg6uRkNcw6A==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1506,9 +1655,15 @@ } }, "node_modules/@oxfmt/binding-win32-ia32-msvc": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.48.0.tgz", + "integrity": "sha512-yiEKnIAGvx5CyZQOlMaNlZkAbwT7/Quk0j3WLt+PR5hK+qYjPTRRJYDfD77wCBPLvEYAG41v4KG3iL0H+uxoxg==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.49.0.tgz", "integrity": "sha512-rXVe0HICwQF0dBgbQtBCoYf8x/SidPIdhyQl+iPuJlV7suV+qDv7yUEB3wQ4qC3nOeNxz287SwFXKzyr0kWgEg==", +>>>>>>> origin/main "cpu": [ "ia32" ], @@ -1523,9 +1678,15 @@ } }, "node_modules/@oxfmt/binding-win32-x64-msvc": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.48.0.tgz", + "integrity": "sha512-GSD2+7t2UoVMV2NgxXypa4bKewflPMAjYnF0Xw9/ht82ZfafAHhb8STwrEd7wlH2PFogt5zw3WVCxYJaHUdbeQ==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.49.0.tgz", "integrity": "sha512-gwWLwSEmBBfIK/Wh7GGd658161o4RKAvHWRaRQbJm571iQXGKfyr7UKsI1vsWvDlNLc30CxJDc8mMmCvJ/kczQ==", +>>>>>>> origin/main "cpu": [ "x64" ], @@ -1540,9 +1701,15 @@ } }, "node_modules/@oxlint/binding-android-arm-eabi": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.63.0.tgz", + "integrity": "sha512-A9xLtQt7i0OA1PoB/meog6kikXI9CdwEp7ZwQqmgnpKn3G3b1orvTDy8CQ6T7w1HvDrgWGB78PkFKcWgibcTCg==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.64.0.tgz", "integrity": "sha512-2r6Nq3XXGLHEXKkSj8JtmJ6N4gDw431DPFOg0ZoJHlNjnG6HVMm/ksQ10m0HJ8WBvwgMe1L50UHPaYZutCRPCw==", +>>>>>>> origin/main "cpu": [ "arm" ], @@ -1557,9 +1724,15 @@ } }, "node_modules/@oxlint/binding-android-arm64": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.63.0.tgz", + "integrity": "sha512-SQo+ZMvdR9l3CxZp5W5gFNxSiDxclY6lOzzNpKYLF8asESpm3Pwumx0gER5T7aHLF1/2BAAtLD3DiDkdgy4V1A==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.64.0.tgz", "integrity": "sha512-ePJMpePgg7fBv+L/hVx1xXRU5/5gd5m0obLA6hPEfLXF3GjpR8idIDbY1dhQYhyz1ms2wdTccSboo6KEd2Oxtg==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1574,9 +1747,15 @@ } }, "node_modules/@oxlint/binding-darwin-arm64": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.63.0.tgz", + "integrity": "sha512-6W82XjJDTmMnjg30427l0dufpnyLoq7wEukKdM6/g2VIybRVuQiBVh43EA4b+UxZ3+tLcKm+Or/pXGNgLCEU8g==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.64.0.tgz", "integrity": "sha512-U4DMLQd10gJLuoSTLSGbfv3bGjTlUNsScm9Dgb8wwBqmCzidf1pE1pXV4doGNxqwH3KtVng1AGTINA0NvkGLvQ==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1591,9 +1770,15 @@ } }, "node_modules/@oxlint/binding-darwin-x64": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.63.0.tgz", + "integrity": "sha512-CnWd/YCuVG5W1BYkjJEVbJG11o526O9qAwBEQM+nh8K19CRFUkFdROXCyYkGmroHEYQe4vgQ6+lh3550Lp35Xw==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.64.0.tgz", "integrity": "sha512-GoRIL48QWm4/TAvjN8pB1nAG+1/uqc9EdnWT9zqHeb6wsmjZtywj8VRe5aGW47Fdb64YtLOsdLqVxOvQuz98Wg==", +>>>>>>> origin/main "cpu": [ "x64" ], @@ -1608,9 +1793,15 @@ } }, "node_modules/@oxlint/binding-freebsd-x64": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.63.0.tgz", + "integrity": "sha512-a4eZAqrmtajqcxfdAzC+l7g3PaE3V8hpAYqqeD3fTxLXOMFdK3eNTZrU80n4dDEVm0JXy1aL5PqvqWldBl6zYA==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.64.0.tgz", "integrity": "sha512-5dFkv4tkg7PxJJGS9/OjrJwjhuHczrd3OQOkRE0wHcLM+ncUnULtzEPWjqGOxTXxZnLWcB91bGiIznx89TVXyQ==", +>>>>>>> origin/main "cpu": [ "x64" ], @@ -1625,9 +1816,15 @@ } }, "node_modules/@oxlint/binding-linux-arm-gnueabihf": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.63.0.tgz", + "integrity": "sha512-tYUtU9TdbU3uXF5D62g5zXJ13iniFGhXQx5vp9cyEjGdbSAY3VdFBSaldYvyoDmgMZ0ZYuwQP1Y4t2Fhejwa0w==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.64.0.tgz", "integrity": "sha512-jsBqMLl/uOL5+Kq/+BtK9FrmiNGUbx8SiyZXv+WlUxA45KuwcLu9BfiSIL3I3DBDgWM3yZizDITnTK9BcqNBQg==", +>>>>>>> origin/main "cpu": [ "arm" ], @@ -1642,9 +1839,15 @@ } }, "node_modules/@oxlint/binding-linux-arm-musleabihf": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.63.0.tgz", + "integrity": "sha512-I5r3twFf776UZg9dmRo2xbrKt00tTkORXEVe0ctg4vdTkQvJAjiCHxnbAU2HL1AiJ9cqADA76MAliuilsAWnvg==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.64.0.tgz", "integrity": "sha512-1lrj8At/Uuc9GhjrVFBQo0NEjfBrTkzpmtHIGAhNnIXqn1CAyGL+qrztUsXb2GIluJrpl9Q7qRLJOb/NqydacQ==", +>>>>>>> origin/main "cpu": [ "arm" ], @@ -1659,9 +1862,15 @@ } }, "node_modules/@oxlint/binding-linux-arm64-gnu": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.63.0.tgz", + "integrity": "sha512-t7ltUkg6FFh4b564QyGir8xIj/QZbXu8FlcRkcyW9+ztr/mfRHlvUOFd95pJCXi9s/L5DrUeWWgpXRS+V+6igQ==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.64.0.tgz", "integrity": "sha512-HpSQbubwh03mMhAdy2BYtad/fsY8vDFHDAb6bUwuCYg2VD3xCQgn6ArKcO0oZyLCheacKTv4PrF3Mfu5hgoE2g==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1676,9 +1885,15 @@ } }, "node_modules/@oxlint/binding-linux-arm64-musl": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.63.0.tgz", + "integrity": "sha512-Q5mmZy/XWjuYFUuQyYjOvZ5U/JkKEwnpir6hGxhh6HcdP0V/BKxLo8dqkfF/t7r7AguB17dfS/8+go5AQDRR6g==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.64.0.tgz", "integrity": "sha512-00QQ0h0Y7u0G69BgiH3+ky2aaq/QvkDL6DYok8htIuJHxybiux5aQ8jwmg8qIk9wha6UagUP2BAwAzbemcJbpg==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1693,9 +1908,15 @@ } }, "node_modules/@oxlint/binding-linux-ppc64-gnu": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.63.0.tgz", + "integrity": "sha512-uBGtuZ0TzLB4x5wVa82HGNvYqY8buwDhyCnCP0R0gkk9szqVsP0MeTtD5HX7EsEuFIt+aYmYxuxeVxs3nTSwtQ==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.64.0.tgz", "integrity": "sha512-2GaimTV6EMW+s5HS0An3oGbQme3BgHswvfVdGk3EB57Xe9+/gyT+Qd7lNVzb3rtir52vbIPzXfaYArzs5b5zcw==", +>>>>>>> origin/main "cpu": [ "ppc64" ], @@ -1710,9 +1931,15 @@ } }, "node_modules/@oxlint/binding-linux-riscv64-gnu": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.63.0.tgz", + "integrity": "sha512-h4s6FwxE+9MeA181o0dnDwHP32Y/bG8EiB/vrD6Ib+AMt6haigDc/0bUtI/sLmQDBMJnUfaCmtSSrEAqjtEVrA==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.64.0.tgz", "integrity": "sha512-H46AtFb9wypjoVwGdlxrm0DsD809NGmtiK9HiyPKTxkSte2YjhC4S+00rOIrwCaxcyPiGid3Y3OMXp5KMAkGZw==", +>>>>>>> origin/main "cpu": [ "riscv64" ], @@ -1727,9 +1954,15 @@ } }, "node_modules/@oxlint/binding-linux-riscv64-musl": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.63.0.tgz", + "integrity": "sha512-2EaNcCBR8Mcjl5ARtuN3BdEpVkX7KpjSjMGZ/mJMIeaXgTtdz5ytg2VwygMSStA/k0ixfvZFoZOfjDEcouV5vQ==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.64.0.tgz", "integrity": "sha512-HEgsidjjvvyzdg82icYkuFCf7REDV7B9JFwbIMbVwrKLBY0MrXX+bku3POn/hduZ2yW91IyVDUMq0Bf02KwXQw==", +>>>>>>> origin/main "cpu": [ "riscv64" ], @@ -1744,9 +1977,15 @@ } }, "node_modules/@oxlint/binding-linux-s390x-gnu": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.63.0.tgz", + "integrity": "sha512-p4hlf/fd7TrYYl3QrWWD0GocqJefwMu3cHQhmi2FvEB/YOvFb5DZN3SMBaPi7B1TM5DeypkEtrVib674q1KKPg==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.64.0.tgz", "integrity": "sha512-Axvm8qryotmKN00P5w4JapaSjvP2LOSbdbBJiX+2SuHd3QzhW7TUc8skqgw+ahQZ5DmzEYeHCqauvW8f32Ns6Q==", +>>>>>>> origin/main "cpu": [ "s390x" ], @@ -1761,9 +2000,15 @@ } }, "node_modules/@oxlint/binding-linux-x64-gnu": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.63.0.tgz", + "integrity": "sha512-Vgq9rkRVcPcjbcH+ihYTfpeR7vCXfqpd+z5ItTGc0yYUV59L5ceHYN1iV4H9bKGV7Rn5hkVc7x3mSvHegduENA==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.64.0.tgz", "integrity": "sha512-cR60vSd7+m+KRZ3GQGfDxWwahW5RMXg0qlGvAluZr0fTUYvw0H9N9AXAF/M/PMqgytyqvVNmBAkJG9l7U30Y1g==", +>>>>>>> origin/main "cpu": [ "x64" ], @@ -1778,9 +2023,15 @@ } }, "node_modules/@oxlint/binding-linux-x64-musl": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.63.0.tgz", + "integrity": "sha512-3/Lkq/ncooA61rorrC+ZQed1Bc4VpGj+WnGsp58zmxKgvZ2vhreu+dcVyr3mX8NUpq7mfZ4gDDTou/yrF1Pd7A==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.64.0.tgz", "integrity": "sha512-2u/aPZ9pEg7HnvZPDsHxUGNnrpr4qaHi+mCgLgpt+LYRzPrS4Px4wPfkIdRdr2GvKnaYyt+XSlto0Vm5sbStTg==", +>>>>>>> origin/main "cpu": [ "x64" ], @@ -1795,9 +2046,15 @@ } }, "node_modules/@oxlint/binding-openharmony-arm64": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.63.0.tgz", + "integrity": "sha512-0/EdD/6hDkx5Mfd769PTjvEM8mZ/6Dfukp1dBCL/2PjlIVGEtYdNZyok6ChqYPsT9JcFnlQnUeQzO0/1L/oC9w==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.64.0.tgz", "integrity": "sha512-kfhkGfCdoXLSxEkrhDlJrvBYajGmq+ma4EMc53dsOWTq+rIBOlI0vTBmpZNnM5oH2LY/K/w1HAK+UQEgjgpVUg==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1812,9 +2069,15 @@ } }, "node_modules/@oxlint/binding-win32-arm64-msvc": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.63.0.tgz", + "integrity": "sha512-wb0CUkN8ngwPiRQBjD1Cj0LsHeNvm+Xt6YBHDMtj2DVQVD6Oj8Ri7g6BD+KICf6LaBqZlmzOvy6nF9E/8yyGOg==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.64.0.tgz", "integrity": "sha512-r/cNKBFieONoVu2bb1KkVouq9W+edDUgHumXJGphCRRj+U0xaD4nanrw8ZOqo0IsutPkEM4vCcGBpak6x5aXMg==", +>>>>>>> origin/main "cpu": [ "arm64" ], @@ -1829,9 +2092,15 @@ } }, "node_modules/@oxlint/binding-win32-ia32-msvc": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.63.0.tgz", + "integrity": "sha512-BX5iq+ovdNlVYhSn5qPMUIT0uwAwt2lmEnCnzK+Gkhw4DovIvhGb96OFhV8yzQNUnQxn/xGkOR+X+BLrLDNm8w==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.64.0.tgz", "integrity": "sha512-tUw0xUUwEFVZbpJoeCblkv8SJA4Xz3CdXCJbAnBsiNLyxDrk2tLcxEAS6M73Q7hHHDg3OtwI8vZVK3t5RJt4Gw==", +>>>>>>> origin/main "cpu": [ "ia32" ], @@ -1846,9 +2115,15 @@ } }, "node_modules/@oxlint/binding-win32-x64-msvc": { +<<<<<<< HEAD + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.63.0.tgz", + "integrity": "sha512-QeN/WELOfsXMeYwxvfgQrl6CbVftYUCZsGXHjXQd5Trccm8+i4gmtxaOui4xbJQaiDlviF8F3yLSBloQUeFsfA==", +======= "version": "1.64.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.64.0.tgz", "integrity": "sha512-9CBR+LO0JVST87fNTzzNxS5I29jIUO5gxT9i9+M3SDHHALElj9sY1Prf12tad3vIRC6OD7Ehtvvh+sn13vSwHw==", +>>>>>>> origin/main "cpu": [ "x64" ], @@ -1923,9 +2198,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0.tgz", + "integrity": "sha512-TWMZnRLMe63C2Lhyicviu7ZHaU4kxa6PS3rofvc9GmcvptzNN11BcfQ4Sl7MwTOsisQoa2keB/EBdNCAnUo8vA==", "cpu": [ "arm64" ], @@ -1940,9 +2215,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0.tgz", + "integrity": "sha512-6XcD+8k0gPVItNagEw78/qqcBDwKcwDYS8V2hRmVsfUSIrd8cWe/CBvRDI5toqFyPfj+FJr6t8U6Xj2P2prEew==", "cpu": [ "arm64" ], @@ -1957,9 +2232,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz", - "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0.tgz", + "integrity": "sha512-iN/tWVXRQDWvmZlKdceP1Dwug9GDpEymhb9p4xnEe6zvCg5lFmzVljl+1qR1NVx3yfGpr2Na+CuLmv5IU8uzfQ==", "cpu": [ "x64" ], @@ -1974,9 +2249,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz", - "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0.tgz", + "integrity": "sha512-jjQMDvvwSOuhOwMszD/klSOjyWMM3zI64hWTj9KT5x4MxRbZAf+7vLQ6qouRhtsLVFHr3f0ILaJAfgENPiQdAQ==", "cpu": [ "x64" ], @@ -1991,9 +2266,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz", - "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0.tgz", + "integrity": "sha512-d//Dtg2x6/m3mbV64yUGNnDGNZaDGRpDLLNGerHQUVObuNaIQaaDp25yUiqGXtHEXX+NP2d0wAlmKgpYgIAJ2A==", "cpu": [ "arm" ], @@ -2008,9 +2283,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0.tgz", + "integrity": "sha512-n7Ofp0mx+aB2cC+Sdy5YtMnXtY9lchnHbY+3Yt0uq9JsWQExf4f5Whu0tK0R8Jdc9S6RchTHjIFY7uc92puOVQ==", "cpu": [ "arm64" ], @@ -2025,9 +2300,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz", - "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0.tgz", + "integrity": "sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA==", "cpu": [ "arm64" ], @@ -2042,9 +2317,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0.tgz", + "integrity": "sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg==", "cpu": [ "ppc64" ], @@ -2059,9 +2334,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0.tgz", + "integrity": "sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA==", "cpu": [ "s390x" ], @@ -2076,9 +2351,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0.tgz", + "integrity": "sha512-Dfn7iak9BcMMePxcoJfpSbWqnEyrp/dRF63/8qW/eHBdOZov6x5aShLLEYGYdIeSJ6vMLK/XCVB+lGIxm41bQA==", "cpu": [ "x64" ], @@ -2093,9 +2368,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz", - "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0.tgz", + "integrity": "sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw==", "cpu": [ "x64" ], @@ -2110,9 +2385,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0.tgz", + "integrity": "sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig==", "cpu": [ "arm64" ], @@ -2127,9 +2402,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz", - "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0.tgz", + "integrity": "sha512-E+oHKGiDA+lsKMmFtffDDw91EryDT7uJocrIuCHqhm6bCTM6xFK+3gaCkYOHfPwQr0cCNarSM2xaELoQDz9jJg==", "cpu": [ "wasm32" ], @@ -2137,18 +2412,18 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "1.9.2", - "@emnapi/runtime": "1.9.2", - "@napi-rs/wasm-runtime": "^1.1.3" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { - "node": ">=14.0.0" + "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz", - "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0.tgz", + "integrity": "sha512-yYK02n8Rngo+gbm1y6G0+7jk1sJ/2Wt7K0me0Y7k/ErBpyf+LJ2gFpqWVTcRV1rUepBlQRmpgWkTQCiiwrK0Ow==", "cpu": [ "arm64" ], @@ -2163,9 +2438,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz", - "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0.tgz", + "integrity": "sha512-14bpChMahXRRXiTwahSl+zzHPW6qQTXtkMuJBFlbo+pqSAews2d4BdCSHfrJ/MBsCZtpmTafsY+1QhBzitcmdg==", "cpu": [ "x64" ], @@ -2180,9 +2455,15 @@ } }, "node_modules/@rolldown/pluginutils": { +<<<<<<< HEAD + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0.tgz", + "integrity": "sha512-aKs/3GSWyV0mrhNmt/96/Z3yczC3yvrzYATCiCXQebBsGyYzjNdUphRVLeJQ67ySKVXRfMxt2lm12pmXvbPFQQ==", +======= "version": "1.0.0-rc.15", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz", "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==", +>>>>>>> origin/main "devOptional": true, "license": "MIT" }, @@ -2275,187 +2556,139 @@ "node": ">=18" } }, - "node_modules/@semantic-release/exec/node_modules/execa": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", - "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "node_modules/@semantic-release/git": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", + "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", "dev": true, "license": "MIT", "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.6", - "figures": "^6.1.0", - "get-stream": "^9.0.0", - "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" + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^5.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" }, "engines": { - "node": "^18.19.0 || >=20.5.0" + "node": ">=14.17" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "peerDependencies": { + "semantic-release": ">=18.0.0" } }, - "node_modules/@semantic-release/exec/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "node_modules/@semantic-release/git/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "license": "MIT", "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/exec/node_modules/human-signals": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", - "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@semantic-release/exec/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "node_modules/@semantic-release/git/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/exec/node_modules/npm-run-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", - "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "node_modules/@semantic-release/git/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0", - "unicorn-magic": "^0.3.0" - }, + "license": "Apache-2.0", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10.17.0" } }, - "node_modules/@semantic-release/exec/node_modules/parse-json": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", - "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "node_modules/@semantic-release/git/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.26.2", - "index-to-position": "^1.1.0", - "type-fest": "^4.39.1" - }, "engines": { - "node": ">=18" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/exec/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/@semantic-release/git/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "path-key": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/exec/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/@semantic-release/exec/node_modules/strip-final-newline": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", - "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "node_modules/@semantic-release/git/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, "engines": { - "node": ">=18" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/exec/node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "node_modules/@semantic-release/git/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "ISC" }, - "node_modules/@semantic-release/git": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", - "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", + "node_modules/@semantic-release/git/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, "license": "MIT", - "dependencies": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "debug": "^4.0.0", - "dir-glob": "^3.0.0", - "execa": "^5.0.0", - "lodash": "^4.17.4", - "micromatch": "^4.0.0", - "p-reduce": "^2.0.0" - }, "engines": { - "node": ">=14.17" - }, - "peerDependencies": { - "semantic-release": ">=18.0.0" + "node": ">=6" } }, "node_modules/@semantic-release/github": { - "version": "12.0.6", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-12.0.6.tgz", - "integrity": "sha512-aYYFkwHW3c6YtHwQF0t0+lAjlU+87NFOZuH2CvWFD0Ylivc7MwhZMiHOJ0FMpIgPpCVib/VUAcOwvrW0KnxQtA==", + "version": "12.0.8", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-12.0.8.tgz", + "integrity": "sha512-tej5AAgK5X9wHRoDmYhecMXEHEkFeGOY1XsEblKxu8pIQwahzf1STYyr7iPU6Lpbg6C5I3N2w/ocXrBo+L7jhw==", "dev": true, "license": "MIT", "dependencies": { @@ -2467,8 +2700,8 @@ "aggregate-error": "^5.0.0", "debug": "^4.3.4", "dir-glob": "^3.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", + "http-proxy-agent": "^9.0.0", + "https-proxy-agent": "^9.0.0", "issue-parser": "^7.0.0", "lodash-es": "^4.17.21", "mime": "^4.0.0", @@ -2613,90 +2846,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/execa": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", - "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "node_modules/@semantic-release/npm/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, "license": "MIT", - "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.6", - "figures": "^6.1.0", - "get-stream": "^9.0.0", - "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" - }, "engines": { - "node": "^18.19.0 || >=20.5.0" + "node": ">=12" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/human-signals": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", - "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/normalize-url": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-9.0.0.tgz", - "integrity": "sha512-z9nC87iaZXXySbWWtTHfCFJyFvKaUAW6lODhikG7ILSbVgmwuFjUqkgnheHvAUcGedO29e2QGBRXMUD64aurqQ==", + "node_modules/@semantic-release/npm/node_modules/normalize-url": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-9.0.0.tgz", + "integrity": "sha512-z9nC87iaZXXySbWWtTHfCFJyFvKaUAW6lODhikG7ILSbVgmwuFjUqkgnheHvAUcGedO29e2QGBRXMUD64aurqQ==", "dev": true, "license": "MIT", "engines": { @@ -2706,79 +2872,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/npm-run-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", - "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0", - "unicorn-magic": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@semantic-release/npm/node_modules/strip-final-newline": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", - "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@semantic-release/release-notes-generator": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.1.0.tgz", - "integrity": "sha512-CcyDRk7xq+ON/20YNR+1I/jP7BYKICr1uKd1HHpROSnnTdGqOTburi4jcRiTYz0cpfhxSloQO3cGhnoot7IEkA==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.1.1.tgz", + "integrity": "sha512-Pbd2e2XRMUD0OxehHpgd5/YghsE76cddkRHSoDvKLK+OCy4Ewxn49rWR631MEUU01lgwF/uyVXvbnVuu6+Z6VA==", "dev": true, "license": "MIT", "dependencies": { @@ -2787,9 +2884,7 @@ "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", - "get-stream": "^7.0.0", "import-from-esm": "^2.0.0", - "into-stream": "^7.0.0", "lodash-es": "^4.17.21", "read-package-up": "^11.0.0" }, @@ -2800,19 +2895,6 @@ "semantic-release": ">=20.1.0" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", - "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@semantic-release/release-notes-generator/node_modules/hosted-git-info": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", @@ -2848,24 +2930,6 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/parse-json": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", - "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.26.2", - "index-to-position": "^1.1.0", - "type-fest": "^4.39.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@semantic-release/release-notes-generator/node_modules/read-package-up": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", @@ -2904,6 +2968,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@semantic-release/release-notes-generator/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@semantic-release/release-notes-generator/node_modules/unicorn-magic": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", @@ -2986,9 +3063,9 @@ "license": "MIT" }, "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", "dev": true, "license": "MIT", "optional": true, @@ -3015,9 +3092,15 @@ "license": "MIT" }, "node_modules/@types/estree": { +<<<<<<< HEAD + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", +======= "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", +>>>>>>> origin/main "devOptional": true, "license": "MIT" }, @@ -3028,9 +3111,15 @@ "license": "MIT" }, "node_modules/@types/node": { +<<<<<<< HEAD + "version": "25.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.2.tgz", + "integrity": "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw==", +======= "version": "25.7.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.7.0.tgz", "integrity": "sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg==", +>>>>>>> origin/main "dev": true, "license": "MIT", "dependencies": { @@ -3045,9 +3134,15 @@ "license": "MIT" }, "node_modules/@vitest/expect": { +<<<<<<< HEAD + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.5.tgz", + "integrity": "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==", +======= "version": "4.1.6", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.6.tgz", "integrity": "sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "dependencies": { @@ -3063,9 +3158,15 @@ } }, "node_modules/@vitest/mocker": { +<<<<<<< HEAD + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.5.tgz", + "integrity": "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==", +======= "version": "4.1.6", "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.6.tgz", "integrity": "sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "dependencies": { @@ -3090,9 +3191,15 @@ } }, "node_modules/@vitest/pretty-format": { +<<<<<<< HEAD + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.5.tgz", + "integrity": "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==", +======= "version": "4.1.6", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.6.tgz", "integrity": "sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "dependencies": { @@ -3103,9 +3210,15 @@ } }, "node_modules/@vitest/runner": { +<<<<<<< HEAD + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.5.tgz", + "integrity": "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==", +======= "version": "4.1.6", "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.6.tgz", "integrity": "sha512-nOPCmn2+yD0ZNmKdsXGv/UxMMWbMuKeD6GyYncNwdkYDxpQvrPSKYj2rWuDjC2Y4b6w6hjip5dBKFzEUuZe3vA==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "dependencies": { @@ -3117,9 +3230,15 @@ } }, "node_modules/@vitest/snapshot": { +<<<<<<< HEAD + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.5.tgz", + "integrity": "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==", +======= "version": "4.1.6", "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.6.tgz", "integrity": "sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "dependencies": { @@ -3133,9 +3252,15 @@ } }, "node_modules/@vitest/spy": { +<<<<<<< HEAD + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.5.tgz", + "integrity": "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==", +======= "version": "4.1.6", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.6.tgz", "integrity": "sha512-JFKxMx6udhwKh/Ldo270e17QX710vgunMkuPAvXjHSvC6oqLWAHhVhjg/I71q0u0CBSErIODV1Kjv0FQNSWjdg==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "funding": { @@ -3143,9 +3268,15 @@ } }, "node_modules/@vitest/utils": { +<<<<<<< HEAD + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.5.tgz", + "integrity": "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==", +======= "version": "4.1.6", "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.6.tgz", "integrity": "sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "dependencies": { @@ -3158,22 +3289,22 @@ } }, "node_modules/@xmldom/xmldom": { - "version": "0.8.13", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", - "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz", + "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==", "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=14.6" } }, "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", "dev": true, "license": "MIT", "engines": { - "node": ">= 14" + "node": ">= 20" } }, "node_modules/aggregate-error": { @@ -3303,6 +3434,104 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/app-path/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/app-path/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/app-path/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/app-path/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/app-path/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/app-path/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/app-path/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/app-path/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3423,6 +3652,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/boxen/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -3473,15 +3714,15 @@ } }, "node_modules/cacheable-request": { - "version": "13.0.18", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-13.0.18.tgz", - "integrity": "sha512-rFWadDRKJs3s2eYdXlGggnBZKG7MTblkFBB0YllFds+UYnfogDp2wcR6JN97FhRkHTvq59n2vhNoHNZn29dh/Q==", + "version": "13.0.19", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-13.0.19.tgz", + "integrity": "sha512-SVXGH037+Mo1aIMO5B2UcleR43FGjFdN+M8JObSyEoQ2Mn4CODRWx28gN5jiTF0n5ItsgtIZfyargMNs8GX4kg==", "license": "MIT", "dependencies": { - "@types/http-cache-semantics": "^4.0.4", + "@types/http-cache-semantics": "^4.2.0", "get-stream": "^9.0.1", "http-cache-semantics": "^4.2.0", - "keyv": "^5.5.5", + "keyv": "^5.6.0", "mimic-response": "^4.0.0", "normalize-url": "^8.1.1", "responselike": "^4.0.2" @@ -3490,34 +3731,6 @@ "node": ">=18" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "license": "MIT", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -3871,6 +4084,20 @@ "proto-list": "~1.2.1" } }, + "node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/conventional-changelog-angular": { "version": "8.3.1", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.1.tgz", @@ -3984,18 +4211,37 @@ "parse-json": "^5.2.0" }, "engines": { - "node": ">=14" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cross-spawn": { @@ -4359,19 +4605,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/env-ci/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/env-ci/node_modules/strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -4436,9 +4669,15 @@ } }, "node_modules/es-module-lexer": { +<<<<<<< HEAD + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", +======= "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", +>>>>>>> origin/main "devOptional": true, "license": "MIT" }, @@ -4502,23 +4741,27 @@ } }, "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "dev": true, "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "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" }, "engines": { - "node": ">=10" + "node": "^18.19.0 || >=20.5.0" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" @@ -4671,21 +4914,10 @@ "node": ">= 18" } }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, "node_modules/fs-extra": { - "version": "11.3.4", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", - "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz", + "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==", "dev": true, "license": "MIT", "dependencies": { @@ -4744,9 +4976,9 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", - "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", "license": "MIT", "engines": { "node": ">=18" @@ -4793,12 +5025,16 @@ } }, "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4867,6 +5103,18 @@ "url": "https://github.com/sindresorhus/got?sponsor=1" } }, + "node_modules/got/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4970,9 +5218,9 @@ } }, "node_modules/hosted-git-info": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", + "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", "dev": true, "license": "ISC", "dependencies": { @@ -4989,17 +5237,17 @@ "license": "BSD-2-Clause" }, "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-9.0.0.tgz", + "integrity": "sha512-FcF8VhXYLQcxWCnt/cCpT2apKsRDUGeVEeMqGu4HSTu29U8Yw0TLOjdYIlDsYk3IkUh+taX4IDWpPcCqKDhCjA==", "dev": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.0", + "agent-base": "9.0.0", "debug": "^4.3.4" }, "engines": { - "node": ">= 14" + "node": ">= 20" } }, "node_modules/http2-wrapper": { @@ -5016,26 +5264,27 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.0.0.tgz", + "integrity": "sha512-/MVmHp58WkOypgFhCLk4fzpPcFQvTJ/e6LBI7irpIO2HfxUbpmYoHF+KzipzJpxxzJu7aJNWQ0xojJ/dzV2G5g==", "dev": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" + "agent-base": "9.0.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 14" + "node": ">= 20" } }, "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "dev": true, "license": "Apache-2.0", "engines": { - "node": ">=10.17.0" + "node": ">=18.18.0" } }, "node_modules/ieee754": { @@ -5059,9 +5308,9 @@ "license": "BSD-3-Clause" }, "node_modules/image-dimensions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/image-dimensions/-/image-dimensions-2.5.0.tgz", - "integrity": "sha512-CKZPHjAEtSg9lBV9eER0bhNn/yrY7cFEQEhkwjLhqLY+Na8lcP1pEyWsaGMGc8t2qbKWA/tuqbhFQpOKGN72Yw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/image-dimensions/-/image-dimensions-2.5.1.tgz", + "integrity": "sha512-It7CkTNp7IYA8jhvGgz8K18OAbHF3/Juk8RNEyTyMFfolJOIU1Y2wGDnzDQPbGCjyxVF/++pwIZE0BKJUEOb1g==", "license": "MIT", "bin": { "image-dimensions": "cli.js" @@ -5177,23 +5426,6 @@ "dev": true, "license": "ISC" }, - "node_modules/into-stream": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", - "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "from2": "^2.3.0", - "p-is-promise": "^3.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -5295,12 +5527,12 @@ } }, "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5348,9 +5580,9 @@ "license": "ISC" }, "node_modules/issue-parser": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.1.tgz", - "integrity": "sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.2.tgz", + "integrity": "sha512-7atWPjhGEIX3JEtMrOYd8TKzboYlq+5sNbdl9POiLYOI14G5HZiQbZP0Xj5EZdrufQVXfJlpTV0hys0CuxwxZw==", "dev": true, "license": "MIT", "dependencies": { @@ -5476,9 +5708,9 @@ "license": "MIT" }, "node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -6042,9 +6274,9 @@ } }, "node_modules/log-update/node_modules/string-width": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", - "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", "license": "MIT", "dependencies": { "get-east-asian-width": "^1.5.0", @@ -6102,9 +6334,9 @@ } }, "node_modules/lru-cache": { - "version": "11.3.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", - "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -6139,6 +6371,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/make-asynchronous/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/marked": { "version": "18.0.3", "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.3.tgz", @@ -6310,9 +6555,15 @@ } }, "node_modules/nanoid": { +<<<<<<< HEAD + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", +======= "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", +>>>>>>> origin/main "devOptional": true, "funding": [ { @@ -6397,9 +6648,9 @@ } }, "node_modules/npm": { - "version": "11.12.1", - "resolved": "https://registry.npmjs.org/npm/-/npm-11.12.1.tgz", - "integrity": "sha512-zcoUuF1kezGSAo0CqtvoLXX3mkRqzuqYdL6Y5tdo8g69NVV3CkjQ6ZBhBgB4d7vGkPcV6TcvLi3GRKPDFX+xTA==", + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/npm/-/npm-11.14.1.tgz", + "integrity": "sha512-aopNZ0eEl6LbxoFcrXLmTEPzNBNxfiQnVgR9RmJBqzm+5h5pFoOmRljpRJbsXxocBeSl7GLcx3MoDf2UlEOjZw==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -6478,8 +6729,8 @@ ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^9.4.2", - "@npmcli/config": "^10.8.1", + "@npmcli/arborist": "^9.5.0", + "@npmcli/config": "^10.9.0", "@npmcli/fs": "^5.0.0", "@npmcli/map-workspaces": "^5.0.3", "@npmcli/metavuln-calculator": "^9.0.3", @@ -6500,24 +6751,24 @@ "hosted-git-info": "^9.0.2", "ini": "^6.0.0", "init-package-json": "^8.2.5", - "is-cidr": "^6.0.3", + "is-cidr": "^6.0.4", "json-parse-even-better-errors": "^5.0.0", "libnpmaccess": "^10.0.3", - "libnpmdiff": "^8.1.5", - "libnpmexec": "^10.2.5", - "libnpmfund": "^7.0.19", + "libnpmdiff": "^8.1.7", + "libnpmexec": "^10.2.7", + "libnpmfund": "^7.0.21", "libnpmorg": "^8.0.1", - "libnpmpack": "^9.1.5", + "libnpmpack": "^9.1.7", "libnpmpublish": "^11.1.3", "libnpmsearch": "^9.0.1", "libnpmteam": "^8.0.2", "libnpmversion": "^8.0.3", "make-fetch-happen": "^15.0.5", - "minimatch": "^10.2.4", + "minimatch": "^10.2.5", "minipass": "^7.1.3", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^12.2.0", + "node-gyp": "^12.3.0", "nopt": "^9.0.0", "npm-audit-report": "^7.0.0", "npm-install-checks": "^8.0.0", @@ -6536,7 +6787,7 @@ "spdx-expression-parse": "^4.0.0", "ssri": "^13.0.1", "supports-color": "^10.2.2", - "tar": "^7.5.11", + "tar": "^7.5.13", "text-table": "~0.2.0", "tiny-relative-date": "^2.0.2", "treeverse": "^3.0.0", @@ -6552,15 +6803,33 @@ } }, "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.0.0" + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/npm/node_modules/@gar/promise-retry": { @@ -6607,7 +6876,7 @@ } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "9.4.2", + "version": "9.5.0", "dev": true, "inBundle": true, "license": "ISC", @@ -6655,7 +6924,7 @@ } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "10.8.1", + "version": "10.9.0", "dev": true, "inBundle": true, "license": "ISC", @@ -6858,7 +7127,7 @@ } }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.5.0", + "version": "0.5.1", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -7000,7 +7269,7 @@ } }, "node_modules/npm/node_modules/brace-expansion": { - "version": "5.0.4", + "version": "5.0.5", "dev": true, "inBundle": true, "license": "MIT", @@ -7069,7 +7338,7 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "5.0.3", + "version": "5.0.5", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -7125,7 +7394,7 @@ } }, "node_modules/npm/node_modules/diff": { - "version": "8.0.3", + "version": "8.0.4", "dev": true, "inBundle": true, "license": "BSD-3-Clause", @@ -7292,7 +7561,7 @@ } }, "node_modules/npm/node_modules/ip-address": { - "version": "10.1.0", + "version": "10.1.1", "dev": true, "inBundle": true, "license": "MIT", @@ -7301,12 +7570,12 @@ } }, "node_modules/npm/node_modules/is-cidr": { - "version": "6.0.3", + "version": "6.0.4", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "cidr-regex": "^5.0.1" + "cidr-regex": "^5.0.4" }, "engines": { "node": ">=20" @@ -7374,12 +7643,12 @@ } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "8.1.5", + "version": "8.1.7", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^9.4.2", + "@npmcli/arborist": "^9.5.0", "@npmcli/installed-package-contents": "^4.0.0", "binary-extensions": "^3.0.0", "diff": "^8.0.2", @@ -7393,13 +7662,13 @@ } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "10.2.5", + "version": "10.2.7", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@gar/promise-retry": "^1.0.0", - "@npmcli/arborist": "^9.4.2", + "@npmcli/arborist": "^9.5.0", "@npmcli/package-json": "^7.0.0", "@npmcli/run-script": "^10.0.0", "ci-info": "^4.0.0", @@ -7416,12 +7685,12 @@ } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "7.0.19", + "version": "7.0.21", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^9.4.2" + "@npmcli/arborist": "^9.5.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" @@ -7441,12 +7710,12 @@ } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "9.1.5", + "version": "9.1.7", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^9.4.2", + "@npmcli/arborist": "^9.5.0", "@npmcli/run-script": "^10.0.0", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2" @@ -7516,7 +7785,7 @@ } }, "node_modules/npm/node_modules/lru-cache": { - "version": "11.2.7", + "version": "11.3.5", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -7548,12 +7817,12 @@ } }, "node_modules/npm/node_modules/minimatch": { - "version": "10.2.4", + "version": "10.2.5", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -7601,35 +7870,17 @@ } }, "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", + "version": "1.0.6", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.1.3" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/npm/node_modules/minipass-flush/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/minipass-pipeline": { "version": "1.2.4", "dev": true, @@ -7709,7 +7960,7 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "12.2.0", + "version": "12.3.0", "dev": true, "inBundle": true, "license": "MIT", @@ -7717,12 +7968,12 @@ "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^15.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "tar": "^7.5.4", "tinyglobby": "^0.2.12", + "undici": "^6.25.0", "which": "^6.0.0" }, "bin": { @@ -8095,12 +8346,12 @@ } }, "node_modules/npm/node_modules/socks": { - "version": "2.8.7", + "version": "2.8.8", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ip-address": "^10.0.1", + "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -8169,7 +8420,7 @@ } }, "node_modules/npm/node_modules/tar": { - "version": "7.5.11", + "version": "7.5.13", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -8197,13 +8448,13 @@ "license": "MIT" }, "node_modules/npm/node_modules/tinyglobby": { - "version": "0.2.15", + "version": "0.2.16", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -8230,7 +8481,7 @@ } }, "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", + "version": "4.0.4", "dev": true, "inBundle": true, "license": "MIT", @@ -8264,6 +8515,15 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/npm/node_modules/undici": { + "version": "6.25.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/npm/node_modules/util-deprecate": { "version": "1.0.2", "dev": true, @@ -8351,15 +8611,15 @@ "license": "MIT" }, "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "license": "MIT", "dependencies": { - "mimic-fn": "^2.1.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">=6" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8386,9 +8646,15 @@ } }, "node_modules/oxfmt": { +<<<<<<< HEAD + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.48.0.tgz", + "integrity": "sha512-AVaLh+7XeGx+R1zfFV+f6VV61nT2MWVJXVUDhbTm5LBWGyNt64xAyh3NYYyjeY2WykNt9AvqSQLPHcbWquYF9g==", +======= "version": "0.49.0", "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.49.0.tgz", "integrity": "sha512-IAHFMdlJSWe+oAr65dx22UvjCtV9DBMisAuLnKpDqMQrctzCkGnj3QRwNHm0d+uwSWPalsDF8ZYLz9rh6nH2IQ==", +>>>>>>> origin/main "dev": true, "license": "MIT", "dependencies": { @@ -8404,6 +8670,33 @@ "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { +<<<<<<< HEAD + "@oxfmt/binding-android-arm-eabi": "0.48.0", + "@oxfmt/binding-android-arm64": "0.48.0", + "@oxfmt/binding-darwin-arm64": "0.48.0", + "@oxfmt/binding-darwin-x64": "0.48.0", + "@oxfmt/binding-freebsd-x64": "0.48.0", + "@oxfmt/binding-linux-arm-gnueabihf": "0.48.0", + "@oxfmt/binding-linux-arm-musleabihf": "0.48.0", + "@oxfmt/binding-linux-arm64-gnu": "0.48.0", + "@oxfmt/binding-linux-arm64-musl": "0.48.0", + "@oxfmt/binding-linux-ppc64-gnu": "0.48.0", + "@oxfmt/binding-linux-riscv64-gnu": "0.48.0", + "@oxfmt/binding-linux-riscv64-musl": "0.48.0", + "@oxfmt/binding-linux-s390x-gnu": "0.48.0", + "@oxfmt/binding-linux-x64-gnu": "0.48.0", + "@oxfmt/binding-linux-x64-musl": "0.48.0", + "@oxfmt/binding-openharmony-arm64": "0.48.0", + "@oxfmt/binding-win32-arm64-msvc": "0.48.0", + "@oxfmt/binding-win32-ia32-msvc": "0.48.0", + "@oxfmt/binding-win32-x64-msvc": "0.48.0" + } + }, + "node_modules/oxlint": { + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.63.0.tgz", + "integrity": "sha512-9TGXetdjgIHOJ9OiReomP7nnrMkV9HxC1xM2ramJSLQpzxjsAJtQwa4wqkJN2f/uCrqZuJseFuSlWDdvcruveg==", +======= "@oxfmt/binding-android-arm-eabi": "0.49.0", "@oxfmt/binding-android-arm64": "0.49.0", "@oxfmt/binding-darwin-arm64": "0.49.0", @@ -8437,6 +8730,7 @@ "version": "1.64.0", "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.64.0.tgz", "integrity": "sha512-Star3SNpWPeWFPw7kRXIhXUSn6fdiAl25q15CQzH/9WaOtG6e9CWTc25vNZOCr4PE1yEP1GtKJKIKglhj3OmEQ==", +>>>>>>> origin/main "dev": true, "license": "MIT", "bin": { @@ -8449,6 +8743,27 @@ "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { +<<<<<<< HEAD + "@oxlint/binding-android-arm-eabi": "1.63.0", + "@oxlint/binding-android-arm64": "1.63.0", + "@oxlint/binding-darwin-arm64": "1.63.0", + "@oxlint/binding-darwin-x64": "1.63.0", + "@oxlint/binding-freebsd-x64": "1.63.0", + "@oxlint/binding-linux-arm-gnueabihf": "1.63.0", + "@oxlint/binding-linux-arm-musleabihf": "1.63.0", + "@oxlint/binding-linux-arm64-gnu": "1.63.0", + "@oxlint/binding-linux-arm64-musl": "1.63.0", + "@oxlint/binding-linux-ppc64-gnu": "1.63.0", + "@oxlint/binding-linux-riscv64-gnu": "1.63.0", + "@oxlint/binding-linux-riscv64-musl": "1.63.0", + "@oxlint/binding-linux-s390x-gnu": "1.63.0", + "@oxlint/binding-linux-x64-gnu": "1.63.0", + "@oxlint/binding-linux-x64-musl": "1.63.0", + "@oxlint/binding-openharmony-arm64": "1.63.0", + "@oxlint/binding-win32-arm64-msvc": "1.63.0", + "@oxlint/binding-win32-ia32-msvc": "1.63.0", + "@oxlint/binding-win32-x64-msvc": "1.63.0" +======= "@oxlint/binding-android-arm-eabi": "1.64.0", "@oxlint/binding-android-arm64": "1.64.0", "@oxlint/binding-darwin-arm64": "1.64.0", @@ -8468,6 +8783,7 @@ "@oxlint/binding-win32-arm64-msvc": "1.64.0", "@oxlint/binding-win32-ia32-msvc": "1.64.0", "@oxlint/binding-win32-x64-msvc": "1.64.0" +>>>>>>> origin/main }, "peerDependencies": { "oxlint-tsgolint": ">=0.22.1" @@ -8532,16 +8848,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-is-promise": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", - "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -8656,19 +8962,31 @@ } }, "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=8" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8810,12 +9128,12 @@ } }, "node_modules/plist": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", - "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.1.tgz", + "integrity": "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==", "license": "MIT", "dependencies": { - "@xmldom/xmldom": "^0.8.8", + "@xmldom/xmldom": "^0.9.10", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" }, @@ -8833,9 +9151,15 @@ } }, "node_modules/postcss": { +<<<<<<< HEAD + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", +======= "version": "8.5.12", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.12.tgz", "integrity": "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==", +>>>>>>> origin/main "devOptional": true, "funding": [ { @@ -8949,22 +9273,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-package-up/node_modules/type-fest": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", - "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/read-pkg": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", @@ -8985,46 +9293,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg/node_modules/parse-json": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", - "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "node_modules/read-pkg/node_modules/unicorn-magic": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.26.2", - "index-to-position": "^1.1.0", - "type-fest": "^4.39.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg/node_modules/parse-json/node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", - "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, "engines": { "node": ">=20" }, @@ -9117,42 +9391,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/rolldown": { +<<<<<<< HEAD + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0.tgz", + "integrity": "sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA==", +======= "version": "1.0.0-rc.15", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz", "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.124.0", - "@rolldown/pluginutils": "1.0.0-rc.15" + "@oxc-project/types": "=0.129.0", + "@rolldown/pluginutils": "1.0.0" }, "bin": { "rolldown": "bin/cli.mjs" @@ -9161,21 +9414,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-rc.15", - "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", - "@rolldown/binding-darwin-x64": "1.0.0-rc.15", - "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", - "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", - "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", - "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" + "@rolldown/binding-android-arm64": "1.0.0", + "@rolldown/binding-darwin-arm64": "1.0.0", + "@rolldown/binding-darwin-x64": "1.0.0", + "@rolldown/binding-freebsd-x64": "1.0.0", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0", + "@rolldown/binding-linux-arm64-gnu": "1.0.0", + "@rolldown/binding-linux-arm64-musl": "1.0.0", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0", + "@rolldown/binding-linux-s390x-gnu": "1.0.0", + "@rolldown/binding-linux-x64-gnu": "1.0.0", + "@rolldown/binding-linux-x64-musl": "1.0.0", + "@rolldown/binding-openharmony-arm64": "1.0.0", + "@rolldown/binding-wasm32-wasi": "1.0.0", + "@rolldown/binding-win32-arm64-msvc": "1.0.0", + "@rolldown/binding-win32-x64-msvc": "1.0.0" } }, "node_modules/run-applescript": { @@ -9307,45 +9560,14 @@ "node": ">=20" } }, - "node_modules/semantic-release/node_modules/execa": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", - "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.6", - "figures": "^6.1.0", - "get-stream": "^9.0.0", - "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" - }, - "engines": { - "node": "^18.19.0 || >=20.5.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/semantic-release/node_modules/execa/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "node_modules/semantic-release/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "license": "MIT", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9361,16 +9583,6 @@ "node": ">=8" } }, - "node_modules/semantic-release/node_modules/human-signals": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", - "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, "node_modules/semantic-release/node_modules/indent-string": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", @@ -9384,19 +9596,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/semantic-release/node_modules/marked": { "version": "15.0.12", "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", @@ -9432,23 +9631,6 @@ "marked": ">=1 <16" } }, - "node_modules/semantic-release/node_modules/npm-run-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", - "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0", - "unicorn-magic": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/semantic-release/node_modules/p-reduce": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", @@ -9462,32 +9644,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/semantic-release/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", @@ -9504,19 +9660,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/semantic-release/node_modules/strip-final-newline": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", - "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/semantic-release/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -9547,19 +9690,6 @@ "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, - "node_modules/semantic-release/node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/semantic-release/node_modules/yargs": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", @@ -9589,9 +9719,9 @@ } }, "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -9643,10 +9773,16 @@ "license": "ISC" }, "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/signale": { "version": "1.4.0", @@ -9872,9 +10008,15 @@ "license": "MIT" }, "node_modules/std-env": { +<<<<<<< HEAD + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", + "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", +======= "version": "4.0.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", +>>>>>>> origin/main "devOptional": true, "license": "MIT" }, @@ -9963,12 +10105,16 @@ } }, "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-json-comments": { @@ -10059,7 +10205,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", - "dev": true, "license": "MIT", "engines": { "node": ">=20" @@ -10238,9 +10383,15 @@ "license": "MIT" }, "node_modules/tinyexec": { +<<<<<<< HEAD + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", + "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", +======= "version": "1.1.1", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.1.tgz", "integrity": "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "engines": { @@ -10387,12 +10538,15 @@ } }, "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", + "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, "engines": { - "node": ">=16" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -10439,9 +10593,9 @@ } }, "node_modules/undici": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.8.tgz", - "integrity": "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", "license": "MIT", "engines": { "node": ">=20.18.1" @@ -10464,13 +10618,13 @@ } }, "node_modules/unicorn-magic": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", - "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", "dev": true, "license": "MIT", "engines": { - "node": ">=20" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -10569,17 +10723,23 @@ } }, "node_modules/vite": { +<<<<<<< HEAD + "version": "8.0.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.12.tgz", + "integrity": "sha512-w2dDofOWv2QB09ZITZBsvKTVAlYvPR4IAmrY/v0ir9KvLs0xybR7i48wxhM1/oyBWO34wPns+bPGw5ZrZqDpZg==", +======= "version": "8.0.8", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.8.tgz", "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", - "postcss": "^8.5.8", - "rolldown": "1.0.0-rc.15", - "tinyglobby": "^0.2.15" + "postcss": "^8.5.14", + "rolldown": "1.0.0", + "tinyglobby": "^0.2.16" }, "bin": { "vite": "bin/vite.js" @@ -10595,7 +10755,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.1.0", + "@vitejs/devtools": "^0.1.18", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", @@ -10660,9 +10820,15 @@ } }, "node_modules/vitest": { +<<<<<<< HEAD + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.5.tgz", + "integrity": "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==", +======= "version": "4.1.6", "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.6.tgz", "integrity": "sha512-6lvjbS3p9b4CrdCmguzbh2/4uoXhGE2q71R4OX5sqF9R1bo9Xd6fGrMAfvp5wnCzlBnFVdCOp6onuTQVbo8iUQ==", +>>>>>>> origin/main "devOptional": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 0cd02f17..b51361d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,10 @@ { "name": "@doist/todoist-cli", +<<<<<<< HEAD + "version": "1.63.0", +======= "version": "1.64.0", +>>>>>>> origin/main "description": "TypeScript CLI for Todoist", "type": "module", "main": "dist/index.js", @@ -51,8 +55,13 @@ "CHANGELOG.md" ], "dependencies": { +<<<<<<< HEAD + "@doist/cli-core": "0.10.0", + "@doist/todoist-sdk": "10.2.0-next.2", +======= "@doist/cli-core": "0.16.1", "@doist/todoist-sdk": "10.1.5", +>>>>>>> origin/main "@napi-rs/keyring": "1.3.0", "@pnpm/tabtab": "0.5.4", "chalk": "5.6.2", @@ -66,11 +75,19 @@ "@semantic-release/changelog": "6.0.3", "@semantic-release/exec": "7.1.0", "@semantic-release/git": "10.0.1", +<<<<<<< HEAD + "@types/node": "25.6.2", + "conventional-changelog-conventionalcommits": "9.3.1", + "lefthook": "2.1.6", + "oxfmt": "0.48.0", + "oxlint": "1.63.0", +======= "@types/node": "25.7.0", "conventional-changelog-conventionalcommits": "9.3.1", "lefthook": "2.1.6", "oxfmt": "0.49.0", "oxlint": "1.64.0", +>>>>>>> origin/main "semantic-release": "25.0.3", "typescript": "6.0.3", "vitest": "4.1.6" diff --git a/skills/todoist-cli/SKILL.md b/skills/todoist-cli/SKILL.md index 838e3150..bd8a2762 100644 --- a/skills/todoist-cli/SKILL.md +++ b/skills/todoist-cli/SKILL.md @@ -5,7 +5,11 @@ compatibility: "Requires the td CLI (@doist/todoist-cli) to be installed and aut license: MIT metadata: author: Doist +<<<<<<< HEAD + version: "1.63.0" +======= version: "1.64.0" +>>>>>>> origin/main --- # Todoist CLI (td) @@ -88,6 +92,7 @@ Resolution order: `--user ` > `user.defaultUser` from config > the only sto - Task lifecycle: `td task list/view/add/quickadd/update/reschedule/move/complete/uncomplete/delete/browse` (alias: `td task qa` for `quickadd`) - Projects: `td project list/view/create/update/archive/unarchive/archived/delete/move/reorder/join/browse/collaborators/permissions` - Project analytics: `td project progress/health/health-context/activity-stats/analyze-health` +- Goals: `td goal list/view/create/update/delete/complete/uncomplete/link/unlink` - Organization: `td label ...`, `td filter ...`, `td section ...`, `td folder ...`, `td workspace ...` - Collaboration: `td comment ...`, `td notification ...`, `td reminder ...` - Templates and files: `td template ...`, `td attachment view `, `td backup ...` @@ -230,6 +235,25 @@ td section browse id:123 Shared labels can appear in `td label list` and `td label view`, but standard update and delete actions only work for labels with IDs. Use `td label rename-shared` and `td label remove-shared` for shared labels. +### Goals +```bash +td goal list # List all accessible goals +td goal list --workspace "Work" # Filter to workspace goals +td goal view "Ship v2" # View goal details and linked tasks +td goal create --name "Ship v2" # Create personal goal +td goal create --name "Ship v2" --workspace "Work" # Create workspace goal +td goal create --name "Ship v2" --deadline "2026-04-03" +td goal create --name "Ship v2" --json # Return created goal as JSON +td goal create --name "Ship v2" --dry-run # Preview creation +td goal update "Ship v2" --name "Ship v3" +td goal update "Ship v2" --description "New desc" --json +td goal delete "Ship v2" --yes +td goal complete "Ship v2" # Mark goal as completed +td goal uncomplete "Ship v2" # Reopen a completed goal +td goal link "Ship v2" --task "Buy milk" # Link a task to a goal +td goal unlink "Ship v2" --task "Buy milk" # Unlink a task from a goal +``` + ### Comments, Attachments, Notifications, And Reminders ```bash td comment list "Plan sprint" diff --git a/src/commands/auth/auth.test.ts b/src/commands/auth/auth.test.ts index 4954d580..0b9738d1 100644 --- a/src/commands/auth/auth.test.ts +++ b/src/commands/auth/auth.test.ts @@ -72,8 +72,23 @@ vi.mock('node:readline', () => ({ import { createInterface, type Interface } from 'node:readline' import { createApiForToken, getApi } from '../../lib/api/core.js' import type { TodoistAccount, TodoistTokenStore } from '../../lib/auth-store.js' +<<<<<<< HEAD +import { + NoTokenError, + TOKEN_ENV_VAR, + clearApiToken, + getAuthMetadata, + listStoredUsers, + readConfig, + resolveActiveUser, + upsertUser, +} from '../../lib/auth.js' +import { resetGlobalArgs } from '../../lib/global-args.js' +import { UserNotFoundError } from '../../lib/users.js' +======= import { NoTokenError, getAuthMetadata, listStoredUsers, readConfig } from '../../lib/auth.js' import { resetGlobalArgs } from '../../lib/global-args.js' +>>>>>>> origin/main import { createMockApi } from '../../test-support/mock-api.js' import { registerAuthCommand } from './index.js' import { attachTodoistStatusCommand } from './status.js' @@ -83,6 +98,7 @@ const mockCreateInterface = vi.mocked(createInterface) const mockGetAuthMetadata = vi.mocked(getAuthMetadata) const mockListStoredUsers = vi.mocked(listStoredUsers) const mockReadConfig = vi.mocked(readConfig) +const mockResolveActiveUser = vi.mocked(resolveActiveUser) const mockGetApi = vi.mocked(getApi) const mockCreateApiForToken = vi.mocked(createApiForToken) @@ -342,10 +358,13 @@ describe('auth command', () => { }, async set() {}, async clear() {}, +<<<<<<< HEAD +======= async list() { return [{ account: SNAPSHOT_ACCOUNT, isDefault: true }] }, async setDefault() {}, +>>>>>>> origin/main getLastStorageResult: () => undefined, getLastClearResult: () => undefined, } @@ -426,6 +445,9 @@ describe('auth command', () => { 'system credential manager unavailable; token cleared from plaintext config.json', } +<<<<<<< HEAD + it('clears the API token', async () => { +======= beforeEach(() => { clearMock.mockReset().mockResolvedValue(undefined) lastClearMock.mockReset().mockReturnValue({ storage: 'secure-store' }) @@ -434,11 +456,48 @@ describe('auth command', () => { }) it('surfaces keyring-fallback warning to stderr', async () => { +>>>>>>> origin/main const program = createProgram() lastClearMock.mockReturnValue(WARNING_RESULT) await program.parseAsync(['node', 'td', 'auth', 'logout']) +<<<<<<< HEAD + expect(mockClearApiToken).toHaveBeenCalled() + expect(consoleSpy).toHaveBeenCalledWith('✓ Logged out') + }) + + it('surfaces keyring-fallback warning to stderr in plain mode', async () => { + const program = createProgram() + mockClearApiToken.mockResolvedValue(WARNING_RESULT) + + await program.parseAsync(['node', 'td', 'auth', 'logout']) + + expect(consoleSpy).toHaveBeenCalledWith('✓ Logged out') + expect(errorSpy).toHaveBeenCalledWith('Warning:', WARNING_RESULT.warning) + }) + + it('routes warning to stderr and emits JSON envelope on stdout in --json mode', async () => { + const program = createProgram() + mockClearApiToken.mockResolvedValue(WARNING_RESULT) + + await program.parseAsync(['node', 'td', 'auth', 'logout', '--json']) + + const stdoutLines = consoleSpy.mock.calls.map((c: unknown[]) => String(c[0])) + expect(stdoutLines).toEqual([JSON.stringify({ ok: true }, null, 2)]) + // Plain "Stored token removed" confirmation must be suppressed under --json. + expect(stdoutLines.join('\n')).not.toContain('Stored token removed') + expect(errorSpy).toHaveBeenCalledWith('Warning:', WARNING_RESULT.warning) + }) + + it('routes warning to stderr and keeps stdout silent in --ndjson mode', async () => { + const program = createProgram() + mockClearApiToken.mockResolvedValue(WARNING_RESULT) + + await program.parseAsync(['node', 'td', 'auth', 'logout', '--ndjson']) + + expect(consoleSpy).not.toHaveBeenCalled() +======= expect(errorSpy).toHaveBeenCalledWith('Warning:', WARNING_RESULT.warning) }) @@ -504,11 +563,77 @@ describe('auth command', () => { const stdout = consoleSpy.mock.calls.map((c: unknown[]) => String(c[0])).join('\n') expect(stdout).toContain('"ok": true') expect(stdout).not.toContain('Stored token removed') +>>>>>>> origin/main expect(errorSpy).toHaveBeenCalledWith('Warning:', WARNING_RESULT.warning) }) }) describe('token view subcommand', () => { +<<<<<<< HEAD + let originalEnvToken: string | undefined + + beforeEach(() => { + originalEnvToken = process.env[TOKEN_ENV_VAR] + delete process.env[TOKEN_ENV_VAR] + }) + + afterEach(() => { + if (originalEnvToken === undefined) { + delete process.env[TOKEN_ENV_VAR] + } else { + process.env[TOKEN_ENV_VAR] = originalEnvToken + } + }) + + it('prints the bare token to stdout', async () => { + const program = createProgram() + mockResolveActiveUser.mockResolvedValue({ + id: TEST_USER.id, + email: TEST_USER.email, + token: 'stored_token_abc123456', + authMode: 'read-write', + source: 'secure-store', + }) + + await program.parseAsync(['node', 'td', 'auth', 'token', 'view']) + + expect(mockResolveActiveUser).toHaveBeenCalled() + expect(consoleSpy).toHaveBeenCalledTimes(1) + expect(consoleSpy).toHaveBeenCalledWith('stored_token_abc123456') + }) + + it('refuses when TODOIST_API_TOKEN is set', async () => { + const program = createProgram() + process.env[TOKEN_ENV_VAR] = 'env_token_value' + + await expect( + program.parseAsync(['node', 'td', 'auth', 'token', 'view']), + ).rejects.toHaveProperty('code', 'TOKEN_FROM_ENV') + expect(mockResolveActiveUser).not.toHaveBeenCalled() + expect(consoleSpy).not.toHaveBeenCalled() + }) + + it('propagates NoTokenError when no users are stored', async () => { + const program = createProgram() + mockResolveActiveUser.mockRejectedValue(new NoTokenError()) + + await expect( + program.parseAsync(['node', 'td', 'auth', 'token', 'view']), + ).rejects.toHaveProperty('code', 'NO_TOKEN') + expect(consoleSpy).not.toHaveBeenCalled() + }) + + it('propagates UserNotFoundError when --user ref does not match', async () => { + const program = createProgram() + mockResolveActiveUser.mockRejectedValue(new UserNotFoundError('missing@example.com')) + + // `--user ` is parsed from process.argv by the global-args + // layer (not commander) and stripped before commander sees the + // argv. Stub process.argv to mirror production wiring so the + // test exercises the same code path as a real invocation. + const originalArgv = process.argv + process.argv = ['node', 'td', 'auth', 'token', 'view', '--user', 'missing@example.com'] +======= // `attachTokenViewCommand`'s bare-token output, TOKEN_FROM_ENV // refusal, and NOT_AUTHENTICATED on no-snapshot are all tested in // cli-core. The wrap's `--user` injection is exercised here because @@ -542,16 +667,101 @@ describe('auth command', () => { const program = createProgram() const originalArgv = process.argv process.argv = ['node', 'td', '--user', 'nobody@example.com', 'auth', 'token', 'view'] +>>>>>>> origin/main resetGlobalArgs() try { await expect( program.parseAsync(['node', 'td', 'auth', 'token', 'view']), ).rejects.toHaveProperty('code', 'USER_NOT_FOUND') +<<<<<<< HEAD +======= expect(activeMock).not.toHaveBeenCalled() +>>>>>>> origin/main + } finally { + process.argv = originalArgv + resetGlobalArgs() + } +<<<<<<< HEAD + expect(consoleSpy).not.toHaveBeenCalled() + }) + }) + + describe('token view subcommand', () => { + let originalEnvToken: string | undefined + + beforeEach(() => { + originalEnvToken = process.env[TOKEN_ENV_VAR] + delete process.env[TOKEN_ENV_VAR] + }) + + afterEach(() => { + if (originalEnvToken === undefined) { + delete process.env[TOKEN_ENV_VAR] + } else { + process.env[TOKEN_ENV_VAR] = originalEnvToken + } + }) + + it('prints the bare token to stdout', async () => { + const program = createProgram() + mockResolveActiveUser.mockResolvedValue({ + id: TEST_USER.id, + email: TEST_USER.email, + token: 'stored_token_abc123456', + authMode: 'read-write', + source: 'secure-store', + }) + + await program.parseAsync(['node', 'td', 'auth', 'token', 'view']) + + expect(mockResolveActiveUser).toHaveBeenCalled() + expect(consoleSpy).toHaveBeenCalledTimes(1) + expect(consoleSpy).toHaveBeenCalledWith('stored_token_abc123456') + }) + + it('refuses when TODOIST_API_TOKEN is set', async () => { + const program = createProgram() + process.env[TOKEN_ENV_VAR] = 'env_token_value' + + await expect( + program.parseAsync(['node', 'td', 'auth', 'token', 'view']), + ).rejects.toHaveProperty('code', 'TOKEN_FROM_ENV') + expect(mockResolveActiveUser).not.toHaveBeenCalled() + expect(consoleSpy).not.toHaveBeenCalled() + }) + + it('propagates NoTokenError when no users are stored', async () => { + const program = createProgram() + mockResolveActiveUser.mockRejectedValue(new NoTokenError()) + + await expect( + program.parseAsync(['node', 'td', 'auth', 'token', 'view']), + ).rejects.toHaveProperty('code', 'NO_TOKEN') + expect(consoleSpy).not.toHaveBeenCalled() + }) + + it('propagates UserNotFoundError when --user ref does not match', async () => { + const program = createProgram() + mockResolveActiveUser.mockRejectedValue(new UserNotFoundError('missing@example.com')) + + // `--user ` is parsed from process.argv by the global-args + // layer (not commander) and stripped before commander sees the + // argv. Stub process.argv to mirror production wiring so the + // test exercises the same code path as a real invocation. + const originalArgv = process.argv + process.argv = ['node', 'td', 'auth', 'token', 'view', '--user', 'missing@example.com'] + resetGlobalArgs() + try { + await expect( + program.parseAsync(['node', 'td', 'auth', 'token', 'view']), + ).rejects.toHaveProperty('code', 'USER_NOT_FOUND') } finally { process.argv = originalArgv resetGlobalArgs() } + expect(consoleSpy).not.toHaveBeenCalled() +======= +>>>>>>> origin/main }) }) }) diff --git a/src/commands/auth/index.ts b/src/commands/auth/index.ts index a8924b9a..4ee16f1b 100644 --- a/src/commands/auth/index.ts +++ b/src/commands/auth/index.ts @@ -1,3 +1,11 @@ +<<<<<<< HEAD +import type { Command } from 'commander' +import { createTodoistTokenStore } from '../../lib/auth-store.js' +import { attachTodoistLoginCommand } from './login.js' +import { attachTodoistLogoutCommand } from './logout.js' +import { attachTodoistStatusCommand } from './status.js' +import { viewToken } from './token-view.js' +======= import { attachTokenViewCommand } from '@doist/cli-core/auth' import type { Command } from 'commander' import { createTodoistTokenStore, TOKEN_ENV_VAR } from '../../lib/auth-store.js' @@ -5,11 +13,34 @@ import { attachTodoistLoginCommand } from './login.js' import { attachTodoistLogoutCommand } from './logout.js' import { attachTodoistStatusCommand } from './status.js' import { withUserRefAware } from './store-wrap.js' +>>>>>>> origin/main import { loginWithToken } from './token.js' export function registerAuthCommand(program: Command): void { const auth = program.command('auth').description('Manage authentication') +<<<<<<< HEAD + // Shared store instance: login stashes the post-`set` storage result for + // its success handler, logout reads the post-`clear` result for the same + // keyring-fallback warning surface. Status uses `active()` as the + // authenticated-snapshot gate. + const store = createTodoistTokenStore() + + attachTodoistLoginCommand(auth, store) + attachTodoistLogoutCommand(auth, store) + attachTodoistStatusCommand(auth, store) + + // `token` is a hybrid: it accepts a positional `[token]` (save) and also + // exposes subcommands (`view`). Commander matches subcommand names before + // falling through to the parent action, so `td auth token view` always + // dispatches to the `view` subcommand — `view` is never treated as a + // literal token value. Real Todoist tokens are 40-char hex strings, so + // this disambiguation is safe in practice. + // + // `token view` stays hand-rolled (not migrated to `attachTokenViewCommand`) + // because it depends on the `--user ` selector + env precedence rules + // that the `TokenStore` adapter intentionally drops from `active()`. +======= // Two stores share storage but expose different reads: // - `store` is the raw cli-core `TokenStore` — login uses it to `set()`, // status uses `active()` (with env-token short-circuit) as the @@ -30,11 +61,20 @@ export function registerAuthCommand(program: Command): void { // subcommand prints. Commander matches the subcommand name before the // parent action, so `td auth token view` always dispatches to the view // path — Todoist tokens are 40-char hex so the disambiguation is safe. +>>>>>>> origin/main const tokenCmd = auth .command('token [token]') .description('Save API token for CLI authentication (or use a subcommand: `view`)') .action(loginWithToken) +<<<<<<< HEAD + tokenCmd + .command('view') + .description( + 'Print the stored API token for the active user (or --user ) to stdout for use in scripts', + ) + .action(viewToken) +======= attachTokenViewCommand(tokenCmd, { name: 'view', store: refAware, @@ -42,4 +82,5 @@ export function registerAuthCommand(program: Command): void { description: 'Print the stored API token for the active user (or --user ) to stdout for use in scripts', }) +>>>>>>> origin/main } diff --git a/src/commands/auth/logout.ts b/src/commands/auth/logout.ts index 46274354..112f920b 100644 --- a/src/commands/auth/logout.ts +++ b/src/commands/auth/logout.ts @@ -4,11 +4,19 @@ import type { TodoistAccount, TodoistTokenStore } from '../../lib/auth-store.js' import { logTokenStorageResult } from './helpers.js' /** +<<<<<<< HEAD + * Attach `td auth logout` via cli-core's generic `attachLogoutCommand`. The + * registrar emits the success line (`✓ Logged out` / `{ok:true}` / silent + * ndjson); `onCleared` only surfaces the keyring-fallback warning carried by + * `TokenStorageResult` — cli-core's `TokenStore.clear: void` contract can't + * expose it directly, so we stash it on the adapter (`getLastClearResult`). +======= * `td auth logout`. cli-core owns the success line + `--json` / `--ndjson` * envelopes; the Todoist hook surfaces the keyring-fallback warning that * cli-core's `TokenStore.clear: void` contract can't carry. The `--user * ` injection lives on the wrapped store the caller passes in (see * `withUserRefAware` in `store-wrap.ts`). +>>>>>>> origin/main */ export function attachTodoistLogoutCommand(auth: Command, store: TodoistTokenStore): Command { return attachLogoutCommand(auth, { diff --git a/src/commands/auth/token-view.ts b/src/commands/auth/token-view.ts new file mode 100644 index 00000000..ecd2ecd0 --- /dev/null +++ b/src/commands/auth/token-view.ts @@ -0,0 +1,18 @@ +import { resolveActiveUser, TOKEN_ENV_VAR } from '../../lib/auth.js' +import { CliError } from '../../lib/errors.js' + +export async function viewToken(): Promise { + if (process.env[TOKEN_ENV_VAR]) { + throw new CliError( + 'TOKEN_FROM_ENV', + `Refusing to print token: ${TOKEN_ENV_VAR} is set in the environment.`, + [ + `The token is already available in your environment as $${TOKEN_ENV_VAR}.`, + `Unset ${TOKEN_ENV_VAR} to print the stored token instead.`, + ], + ) + } + + const resolved = await resolveActiveUser() + console.log(resolved.token) +} diff --git a/src/commands/config/view.ts b/src/commands/config/view.ts index f67e6e10..35e81dd1 100644 --- a/src/commands/config/view.ts +++ b/src/commands/config/view.ts @@ -9,6 +9,10 @@ import { TOKEN_ENV_VAR, } from '../../lib/auth.js' import { type Config, getConfigPath, readConfigStrict } from '../../lib/config.js' +<<<<<<< HEAD +import { SECURE_STORE_DESCRIPTION, SecureStoreUnavailableError } from '../../lib/secure-store.js' +======= +>>>>>>> origin/main import { getDefaultUserId, NoUserSelectedError } from '../../lib/users.js' const SECURE_STORE_DESCRIPTION = 'system credential manager' diff --git a/src/commands/goal.test.ts b/src/commands/goal.test.ts new file mode 100644 index 00000000..2035f733 --- /dev/null +++ b/src/commands/goal.test.ts @@ -0,0 +1,277 @@ +import { Command } from 'commander' +import { beforeEach, describe, expect, it, vi } from 'vitest' + +vi.mock('../lib/api/core.js', () => ({ + getApi: vi.fn(), +})) + +import { getApi } from '../lib/api/core.js' +import { fixtures } from '../test-support/fixtures.js' +import { createMockApi, type MockApi } from '../test-support/mock-api.js' +import { registerGoalCommand } from './goal.js' + +const mockGetApi = vi.mocked(getApi) + +function createProgram() { + const program = new Command() + program.exitOverride() + registerGoalCommand(program) + return program +} + +describe('goal list', () => { + let mockApi: MockApi + + beforeEach(() => { + vi.clearAllMocks() + mockApi = createMockApi() + mockGetApi.mockResolvedValue(mockApi) + }) + + it('shows "No goals found" when empty', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + await program.parseAsync(['node', 'td', 'goal', 'list']) + + expect(consoleSpy).toHaveBeenCalledWith('No goals found.') + consoleSpy.mockRestore() + }) + + it('lists goals with progress', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.getGoals.mockResolvedValue({ + results: [fixtures.goals.shipV2, fixtures.goals.learnRust], + nextCursor: null, + }) + + await program.parseAsync(['node', 'td', 'goal', 'list']) + + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Ship v2')) + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Learn Rust')) + consoleSpy.mockRestore() + }) + + it('outputs JSON with --json flag', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.getGoals.mockResolvedValue({ + results: [fixtures.goals.shipV2], + nextCursor: null, + }) + + await program.parseAsync(['node', 'td', 'goal', 'list', '--json']) + + const output = consoleSpy.mock.calls[0][0] + const parsed = JSON.parse(output) + expect(parsed.results).toBeDefined() + expect(parsed.results[0].name).toBe('Ship v2') + consoleSpy.mockRestore() + }) +}) + +describe('goal view', () => { + let mockApi: MockApi + + beforeEach(() => { + vi.clearAllMocks() + mockApi = createMockApi() + mockGetApi.mockResolvedValue(mockApi) + }) + + it('shows goal details and linked tasks', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.getGoal.mockResolvedValue(fixtures.goals.shipV2) + mockApi.getTasks.mockResolvedValue({ results: [], nextCursor: null }) + + await program.parseAsync(['node', 'td', 'goal', 'view', `id:${fixtures.goals.shipV2.id}`]) + + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Ship v2')) + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('2026-04-03')) + consoleSpy.mockRestore() + }) + + it('includes description in JSON output', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.getGoal.mockResolvedValue(fixtures.goals.shipV2) + mockApi.getTasks.mockResolvedValue({ results: [], nextCursor: null }) + + await program.parseAsync([ + 'node', + 'td', + 'goal', + 'view', + `id:${fixtures.goals.shipV2.id}`, + '--json', + ]) + + const output = consoleSpy.mock.calls[0][0] + const parsed = JSON.parse(output) + expect(parsed.goal.description).toBe('Launch the new version') + consoleSpy.mockRestore() + }) + + it('is the default subcommand', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.getGoal.mockResolvedValue(fixtures.goals.shipV2) + mockApi.getTasks.mockResolvedValue({ results: [], nextCursor: null }) + + await program.parseAsync(['node', 'td', 'goal', `id:${fixtures.goals.shipV2.id}`]) + + expect(mockApi.getGoal).toHaveBeenCalled() + consoleSpy.mockRestore() + }) +}) + +describe('goal create', () => { + let mockApi: MockApi + + beforeEach(() => { + vi.clearAllMocks() + mockApi = createMockApi() + mockGetApi.mockResolvedValue(mockApi) + }) + + it('creates a goal', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.addGoal.mockResolvedValue(fixtures.goals.shipV2) + + await program.parseAsync(['node', 'td', 'goal', 'create', '--name', 'Ship v2']) + + expect(mockApi.addGoal).toHaveBeenCalledWith(expect.objectContaining({ name: 'Ship v2' })) + expect(consoleSpy).toHaveBeenCalledWith('Created: Ship v2') + consoleSpy.mockRestore() + }) + + it('outputs JSON with --json', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.addGoal.mockResolvedValue(fixtures.goals.shipV2) + + await program.parseAsync(['node', 'td', 'goal', 'create', '--name', 'Ship v2', '--json']) + + const output = consoleSpy.mock.calls[0][0] + const parsed = JSON.parse(output) + expect(parsed.name).toBe('Ship v2') + consoleSpy.mockRestore() + }) + + it('--dry-run previews without calling API', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + await program.parseAsync(['node', 'td', 'goal', 'create', '--name', 'Ship v2', '--dry-run']) + + expect(mockApi.addGoal).not.toHaveBeenCalled() + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Would create goal')) + consoleSpy.mockRestore() + }) +}) + +describe('goal delete', () => { + let mockApi: MockApi + + beforeEach(() => { + vi.clearAllMocks() + mockApi = createMockApi() + mockGetApi.mockResolvedValue(mockApi) + }) + + it('shows dry-run without --yes', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.getGoal.mockResolvedValue(fixtures.goals.shipV2) + + await program.parseAsync(['node', 'td', 'goal', 'delete', `id:${fixtures.goals.shipV2.id}`]) + + expect(mockApi.deleteGoal).not.toHaveBeenCalled() + expect(consoleSpy).toHaveBeenCalledWith('Would delete goal: Ship v2') + consoleSpy.mockRestore() + }) + + it('deletes with --yes', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.getGoal.mockResolvedValue(fixtures.goals.shipV2) + mockApi.deleteGoal.mockResolvedValue(true) + + await program.parseAsync([ + 'node', + 'td', + 'goal', + 'delete', + `id:${fixtures.goals.shipV2.id}`, + '--yes', + ]) + + expect(mockApi.deleteGoal).toHaveBeenCalledWith(fixtures.goals.shipV2.id) + consoleSpy.mockRestore() + }) +}) + +describe('goal complete/uncomplete', () => { + let mockApi: MockApi + + beforeEach(() => { + vi.clearAllMocks() + mockApi = createMockApi() + mockGetApi.mockResolvedValue(mockApi) + }) + + it('completes a goal', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.getGoal.mockResolvedValue(fixtures.goals.shipV2) + mockApi.completeGoal.mockResolvedValue({ ...fixtures.goals.shipV2, isCompleted: true }) + + await program.parseAsync([ + 'node', + 'td', + 'goal', + 'complete', + `id:${fixtures.goals.shipV2.id}`, + ]) + + expect(mockApi.completeGoal).toHaveBeenCalledWith(fixtures.goals.shipV2.id) + expect(consoleSpy).toHaveBeenCalledWith('Completed: Ship v2') + consoleSpy.mockRestore() + }) + + it('uncompletes a goal', async () => { + const program = createProgram() + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) + + mockApi.getGoal.mockResolvedValue(fixtures.goals.learnRust) + mockApi.uncompleteGoal.mockResolvedValue({ + ...fixtures.goals.learnRust, + isCompleted: false, + }) + + await program.parseAsync([ + 'node', + 'td', + 'goal', + 'uncomplete', + `id:${fixtures.goals.learnRust.id}`, + ]) + + expect(mockApi.uncompleteGoal).toHaveBeenCalledWith(fixtures.goals.learnRust.id) + expect(consoleSpy).toHaveBeenCalledWith('Reopened: Learn Rust') + consoleSpy.mockRestore() + }) +}) diff --git a/src/commands/goal.ts b/src/commands/goal.ts new file mode 100644 index 00000000..c08b7a17 --- /dev/null +++ b/src/commands/goal.ts @@ -0,0 +1,449 @@ +import chalk from 'chalk' +import { Command } from 'commander' +import { getApi, type Project } from '../lib/api/core.js' +import { CollaboratorCache, formatAssignee } from '../lib/collaborators.js' +import { isAccessible } from '../lib/global-args.js' +import type { PaginatedViewOptions } from '../lib/options.js' +import { + formatJson, + formatNextCursorFooter, + formatPaginatedJson, + formatPaginatedNdjson, + formatProgressBar, + formatTaskRow, + printDryRun, +} from '../lib/output.js' +import { LIMITS, paginate } from '../lib/pagination.js' +import { resolveGoalRef } from '../lib/refs.js' +import { resolveWorkspaceRef } from '../lib/refs.js' +import { resolveTaskRef } from '../lib/refs.js' + +function formatOwnerType(ownerType: string): string { + return ownerType === 'WORKSPACE' ? 'Workspace' : 'User' +} + +// ── List ── + +async function listGoals(options: PaginatedViewOptions & { workspace?: string }): Promise { + const api = await getApi() + + const targetLimit = options.all + ? Number.MAX_SAFE_INTEGER + : options.limit + ? parseInt(options.limit, 10) + : LIMITS.goals + + let workspaceId: string | undefined + if (options.workspace) { + const ws = await resolveWorkspaceRef(options.workspace) + workspaceId = String(ws.id) + } + + const { results: goals, nextCursor } = await paginate( + (cursor, limit) => + api.getGoals({ + ownerType: workspaceId ? 'WORKSPACE' : undefined, + workspaceId, + cursor: cursor ?? undefined, + limit, + }), + { limit: targetLimit }, + ) + + if (options.json) { + console.log(formatPaginatedJson({ results: goals, nextCursor }, 'goal', options.full)) + return + } + + if (options.ndjson) { + console.log(formatPaginatedNdjson({ results: goals, nextCursor }, 'goal', options.full)) + return + } + + if (goals.length === 0) { + console.log('No goals found.') + return + } + + for (const goal of goals) { + const id = chalk.dim(goal.id.slice(0, 8)) + const name = goal.isCompleted ? chalk.strikethrough(goal.name) : goal.name + const progress = formatProgressBar(goal.progress?.percentage ?? 0, 10) + const deadline = goal.isCompleted + ? chalk.dim('completed') + : goal.deadline + ? chalk.green(goal.deadline) + : '' + console.log(`${id} ${name} ${progress} ${deadline}`) + } + console.log(formatNextCursorFooter(nextCursor)) +} + +// ── View ── + +async function viewGoal(ref: string, options: PaginatedViewOptions): Promise { + const api = await getApi() + const goal = await resolveGoalRef(api, ref) + + const targetLimit = options.all + ? Number.MAX_SAFE_INTEGER + : options.limit + ? parseInt(options.limit, 10) + : LIMITS.tasks + + const { results: tasks, nextCursor } = await paginate( + (cursor, limit) => api.getTasks({ goalId: goal.id, cursor: cursor ?? undefined, limit }), + { limit: targetLimit }, + ) + + if (options.json) { + const goalJson = JSON.parse(formatJson(goal, 'goal', options.full)) + const tasksJson = JSON.parse( + formatPaginatedJson({ results: tasks, nextCursor }, 'task', options.full), + ) + console.log(JSON.stringify({ goal: goalJson, tasks: tasksJson }, null, 2)) + return + } + + if (options.ndjson) { + console.log( + JSON.stringify({ + _type: 'goal', + ...JSON.parse(formatJson(goal, 'goal', options.full)), + }), + ) + console.log(formatPaginatedNdjson({ results: tasks, nextCursor }, 'task', options.full)) + return + } + + // Header + console.log(chalk.bold(goal.name)) + console.log(chalk.dim(`ID: ${goal.id}`)) + console.log(chalk.dim(`Owner: ${formatOwnerType(goal.ownerType)}`)) + if (goal.description) console.log(`Desc: ${goal.description}`) + if (goal.deadline) console.log(`Deadline: ${chalk.green(goal.deadline)}`) + console.log( + `Progress: ${formatProgressBar(goal.progress?.percentage ?? 0)} (${goal.progress?.completedTaskCount ?? 0}/${goal.progress?.totalTaskCount ?? 0})`, + ) + if (goal.isCompleted) { + console.log(chalk.green(isAccessible() ? 'Goal completed' : '✓ Completed')) + } + console.log('') + + if (tasks.length === 0) { + console.log('No linked tasks.') + console.log(formatNextCursorFooter(nextCursor)) + return + } + + const { results: projects } = await api.getProjects() + const projectMap = new Map() + for (const p of projects) { + projectMap.set(p.id, p) + } + + const collaboratorCache = new CollaboratorCache() + await collaboratorCache.preload(api, tasks, projectMap) + + for (const task of tasks) { + const assignee = formatAssignee({ + userId: task.responsibleUid, + projectId: task.projectId, + projects: projectMap, + cache: collaboratorCache, + }) + console.log( + formatTaskRow({ + task, + projectName: projectMap.get(task.projectId)?.name, + assignee: assignee ?? undefined, + }), + ) + console.log('') + } + console.log(formatNextCursorFooter(nextCursor)) +} + +// ── Create ── + +interface CreateOptions { + name: string + workspace?: string + description?: string + deadline?: string + responsible?: string + json?: boolean + dryRun?: boolean +} + +async function createGoal(options: CreateOptions): Promise { + if (options.dryRun) { + printDryRun('create goal', { + Name: options.name, + Workspace: options.workspace, + Description: options.description, + Deadline: options.deadline, + Responsible: options.responsible, + }) + return + } + + const api = await getApi() + + let workspaceId: string | undefined + if (options.workspace) { + const ws = await resolveWorkspaceRef(options.workspace) + workspaceId = String(ws.id) + } + + const goal = await api.addGoal({ + name: options.name, + workspaceId, + description: options.description ?? null, + deadline: options.deadline ?? null, + responsibleUid: options.responsible ?? null, + }) + + if (options.json) { + console.log(formatJson(goal, 'goal')) + return + } + + console.log(`Created: ${goal.name}`) + console.log(chalk.dim(`ID: ${goal.id}`)) +} + +// ── Update ── + +interface UpdateOptions { + name?: string + description?: string + deadline?: string + responsible?: string + json?: boolean + dryRun?: boolean +} + +async function updateGoal(ref: string, options: UpdateOptions): Promise { + const { name, description, deadline, responsible, json, dryRun } = options + + if (!name && !description && !deadline && !responsible) { + throw new Error( + 'No update fields specified. Use --name, --description, --deadline, or --responsible.', + ) + } + + if (dryRun) { + printDryRun('update goal', { + Ref: ref, + Name: name, + Description: description, + Deadline: deadline, + Responsible: responsible, + }) + return + } + + const api = await getApi() + const goal = await resolveGoalRef(api, ref) + + const args: Record = {} + if (name) args.name = name + if (description) args.description = description + if (deadline) args.deadline = deadline + if (responsible) args.responsibleUid = responsible + + const updated = await api.updateGoal(goal.id, args) + + if (json) { + console.log(formatJson(updated, 'goal')) + return + } + + console.log(`Updated: ${goal.name} → ${updated.name}`) +} + +// ── Delete ── + +async function deleteGoal( + ref: string, + options: { yes?: boolean; dryRun?: boolean }, +): Promise { + const api = await getApi() + const goal = await resolveGoalRef(api, ref) + + if (options.dryRun) { + printDryRun('delete goal', { Goal: goal.name }) + return + } + + if (!options.yes) { + console.log(`Would delete goal: ${goal.name}`) + console.log('Use --yes to confirm.') + return + } + + await api.deleteGoal(goal.id) + console.log(`Deleted goal: ${goal.name}`) +} + +// ── Complete / Uncomplete ── + +async function completeGoal(ref: string): Promise { + const api = await getApi() + const goal = await resolveGoalRef(api, ref) + await api.completeGoal(goal.id) + console.log(`Completed: ${goal.name}`) +} + +async function uncompleteGoal(ref: string): Promise { + const api = await getApi() + const goal = await resolveGoalRef(api, ref) + await api.uncompleteGoal(goal.id) + console.log(`Reopened: ${goal.name}`) +} + +// ── Link / Unlink ── + +async function linkGoal(ref: string, options: { task: string }): Promise { + const api = await getApi() + const goal = await resolveGoalRef(api, ref) + const task = await resolveTaskRef(api, options.task) + + await api.linkTaskToGoal({ goalId: goal.id, taskId: task.id }) + console.log(`Linked task "${task.content}" to goal "${goal.name}"`) +} + +async function unlinkGoal(ref: string, options: { task: string }): Promise { + const api = await getApi() + const goal = await resolveGoalRef(api, ref) + const task = await resolveTaskRef(api, options.task) + + await api.unlinkTaskFromGoal({ goalId: goal.id, taskId: task.id }) + console.log(`Unlinked task "${task.content}" from goal "${goal.name}"`) +} + +// ── Register ── + +export function registerGoalCommand(program: Command): void { + const goal = program.command('goal').description('Manage goals') + + goal.command('view [ref]', { isDefault: true }) + .description('View goal details and linked tasks') + .option('--limit ', 'Limit number of results (default: 300)') + .option('--all', 'Fetch all results (no limit)') + .option('--json', 'Output as JSON') + .option('--ndjson', 'Output as newline-delimited JSON') + .option('--full', 'Include all fields in JSON output') + .action((ref, options) => { + if (!ref) { + goal.help() + return + } + return viewGoal(ref, options) + }) + + goal.command('list') + .description('List all accessible goals') + .option('--workspace ', 'Filter to a workspace') + .option('--limit ', 'Limit number of results (default: 200)') + .option('--all', 'Fetch all results (no limit)') + .option('--json', 'Output as JSON') + .option('--ndjson', 'Output as newline-delimited JSON') + .option('--full', 'Include all fields in JSON output') + .action(listGoals) + + const createCmd = goal + .command('create') + .description('Create a goal') + .option('--name ', 'Goal name (required)') + .option('--workspace ', 'Workspace (omit for personal goal)') + .option('--description ', 'Goal description') + .option('--deadline ', 'Target date (YYYY-MM-DD)') + .option('--responsible ', 'Responsible user ID') + .option('--json', 'Output the created goal as JSON') + .option('--dry-run', 'Preview what would happen without executing') + .action((options) => { + if (!options.name) { + createCmd.help() + return + } + return createGoal(options) + }) + + const updateCmd = goal + .command('update [ref]') + .description('Update a goal') + .option('--name ', 'New name') + .option('--description ', 'New description') + .option('--deadline ', 'New deadline (YYYY-MM-DD)') + .option('--responsible ', 'New responsible user ID') + .option('--json', 'Output the updated goal as JSON') + .option('--dry-run', 'Preview what would happen without executing') + .action((ref, options) => { + if (!ref) { + updateCmd.help() + return + } + return updateGoal(ref, options) + }) + + const deleteCmd = goal + .command('delete [ref]') + .description('Delete a goal') + .option('--yes', 'Confirm deletion') + .option('--dry-run', 'Preview what would happen without executing') + .action((ref, options) => { + if (!ref) { + deleteCmd.help() + return + } + return deleteGoal(ref, options) + }) + + const completeCmd = goal + .command('complete [ref]') + .description('Mark a goal as completed') + .action((ref) => { + if (!ref) { + completeCmd.help() + return + } + return completeGoal(ref) + }) + + const uncompleteCmd = goal + .command('uncomplete [ref]') + .description('Reopen a completed goal') + .action((ref) => { + if (!ref) { + uncompleteCmd.help() + return + } + return uncompleteGoal(ref) + }) + + const linkCmd = goal + .command('link [ref]') + .description('Link a task to a goal') + .option('--task ', 'Task to link (required)') + .action((ref, options) => { + if (!ref || !options.task) { + linkCmd.help() + return + } + return linkGoal(ref, options) + }) + + const unlinkCmd = goal + .command('unlink [ref]') + .description('Unlink a task from a goal') + .option('--task ', 'Task to unlink (required)') + .action((ref, options) => { + if (!ref || !options.task) { + unlinkCmd.help() + return + } + return unlinkGoal(ref, options) + }) +} diff --git a/src/index.ts b/src/index.ts index be061696..01142a45 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,17 @@ import { stripUserFlag } from '@doist/cli-core' import { type Command, program } from 'commander' import packageJson from '../package.json' with { type: 'json' } import { BaseCliError, CliError } from './lib/errors.js' +<<<<<<< HEAD +import { + getRequestedUserRef, + isJsonMode, + isNdjsonMode, + isRawMode, + stripUserFlag, +} from './lib/global-args.js' +======= import { getRequestedUserRef, isJsonMode, isNdjsonMode, isRawMode } from './lib/global-args.js' +>>>>>>> origin/main import { initializeLogger } from './lib/logger.js' import { preloadMarkdown } from './lib/markdown.js' import { formatError, formatErrorJson } from './lib/output.js' @@ -145,6 +155,7 @@ const commands: Record Promise<(p: Command) => void>]> = 'Manage filters', async () => (await import('./commands/filter/index.js')).registerFilterCommand, ], + goal: ['Manage goals', async () => (await import('./commands/goal.js')).registerGoalCommand], folder: [ 'Manage workspace folders', async () => (await import('./commands/folder/index.js')).registerFolderCommand, diff --git a/src/lib/auth-store.test.ts b/src/lib/auth-store.test.ts new file mode 100644 index 00000000..20b1e8dc --- /dev/null +++ b/src/lib/auth-store.test.ts @@ -0,0 +1,183 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +vi.mock('./auth.js', async (importOriginal) => { + const actual = await importOriginal() + return { + ...actual, + loadTokenForStoredUser: vi.fn(), + upsertUser: vi.fn(), + clearApiToken: vi.fn(), + } +}) + +vi.mock('./config.js', async (importOriginal) => { + const actual = await importOriginal() + return { + ...actual, + readConfig: vi.fn(), + } +}) + +import { + accountToUpsertInput, + createTodoistTokenStore, + type TodoistAccount, + toTodoistAccount, +} from './auth-store.js' +import { + clearApiToken, + loadTokenForStoredUser, + NoTokenError, + TOKEN_ENV_VAR, + upsertUser, +} from './auth.js' +import { readConfig } from './config.js' +import { SecureStoreUnavailableError } from './secure-store.js' + +const mockReadConfig = vi.mocked(readConfig) +const mockLoadToken = vi.mocked(loadTokenForStoredUser) +const mockUpsertUser = vi.mocked(upsertUser) +const mockClearApiToken = vi.mocked(clearApiToken) + +const USER_A = { + id: '111', + email: 'a@example.com', + auth_mode: 'read-write' as const, + auth_scope: 'data:read_write,data:delete,project:delete', +} +const USER_B = { + id: '222', + email: 'b@example.com', + auth_mode: 'read-only' as const, + auth_scope: 'data:read', + auth_flags: ['read-only' as const], +} + +const ACCOUNT_A: TodoistAccount = { + id: USER_A.id, + email: USER_A.email, + label: USER_A.email, + auth_mode: USER_A.auth_mode, + auth_scope: USER_A.auth_scope, + auth_flags: undefined, +} + +describe('TodoistAccount mappers', () => { + it('round-trips through toTodoistAccount → accountToUpsertInput', () => { + const account = toTodoistAccount({ + id: USER_A.id, + email: USER_A.email, + authMode: USER_A.auth_mode, + authScope: USER_A.auth_scope, + }) + expect(account).toEqual(ACCOUNT_A) + expect(accountToUpsertInput(account, 'token_xyz123456')).toEqual({ + id: USER_A.id, + email: USER_A.email, + token: 'token_xyz123456', + authMode: USER_A.auth_mode, + authScope: USER_A.auth_scope, + authFlags: undefined, + }) + }) +}) + +describe('createTodoistTokenStore', () => { + let originalEnvToken: string | undefined + + beforeEach(() => { + vi.clearAllMocks() + originalEnvToken = process.env[TOKEN_ENV_VAR] + delete process.env[TOKEN_ENV_VAR] + }) + + afterEach(() => { + if (originalEnvToken === undefined) { + delete process.env[TOKEN_ENV_VAR] + } else { + process.env[TOKEN_ENV_VAR] = originalEnvToken + } + }) + + describe('active()', () => { + it('returns null when TODOIST_API_TOKEN is set (env tokens are not persisted)', async () => { + process.env[TOKEN_ENV_VAR] = 'env_token_value' + expect(await createTodoistTokenStore().active()).toBeNull() + expect(mockReadConfig).not.toHaveBeenCalled() + }) + + it('returns null when no users are stored', async () => { + mockReadConfig.mockResolvedValue({ users: [] }) + expect(await createTodoistTokenStore().active()).toBeNull() + }) + + it('returns the single stored user when no default is set', async () => { + mockReadConfig.mockResolvedValue({ users: [USER_A] }) + mockLoadToken.mockResolvedValue({ token: 'tok_a', source: 'secure-store' }) + + expect(await createTodoistTokenStore().active()).toEqual({ + token: 'tok_a', + account: ACCOUNT_A, + }) + }) + + it('prefers the default user when multiple are stored', async () => { + mockReadConfig.mockResolvedValue({ + users: [USER_A, USER_B], + user: { defaultUser: USER_B.id }, + }) + mockLoadToken.mockResolvedValue({ token: 'tok_b', source: 'secure-store' }) + + const result = await createTodoistTokenStore().active() + expect(mockLoadToken).toHaveBeenCalledWith(USER_B) + expect(result?.account.id).toBe(USER_B.id) + expect(result?.account.auth_flags).toEqual(['read-only']) + }) + + it('returns null on multi-user-no-default (no selection error leaks out)', async () => { + mockReadConfig.mockResolvedValue({ users: [USER_A, USER_B] }) + expect(await createTodoistTokenStore().active()).toBeNull() + expect(mockLoadToken).not.toHaveBeenCalled() + }) + + it.each([ + ['NoTokenError', new NoTokenError()], + ['SecureStoreUnavailableError', new SecureStoreUnavailableError('offline')], + ])('returns null when token load throws %s', async (_label, error) => { + mockReadConfig.mockResolvedValue({ users: [USER_A] }) + mockLoadToken.mockRejectedValue(error) + expect(await createTodoistTokenStore().active()).toBeNull() + }) + }) + + describe('set()', () => { + it('persists via upsertUser and exposes the storage result + warning', async () => { + mockUpsertUser.mockResolvedValue({ + storage: 'config-file', + replaced: false, + warning: + 'system credential manager unavailable; token saved as plaintext in /tmp/c.json', + }) + + const store = createTodoistTokenStore() + await store.set(ACCOUNT_A, 'token_xyz123456') + + expect(mockUpsertUser).toHaveBeenCalledWith( + accountToUpsertInput(ACCOUNT_A, 'token_xyz123456'), + ) + expect(store.getLastStorageResult()).toEqual({ + storage: 'config-file', + warning: + 'system credential manager unavailable; token saved as plaintext in /tmp/c.json', + }) + }) + }) + + describe('clear()', () => { + it('delegates to clearApiToken', async () => { + mockClearApiToken.mockResolvedValue({ storage: 'secure-store' }) + await createTodoistTokenStore().clear() + expect(mockClearApiToken).toHaveBeenCalled() + }) + }) +}) diff --git a/src/lib/auth-store.ts b/src/lib/auth-store.ts index ca389e47..845c34d5 100644 --- a/src/lib/auth-store.ts +++ b/src/lib/auth-store.ts @@ -1,3 +1,18 @@ +<<<<<<< HEAD +import type { AuthAccount, TokenStore } from '@doist/cli-core/auth' +import { + clearApiToken, + loadTokenForStoredUser, + NoTokenError, + type TokenStorageResult, + TOKEN_ENV_VAR, + upsertUser, + type UpsertUserInput, +} from './auth.js' +import { type AuthFlag, type AuthMode, readConfig, type StoredUser } from './config.js' +import { SecureStoreUnavailableError } from './secure-store.js' +import { getDefaultUser, getStoredUsers } from './users.js' +======= import { type AccountRef, type AuthAccount, @@ -20,6 +35,7 @@ export const TOKEN_ENV_VAR = 'TODOIST_API_TOKEN' export function accountForUser(id: string): string { return `user-${id}` } +>>>>>>> origin/main /** * Account shape stored by todoist-cli. Extends cli-core's `AuthAccount` with @@ -43,8 +59,14 @@ export type TodoistAccountInput = { /** * Single source of truth for the `TodoistAccount` field layout. Used by the +<<<<<<< HEAD + * auth provider's `validateToken` (post-handshake) and the token-store + * `active()` adapter (post-read) so the persisted shape stays aligned with + * what `set()` later disassembles via `accountToUpsertInput`. +======= * auth provider's `validateToken` (post-handshake), the migration helper, * and the `UserRecordStore` adapter's record → account mapping. +>>>>>>> origin/main */ export function toTodoistAccount(input: TodoistAccountInput): TodoistAccount { return { @@ -57,6 +79,104 @@ export function toTodoistAccount(input: TodoistAccountInput): TodoistAccount { } } +<<<<<<< HEAD +/** Inverse of `toTodoistAccount` — feeds the upsert path that owns persistence. */ +export function accountToUpsertInput(account: TodoistAccount, token: string): UpsertUserInput { + return { + id: account.id, + email: account.email, + token, + authMode: account.auth_mode, + authScope: account.auth_scope, + authFlags: account.auth_flags, + } +} + +function storedUserToAccount(user: StoredUser): TodoistAccount { + return toTodoistAccount({ + id: user.id, + email: user.email, + authMode: user.auth_mode ?? 'unknown', + authScope: user.auth_scope, + authFlags: user.auth_flags, + }) +} + +/** + * `TokenStore` adapter that bridges cli-core's auth runtime + * (which is single-user) to todoist's existing multi-user keyring + config + * store. `set()` is exercised by `runOAuthFlow` during login; `active()` and + * `clear()` are wired through for completeness so the public `TokenStore` + * contract is honoured — per-user reads are still driven from the + * todoist-local commands (logout, status, token, …). + * + * The factory also returns `getLastStorageResult()` so the login command can + * surface keyring-fallback warnings (`upsertUser` reports them via the + * `TokenStorageResult` payload that `set()` would otherwise have to swallow, + * since cli-core's `TokenStore.set` signature is `void`). + */ +export type TodoistTokenStore = TokenStore & { + getLastStorageResult(): TokenStorageResult | undefined + getLastClearResult(): TokenStorageResult | undefined +} + +export function createTodoistTokenStore(): TodoistTokenStore { + let lastStorageResult: TokenStorageResult | undefined + let lastClearResult: TokenStorageResult | undefined + + return { + /** + * Pure view of persisted state. Deliberately ignores the global + * `--user` selector (a CLI-invocation concern, not storage) and + * returns `null` when `TODOIST_API_TOKEN` is in play (env tokens + * don't represent a persisted account). When multiple accounts + * are stored without a default, returns `null` rather than + * throwing a selection error — the runtime caller can react to + * "no active persisted account" but shouldn't see CLI-arg errors + * leaking out of a store read. + */ + async active() { + if (process.env[TOKEN_ENV_VAR]) return null + + const config = await readConfig() + const users = getStoredUsers(config) + if (users.length === 0) return null + + const target = getDefaultUser(config) ?? (users.length === 1 ? users[0] : null) + if (!target) return null + + try { + const { token } = await loadTokenForStoredUser(target) + return { token, account: storedUserToAccount(target) } + } catch (error) { + // Token unreachable (no secret, keyring offline) — surface as + // "no active persisted account" so a `set()` retry can recover + // without a runtime caller having to special-case storage errors. + if (error instanceof NoTokenError) return null + if (error instanceof SecureStoreUnavailableError) return null + throw error + } + }, + + async set(account, token) { + const { replaced: _replaced, ...result } = await upsertUser( + accountToUpsertInput(account, token), + ) + lastStorageResult = result + }, + + async clear() { + lastClearResult = await clearApiToken() + }, + + getLastStorageResult() { + return lastStorageResult + }, + + getLastClearResult() { + return lastClearResult + }, +======= export type TodoistTokenStore = KeyringTokenStore /** @@ -94,5 +214,6 @@ export function createTodoistTokenStore(): TodoistTokenStore { setDefault: (ref) => inner.setDefault(ref), getLastStorageResult: () => inner.getLastStorageResult(), getLastClearResult: () => inner.getLastClearResult(), +>>>>>>> origin/main } } diff --git a/src/lib/auth.test.ts b/src/lib/auth.test.ts index 0928688c..79301978 100644 --- a/src/lib/auth.test.ts +++ b/src/lib/auth.test.ts @@ -90,6 +90,17 @@ describe('lib/auth', () => { getConfigPath: () => TEST_CONFIG_PATH, } }) +<<<<<<< HEAD + + vi.doMock('@napi-rs/keyring', () => ({ + AsyncEntry: class { + private account: string + constructor(service: string, account: string) { + this.account = account + keyring.constructed.push({ service, account }) + } +======= +>>>>>>> origin/main // Mock cli-core's `createSecureStore` directly. Inlining cli-core via // `server.deps.inline` is not sufficient on Linux + npm-linked cli-core: diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 1b2d305a..c8ff90a3 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -13,8 +13,21 @@ export { type UpdateChannel, } from './config.js' +<<<<<<< HEAD +import { + CONFIG_VERSION, + getConfigPath, + readConfig, + writeConfig, + type AuthFlag, + type AuthMode, + type Config, + type StoredUser, +} from './config.js' +======= import { accountForUser, SERVICE_NAME, TOKEN_ENV_VAR } from './auth-store.js' import { type AuthFlag, type AuthMode, readConfig, type StoredUser } from './config.js' +>>>>>>> origin/main import { CliError } from './errors.js' import { getRequestedUserRef } from './global-args.js' import { findUserByRef, getStoredUsers, NoUserSelectedError, UserNotFoundError } from './users.js' @@ -135,11 +148,191 @@ export async function getAuthMetadata(): Promise { } } +<<<<<<< HEAD +/** + * Add or update a user record. Stores the token in the OS credential manager + * under `user-` when available, falls back to per-user plaintext in config. + * Sets `defaultUser` automatically if this is the first user being stored. + */ +export async function upsertUser( + input: UpsertUserInput, +): Promise { + if (!input.token || input.token.trim().length < 10) { + throw new CliError('INVALID_TOKEN', 'Invalid token: Token must be at least 10 characters') + } + if (!input.id) { + throw new CliError('INVALID_USER', 'Cannot store user record: missing id') + } + if (!input.email) { + throw new CliError('INVALID_USER', 'Cannot store user record: missing email') + } + + const trimmedToken = input.token.trim() + const config = await readConfig() + const previouslyExisted = getStoredUsers(config).some((u) => u.id === input.id) + // Always set the first user as the default — even if `config.user.defaultUser` + // points at a stale/orphaned id, that pointer would otherwise wedge multi-user + // resolution on subsequent logins. + const shouldSetDefault = getStoredUsers(config).length === 0 + + const baseRecord: StoredUser = { + id: input.id, + email: input.email, + auth_mode: input.authMode, + auth_scope: input.authScope, + auth_flags: input.authFlags, + } + + const secureStore = createSecureStore(accountForUser(input.id)) + let storedSecurely = false + try { + await secureStore.setSecret(trimmedToken) + storedSecurely = true + } catch (error) { + if (!(error instanceof SecureStoreUnavailableError)) throw error + } + + const userRecord: StoredUser = storedSecurely + ? baseRecord + : { ...baseRecord, api_token: trimmedToken } + + let next = ensureV2Shape(config) + next = upsertStoredUser(next, userRecord).config + if (shouldSetDefault) { + next = setDefaultUserInConfig(next, input.id) + } + next = stripLegacyAuthFields(next) + + try { + await writeConfig(next) + } catch (error) { + // Config write is the source of truth — without it, later commands + // can't resolve the user even though the keyring holds the secret. + // Roll the keyring back so we don't leak credentials for a non-stored + // account, then surface the failure. + if (storedSecurely) { + try { + await secureStore.deleteSecret() + } catch { + // best effort — the original error is what the user needs + } + } + const detail = error instanceof Error && error.message ? `: ${error.message}` : '' + throw new CliError( + 'CONFIG_WRITE_FAILED', + `Could not persist account record to ${getConfigPath()}${detail}`, + ['Check file permissions on ~/.config/todoist-cli/, then re-run the command'], + ) + } + + return { + storage: storedSecurely ? 'secure-store' : 'config-file', + warning: storedSecurely ? undefined : buildFallbackWarning('token saved as plaintext in'), + replaced: previouslyExisted, + } +} + +/** + * Remove the active user (resolved via `--user` or default). For multi-user + * installs without a default, callers must pass `--user ` to disambiguate. + */ +export async function clearApiToken(opts: { ref?: string } = {}): Promise { + const config = await readConfig() + const users = getStoredUsers(config) + const requestedRef = opts.ref ?? getRequestedUserRef() + + // No users stored yet — fall through to legacy logout only on a v1-shaped + // config (no `users` key at all). Empty `users: []` is an already-clean + // v2 install; treat it as a no-op rather than poking the legacy keyring. + if (users.length === 0) { + if (!Array.isArray(config.users)) { + return clearLegacyToken(config) + } + if (requestedRef) { + throw new UserNotFoundError(requestedRef) + } + throw new NoTokenError() + } + + let target: StoredUser + if (requestedRef) { + const found = findUserByRef(config, requestedRef) + if (!found) throw new UserNotFoundError(requestedRef) + target = found.user + } else { + const def = getDefaultUser(config) + if (def) { + target = def + } else if (users.length === 1) { + target = users[0] + } else { + throw new NoUserSelectedError() + } + } + + return removeUserById(target.id) +} + +/** + * Remove a specific user by id. Used by `td user remove` and as the underlying + * primitive for `clearApiToken`. + * + * Order matters: write the new config first (the source of truth) and only + * then delete the secret. If the config update fails the keyring is untouched, + * so the user remains fully functional and a retry will simply re-attempt + * the same operation. A keyring delete failure after a successful config + * update leaves an orphan secret that the keyring's own service can clean up + * later — the CLI no longer references it. + */ +export async function removeUserById(id: string): Promise { + const config = await readConfig() + const next = stripLegacyAuthFields(removeStoredUser(ensureV2Shape(config), id)) + + try { + await writeConfig(next) + } catch (error) { + const detail = error instanceof Error && error.message ? `: ${error.message}` : '' + throw new CliError('CONFIG_WRITE_FAILED', `Could not update ${getConfigPath()}${detail}`, [ + 'Check file permissions on ~/.config/todoist-cli/, then re-run the command', + ]) + } + + const secureStore = createSecureStore(accountForUser(id)) + try { + await secureStore.deleteSecret() + } catch (error) { + if (!(error instanceof SecureStoreUnavailableError)) throw error + return { + storage: 'config-file', + warning: buildFallbackWarning('local auth state cleared in'), + } + } + + return { storage: 'secure-store' } +} + +export async function setDefaultUserId(id: string): Promise { + const config = ensureV2Shape(await readConfig()) + const found = findUserByRef(config, id) + if (!found) throw new UserNotFoundError(id) + await writeConfig(stripLegacyAuthFields(setDefaultUserInConfig(config, found.user.id))) +} + +======= +>>>>>>> origin/main export async function listStoredUsers(): Promise { return getStoredUsers(await readConfig()) } +<<<<<<< HEAD +// --------------------------------------------------------------------------- +// Internal helpers +// --------------------------------------------------------------------------- + +export async function loadTokenForStoredUser( +======= async function loadTokenForStoredUser( +>>>>>>> origin/main user: StoredUser, ): Promise<{ token: string; source: 'secure-store' | 'config-file' }> { if (user.api_token?.trim()) { @@ -165,3 +358,15 @@ function resolvedToMetadata(resolved: ResolvedUser): AuthMetadata { email: resolved.email || undefined, } } +<<<<<<< HEAD + +function buildFallbackWarning(action: string): string { + return `${SECURE_STORE_DESCRIPTION} unavailable; ${action} ${getConfigPath()}` +} + +function buildConfigCleanupWarning(prefix: string, error: unknown): string { + const detail = error instanceof Error && error.message ? ` (${error.message})` : '' + return `${prefix} but could not update ${getConfigPath()}${detail}` +} +======= +>>>>>>> origin/main diff --git a/src/lib/config.ts b/src/lib/config.ts index 9113d53a..1e6958f1 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -158,6 +158,8 @@ export async function readConfigStrict(): Promise { export async function writeConfig(config: Config): Promise { await writeConfigCore(getConfigPath(), config, { deleteWhenEmpty: true }) +<<<<<<< HEAD +======= } /** @@ -177,6 +179,7 @@ export function stripLegacyAuthFields(config: Config): Config { ...rest } = config return rest +>>>>>>> origin/main } // Keep this validator ad-hoc for now: it is only used by `td doctor`, and the diff --git a/src/lib/global-args.ts b/src/lib/global-args.ts index fc23b9fa..f3c9444c 100644 --- a/src/lib/global-args.ts +++ b/src/lib/global-args.ts @@ -131,3 +131,39 @@ export const shouldDisableSpinner = createSpinnerGate({ envVar: 'TD_SPINNER', getArgs: store.get, }) +<<<<<<< HEAD + +/** + * Remove `--user ` / `--user=` from an argv array so commander — + * which has no global-option attachment — never sees the flag at subcommand + * level. Returns a new array; the original is not mutated. Stops at the `--` + * terminator so positional args after it are preserved verbatim. + */ +export function stripUserFlag(argv: string[]): string[] { + const out: string[] = [] + let stopped = false + for (let i = 0; i < argv.length; i++) { + const arg = argv[i] + if (stopped) { + out.push(arg) + continue + } + if (arg === '--') { + stopped = true + out.push(arg) + continue + } + if (arg === '--user') { + // Stays in lockstep with `parseTdLocalFlags` above. + if (i + 1 < argv.length && !argv[i + 1].startsWith('-')) i++ + continue + } + if (arg.startsWith('--user=')) { + continue + } + out.push(arg) + } + return out +} +======= +>>>>>>> origin/main diff --git a/src/lib/migrate-auth.test.ts b/src/lib/migrate-auth.test.ts index 19f3cbfb..280d6a8b 100644 --- a/src/lib/migrate-auth.test.ts +++ b/src/lib/migrate-auth.test.ts @@ -158,6 +158,12 @@ describe('migrateLegacyAuth (todoist-cli wrapper)', () => { headers: expect.objectContaining({ authorization: 'Bearer legacy-token-1234567', 'doist-platform': 'cli', +<<<<<<< HEAD + 'doist-version': expect.stringMatching(/^\d+\.\d+\.\d+(-[\w.]+)?$/), + 'request-id': expect.any(String), + 'session-id': expect.any(String), +======= +>>>>>>> origin/main 'cli-command': 'postinstall:auth-migrate', }), }), diff --git a/src/lib/output.ts b/src/lib/output.ts index c75ac521..af18e1c5 100644 --- a/src/lib/output.ts +++ b/src/lib/output.ts @@ -218,6 +218,16 @@ const LOCATION_REMINDER_ESSENTIAL_FIELDS = [ 'locTrigger', 'radius', ] as const +const GOAL_ESSENTIAL_FIELDS = [ + 'id', + 'name', + 'description', + 'ownerType', + 'ownerId', + 'deadline', + 'isCompleted', + 'progress', +] as const const FILTER_ESSENTIAL_FIELDS = ['id', 'name', 'query', 'color', 'isFavorite'] as const const FOLDER_ESSENTIAL_FIELDS = ['id', 'name', 'workspaceId', 'defaultOrder', 'childOrder'] as const const APP_ESSENTIAL_FIELDS = [ @@ -278,6 +288,9 @@ function addWebUrl(item: T, type: EntityType): T & { w url = '' } break + case 'goal': + url = '' + break case 'reminder': url = '' break @@ -306,6 +319,7 @@ export type EntityType = | 'reminder' | 'location-reminder' | 'filter' + | 'goal' | 'folder' | 'notification' | 'app' @@ -328,6 +342,8 @@ function getEssentialFields(type: EntityType): readonly string[] { return LOCATION_REMINDER_ESSENTIAL_FIELDS case 'filter': return FILTER_ESSENTIAL_FIELDS + case 'goal': + return GOAL_ESSENTIAL_FIELDS case 'folder': return FOLDER_ESSENTIAL_FIELDS case 'notification': diff --git a/src/lib/pagination.ts b/src/lib/pagination.ts index f63337cb..e2afd63b 100644 --- a/src/lib/pagination.ts +++ b/src/lib/pagination.ts @@ -45,4 +45,5 @@ export const LIMITS = { sections: 300, labels: 300, comments: 10, + goals: 200, } as const diff --git a/src/lib/refs.ts b/src/lib/refs.ts index 4ffc0860..9f2aa6d4 100644 --- a/src/lib/refs.ts +++ b/src/lib/refs.ts @@ -1,4 +1,9 @@ -import { type AppWithUserCount, TodoistApi, TodoistRequestError } from '@doist/todoist-sdk' +import { + type AppWithUserCount, + type Goal, + TodoistApi, + TodoistRequestError, +} from '@doist/todoist-sdk' import type { Project, Task } from './api/core.js' import { fetchWorkspaceFolders, @@ -339,6 +344,19 @@ export async function resolveProjectId(api: TodoistApi, ref: string): Promise { + return resolveRef( + ref, + (id) => api.getGoal(id), + () => + paginate((cursor, limit) => api.getGoals({ cursor: cursor ?? undefined, limit }), { + limit: 500, + }), + (g) => g.name, + 'goal', + ) +} + export async function resolveSectionId( api: TodoistApi, ref: string, diff --git a/src/lib/skills/content.ts b/src/lib/skills/content.ts index bc0d71da..1b94d16c 100644 --- a/src/lib/skills/content.ts +++ b/src/lib/skills/content.ts @@ -84,6 +84,7 @@ Resolution order: \`--user \` > \`user.defaultUser\` from config > the only - Task lifecycle: \`td task list/view/add/quickadd/update/reschedule/move/complete/uncomplete/delete/browse\` (alias: \`td task qa\` for \`quickadd\`) - Projects: \`td project list/view/create/update/archive/unarchive/archived/delete/move/reorder/join/browse/collaborators/permissions\` - Project analytics: \`td project progress/health/health-context/activity-stats/analyze-health\` +- Goals: \`td goal list/view/create/update/delete/complete/uncomplete/link/unlink\` - Organization: \`td label ...\`, \`td filter ...\`, \`td section ...\`, \`td folder ...\`, \`td workspace ...\` - Collaboration: \`td comment ...\`, \`td notification ...\`, \`td reminder ...\` - Templates and files: \`td template ...\`, \`td attachment view \`, \`td backup ...\` @@ -226,6 +227,25 @@ td section browse id:123 Shared labels can appear in \`td label list\` and \`td label view\`, but standard update and delete actions only work for labels with IDs. Use \`td label rename-shared\` and \`td label remove-shared\` for shared labels. +### Goals +\`\`\`bash +td goal list # List all accessible goals +td goal list --workspace "Work" # Filter to workspace goals +td goal view "Ship v2" # View goal details and linked tasks +td goal create --name "Ship v2" # Create personal goal +td goal create --name "Ship v2" --workspace "Work" # Create workspace goal +td goal create --name "Ship v2" --deadline "2026-04-03" +td goal create --name "Ship v2" --json # Return created goal as JSON +td goal create --name "Ship v2" --dry-run # Preview creation +td goal update "Ship v2" --name "Ship v3" +td goal update "Ship v2" --description "New desc" --json +td goal delete "Ship v2" --yes +td goal complete "Ship v2" # Mark goal as completed +td goal uncomplete "Ship v2" # Reopen a completed goal +td goal link "Ship v2" --task "Buy milk" # Link a task to a goal +td goal unlink "Ship v2" --task "Buy milk" # Unlink a task from a goal +\`\`\` + ### Comments, Attachments, Notifications, And Reminders \`\`\`bash td comment list "Plan sprint" diff --git a/src/lib/urls.ts b/src/lib/urls.ts index df18b544..6cf346e3 100644 --- a/src/lib/urls.ts +++ b/src/lib/urls.ts @@ -26,6 +26,14 @@ export function sectionUrl(sectionId: string): string { return entityUrl('section', sectionId) } +export function goalsUrl(): string { + return `${BASE_URL}/goals` +} + +export function workspaceGoalsUrl(workspaceId: string): string { + return `${BASE_URL}/goals/${workspaceId}` +} + export function commentUrl(taskId: string, commentId: string): string { return `${entityUrl('task', taskId)}#comment-${commentId}` } diff --git a/src/lib/usage-tracking.test.ts b/src/lib/usage-tracking.test.ts index d5b6b5e4..12d4b76f 100644 --- a/src/lib/usage-tracking.test.ts +++ b/src/lib/usage-tracking.test.ts @@ -31,9 +31,9 @@ describe('usage tracking', () => { const headers = buildUsageTrackingHeaders() - expect(headers['User-Agent']).toMatch(/^todoist-cli\/\d+\.\d+\.\d+$/) + expect(headers['User-Agent']).toMatch(/^todoist-cli\/\d+\.\d+\.\d+(-[\w.]+)?$/) expect(headers['doist-platform']).toBe('cli') - expect(headers['doist-version']).toMatch(/^\d+\.\d+\.\d+$/) + expect(headers['doist-version']).toMatch(/^\d+\.\d+\.\d+(-[\w.]+)?$/) expect(headers['doist-os']).toMatch(/^(macos|linux|windows|unknown)$/) expect(headers['request-id']).toBeTruthy() expect(headers['session-id']).toBeTruthy() @@ -67,7 +67,11 @@ describe('usage tracking', () => { const secondHeaders = captured[1].headers as Record expect(firstHeaders.authorization).toBe('Bearer token') expect(firstHeaders['doist-platform']).toBe('cli') +<<<<<<< HEAD + expect(firstHeaders['doist-version']).toMatch(/^\d+\.\d+\.\d+(-[\w.]+)?$/) +======= expect(firstHeaders['doist-version']).toMatch(/^\d+\.\d+\.\d+$/) +>>>>>>> origin/main expect(firstHeaders['cli-command']).toBe('today') expect(firstHeaders['session-id']).toBe(secondHeaders['session-id']) expect(firstHeaders['request-id']).not.toBe(secondHeaders['request-id']) diff --git a/src/lib/usage-tracking.ts b/src/lib/usage-tracking.ts index c3f5f69f..82f06352 100644 --- a/src/lib/usage-tracking.ts +++ b/src/lib/usage-tracking.ts @@ -1,9 +1,5 @@ import { randomUUID } from 'node:crypto' -import { - type CustomFetch, - type CustomFetchResponse, - getDefaultDispatcher, -} from '@doist/todoist-sdk' +import { type CustomFetch, type FileResponse, getDefaultDispatcher } from '@doist/todoist-sdk' import packageJson from '../../package.json' with { type: 'json' } const CLI_NAME = 'todoist-cli' @@ -93,7 +89,13 @@ async function attachDispatcherIfNative( } } -function toCustomFetchResponse(response: Response): CustomFetchResponse { +// `FileResponse` (== `CustomFetchResponse + arrayBuffer`) is the richer +// shape: SDK file endpoints (`viewAttachment`, `downloadBackup`) read the body +// via `arrayBuffer()` and would otherwise fall back to a `text()` round-trip +// that mangles binary bytes. Returning `FileResponse` for every call is safe +// — non-binary endpoints simply ignore the extra method — and keeps the +// `CustomFetch` contract (a `FileResponse` is a structural `CustomFetchResponse`). +function toCustomFetchResponse(response: Response): FileResponse { return { ok: response.ok, status: response.status, @@ -105,7 +107,9 @@ function toCustomFetchResponse(response: Response): CustomFetchResponse { } } -export function createTrackedFetch(baseFetch: typeof fetch = globalThis.fetch): CustomFetch { +export function createTrackedFetch( + baseFetch: typeof fetch = globalThis.fetch, +): (url: string, options?: Parameters[1]) => Promise { return async (url, options = {}) => { const { timeout: timeoutMs, headers, signal, ...rest } = options diff --git a/src/test-support/fixtures.ts b/src/test-support/fixtures.ts index 905f76c6..c0ae0b18 100644 --- a/src/test-support/fixtures.ts +++ b/src/test-support/fixtures.ts @@ -269,6 +269,52 @@ export const fixtures = { itemOrder: 1, } as Filter, }, + goals: { + shipV2: { + id: '550e8400-e29b-41d4-a716-446655440000', + ownerType: 'USER', + ownerId: 'user-1', + name: 'Ship v2', + description: 'Launch the new version', + deadline: '2026-04-03', + parentGoalId: null, + childOrder: 0, + isCompleted: false, + completedAt: null, + responsibleUid: null, + isDeleted: false, + progress: { + totalTaskCount: 5, + completedTaskCount: 2, + percentage: 40, + }, + creatorUid: 'user-1', + createdAt: '2026-03-25T10:00:00.000000Z', + updatedAt: '2026-03-25T10:00:00.000000Z', + }, + learnRust: { + id: 'e5f6g7h8-e29b-41d4-a716-446655440001', + ownerType: 'WORKSPACE', + ownerId: 'ws-1', + name: 'Learn Rust', + description: null, + deadline: null, + parentGoalId: null, + childOrder: 1, + isCompleted: true, + completedAt: '2026-03-20T15:00:00.000000Z', + responsibleUid: null, + isDeleted: false, + progress: { + totalTaskCount: 3, + completedTaskCount: 3, + percentage: 100, + }, + creatorUid: 'user-1', + createdAt: '2026-01-01T00:00:00.000000Z', + updatedAt: '2026-03-20T15:00:00.000000Z', + }, + }, user: { basic: { id: 'user-1', diff --git a/src/test-support/mock-api.ts b/src/test-support/mock-api.ts index c18049c7..84f0e46f 100644 --- a/src/test-support/mock-api.ts +++ b/src/test-support/mock-api.ts @@ -169,6 +169,17 @@ export function createMockApi(overrides: Partial = {}): MockApi { tasks: [], comments: [], }), + // Goals + getGoals: vi.fn().mockResolvedValue({ results: [], nextCursor: null }), + searchGoals: vi.fn().mockResolvedValue({ results: [], nextCursor: null }), + getGoal: vi.fn(), + addGoal: vi.fn(), + updateGoal: vi.fn(), + deleteGoal: vi.fn(), + completeGoal: vi.fn(), + uncompleteGoal: vi.fn(), + linkTaskToGoal: vi.fn(), + unlinkTaskFromGoal: vi.fn(), // Reminders (REST) getReminders: vi.fn().mockResolvedValue({ results: [], nextCursor: null }), getReminder: vi.fn(),