diff --git a/.changeset/config.json b/.changeset/config.json index bd439093..9ea24c24 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,17 +1,17 @@ -{ - "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json", - "changelog": [ - "@svitejs/changesets-changelog-github-compact", - { "repo": "TanStack/intent" } - ], - "commit": false, - "access": "public", - "baseBranch": "main", - "updateInternalDependencies": "patch", - "fixed": [], - "linked": [], - "ignore": [], - "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { - "onlyUpdatePeerDependentsWhenOutOfRange": true - } -} +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json", + "changelog": [ + "@svitejs/changesets-changelog-github-compact", + { "repo": "TanStack/intent" } + ], + "commit": false, + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "fixed": [], + "linked": [], + "ignore": [], + "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { + "onlyUpdatePeerDependentsWhenOutOfRange": true + } +} diff --git a/.changeset/whole-rocks-wait.md b/.changeset/whole-rocks-wait.md new file mode 100644 index 00000000..27fb6f0d --- /dev/null +++ b/.changeset/whole-rocks-wait.md @@ -0,0 +1,32 @@ +--- +'@tanstack/playbooks': patch +--- + +3 files changed in packages/playbooks/meta/ + +domain-discovery/SKILL.md (681 → ~792 lines) +- Added "Hard rules" section: 7 mandatory rules enforcing interactive interviews, prohibiting docs-as-substitute, question collapsing, and interview skipping +- Added 3 STOP gates between phases (1→2, 3→4, and after Phase 2d skill list confirmation) +- Strengthened Phase 2 & 4 headers with explicit interactivity requirements and "wait for response" instructions +- Added Phase 3 thoroughness: file checklist before reading, read-all enforcement, peer dependency analysis in Phase 1b +- Added 7 new constraint table rows for interview interactivity +- Updated cross-model compatibility notes with STOP gate and question protection rationale +- Added cross-package monorepo question in Phase 2a +- Added packages field to domain_map.yaml schema (package-relative ownership model) +- Softened feedback section to alpha-temporary + +- tree-generator/SKILL.md (859 → ~898 lines) +- Strengthened compressed discovery warning (requires maintainer confirmation to skip) +- Added packages field to skill_tree.yaml schema +- Added monorepo placement section with concrete directory tree example showing skills inside each package +- Added STOP gate after Step 1 (file tree review before writing) +- Added STOP gate after Step 8 (validation results review) +- Added 2 new constraint rows (file tree reviewed, validation presented) +- Softened feedback section to alpha-temporary + +- generate-skill/SKILL.md (419 → ~441 lines) +- Added packages field to frontmatter template +- Added monorepo path guidance: skills ship inside each package, not repo root +- Added STOP gate in Step 6: first skill reviewed before generating batch +- Added first-skill-reviewed constraint row +- Softened feedback section to alpha-temporary diff --git a/.prettierignore b/.prettierignore index f215b787..5b3091d4 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,12 +1,12 @@ -.github -**/.nx/ -**/.nx/cache -**/.svelte-kit -**/build -**/coverage -**/dist -**/docs -**/old-examples -pnpm-lock.yaml - -.angular +.github +**/.nx/ +**/.nx/cache +**/.svelte-kit +**/build +**/coverage +**/dist +**/docs +**/old-examples +pnpm-lock.yaml + +.angular diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 316e7a2b..2ebbdb45 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,55 +1,55 @@ ---- -title: Contributing -id: contributing ---- - -# Contributing - -## Questions - -If you have questions about implementation details, help or support, then please use our dedicated community forum at [Github Discussions](https://github.com/tanstack/intent/discussions) **PLEASE NOTE:** If you choose to instead open an issue for your question, your issue will be immediately closed and redirected to the forum. - -## Reporting Issues - -If you have found what you think is a bug, please [file an issue](https://github.com/tanstack/intent/issues/new). **PLEASE NOTE:** Issues that are identified as implementation questions or non-issues will be immediately closed and redirected to [Github Discussions](https://github.com/tanstack/intent/discussions) - -## Suggesting new features - -If you are here to suggest a feature, first create an issue if it does not already exist. From there, we will discuss use-cases for the feature and then finally discuss how it could be implemented. - -## Development - -Before proceeding with development, ensure you match one of the following criteria: - -- Fixing a small bug -- Fixing a larger issue that has been previously discussed and agreed-upon by maintainers -- Adding a new feature that has been previously discussed and agreed-upon by maintainers - -## Development Workflow - -- Fork this repository, we prefer the `feat-*` branch name style -- Ensure you have `pnpm` installed -- Install projects dependencies and linkages by running `pnpm install` -- Auto-build and auto-test files as you edit by running `pnpm dev` -- Implement your changes and tests -- To run examples, follow their individual directions. Usually this includes: - - cd into the example directory - - Do NOT install dependencies again or do any linking. Nx already handles this for you. Only run install from the project root. - - Starting the dev server with `pnpm dev` or `pnpm start` (from the example directory) -- To test in your own projects: - - Build/watch for changes with `pnpm build`/`pnpm dev` -- Document your changes in the appropriate documentation website markdown pages -- Run `pnpm test` to ensure all tests pass before committing -- Create a changeset (changelog entry) for your changes by running `pnpm changeset` -- Commit your work and open a pull request -- Submit PR for review - -## Adding a new example - -- Clone an existing example into the appropriate `examples` directory -- Name it the example name in kebab-case -- Update the new example's package.json to match the new example name and any other details -- Check dependencies for unused packages -- Install any additional packages to the example that you may need -- Update the docs/config.json file to include the new example in the navigation sidebar -- Commit the example eg. `docs: Add example-name` +--- +title: Contributing +id: contributing +--- + +# Contributing + +## Questions + +If you have questions about implementation details, help or support, then please use our dedicated community forum at [Github Discussions](https://github.com/tanstack/intent/discussions) **PLEASE NOTE:** If you choose to instead open an issue for your question, your issue will be immediately closed and redirected to the forum. + +## Reporting Issues + +If you have found what you think is a bug, please [file an issue](https://github.com/tanstack/intent/issues/new). **PLEASE NOTE:** Issues that are identified as implementation questions or non-issues will be immediately closed and redirected to [Github Discussions](https://github.com/tanstack/intent/discussions) + +## Suggesting new features + +If you are here to suggest a feature, first create an issue if it does not already exist. From there, we will discuss use-cases for the feature and then finally discuss how it could be implemented. + +## Development + +Before proceeding with development, ensure you match one of the following criteria: + +- Fixing a small bug +- Fixing a larger issue that has been previously discussed and agreed-upon by maintainers +- Adding a new feature that has been previously discussed and agreed-upon by maintainers + +## Development Workflow + +- Fork this repository, we prefer the `feat-*` branch name style +- Ensure you have `pnpm` installed +- Install projects dependencies and linkages by running `pnpm install` +- Auto-build and auto-test files as you edit by running `pnpm dev` +- Implement your changes and tests +- To run examples, follow their individual directions. Usually this includes: + - cd into the example directory + - Do NOT install dependencies again or do any linking. Nx already handles this for you. Only run install from the project root. + - Starting the dev server with `pnpm dev` or `pnpm start` (from the example directory) +- To test in your own projects: + - Build/watch for changes with `pnpm build`/`pnpm dev` +- Document your changes in the appropriate documentation website markdown pages +- Run `pnpm test` to ensure all tests pass before committing +- Create a changeset (changelog entry) for your changes by running `pnpm changeset` +- Commit your work and open a pull request +- Submit PR for review + +## Adding a new example + +- Clone an existing example into the appropriate `examples` directory +- Name it the example name in kebab-case +- Update the new example's package.json to match the new example name and any other details +- Check dependencies for unused packages +- Install any additional packages to the example that you may need +- Update the docs/config.json file to include the new example in the navigation sidebar +- Commit the example eg. `docs: Add example-name` diff --git a/LICENSE b/LICENSE index f6948992..2e8dc24f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2025-present Tanner Linsley - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2025-present Tanner Linsley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 449db8af..70d1ba49 100644 --- a/README.md +++ b/README.md @@ -1,88 +1,88 @@ -# @tanstack/intent - -Ship compositional knowledge for AI coding agents alongside your npm packages. - -## The problem - -Your docs are good. Your types are solid. Your agent still gets it wrong. - -Docs target humans who browse. Types check individual API calls but can't encode intent. Training data snapshots the ecosystem as it _was_, mixing versions without flagging which applies. Once a breaking change ships, models contain _both_ versions forever with no way to disambiguate. - -The ecosystem already moves toward agent-readable knowledge — Cursor rules, CLAUDE.md files, skills directories. But delivery is stuck in copy-paste: hunt for a community-maintained rules file, paste it into your config, repeat for every tool. No versioning, no update path, no staleness signal. - -## Skills: the fourth artifact - -You ship code, docs, and types. Skills are the fourth artifact — knowledge encoded for the thing writing most of your code. - -Skills are npm packages of knowledge — encoding how tools compose, which patterns fit which goals, and what to avoid. When a library ships skills using `@tanstack/intent`, that knowledge travels with the tool via `npm update` — not the model's training cutoff. Versioned knowledge the maintainer owns, updated when the package updates. - -Each skill declares its source docs. When those docs change, the CLI flags the skill for review. One source of truth, one derived artifact that stays in sync. - -## Quick Start - -### For library consumers - -Set up skill-to-task mappings in your project's agent config files (CLAUDE.md, .cursorrules, etc.): - -```bash -npx @tanstack/intent install -``` - -No per-library setup. No hunting for rules files. Install the package, run `intent install`, and the agent understands the tool. Update the package, and skills update too. - -List available skills from installed packages: - -```bash -npx @tanstack/intent list -``` - -### For library maintainers - -Generate skills for your library by telling your AI coding agent to run: - -```bash -npx @tanstack/intent scaffold -``` - -This prints a prompt that walks the agent through domain discovery, skill tree generation, and skill creation — one step at a time with your review at each stage. - -Validate your skill files: - -```bash -npx @tanstack/intent validate -``` - -Check for skills that have fallen behind their sources: - -```bash -npx @tanstack/intent stale -``` - -Copy CI workflow templates into your repo so validation and staleness checks run on every push: - -```bash -npx @tanstack/intent setup -``` - -## Keeping skills current - -The real risk with any derived artifact is staleness. `intent stale` flags skills whose source docs have changed, and CI templates catch drift before it ships. - -The feedback loop runs both directions. `intent feedback` lets users submit structured reports when a skill produces wrong output — which skill, which version, what broke. That context flows back to the maintainer, and the fix ships to everyone on the next `npm update`. - -## CLI Commands - -| Command | Description | -| ----------------------- | --------------------------------------------------- | -| `intent install` | Set up skill-to-task mappings in agent config files | -| `intent list [--json]` | Discover intent-enabled packages | -| `intent meta` | List meta-skills for library maintainers | -| `intent scaffold` | Print the guided skill generation prompt | -| `intent validate [dir]` | Validate SKILL.md files | -| `intent setup` | Copy CI templates, generate shim, create labels | -| `intent stale [--json]` | Check skills for version drift | -| `intent feedback` | Submit skill feedback | - -## License - -[MIT](./LICENSE) +# @tanstack/intent + +Ship compositional knowledge for AI coding agents alongside your npm packages. + +## The problem + +Your docs are good. Your types are solid. Your agent still gets it wrong. + +Docs target humans who browse. Types check individual API calls but can't encode intent. Training data snapshots the ecosystem as it _was_, mixing versions without flagging which applies. Once a breaking change ships, models contain _both_ versions forever with no way to disambiguate. + +The ecosystem already moves toward agent-readable knowledge — Cursor rules, CLAUDE.md files, skills directories. But delivery is stuck in copy-paste: hunt for a community-maintained rules file, paste it into your config, repeat for every tool. No versioning, no update path, no staleness signal. + +## Skills: the fourth artifact + +You ship code, docs, and types. Skills are the fourth artifact — knowledge encoded for the thing writing most of your code. + +Skills are npm packages of knowledge — encoding how tools compose, which patterns fit which goals, and what to avoid. When a library ships skills using `@tanstack/intent`, that knowledge travels with the tool via `npm update` — not the model's training cutoff. Versioned knowledge the maintainer owns, updated when the package updates. + +Each skill declares its source docs. When those docs change, the CLI flags the skill for review. One source of truth, one derived artifact that stays in sync. + +## Quick Start + +### For library consumers + +Set up skill-to-task mappings in your project's agent config files (CLAUDE.md, .cursorrules, etc.): + +```bash +npx @tanstack/intent install +``` + +No per-library setup. No hunting for rules files. Install the package, run `intent install`, and the agent understands the tool. Update the package, and skills update too. + +List available skills from installed packages: + +```bash +npx @tanstack/intent list +``` + +### For library maintainers + +Generate skills for your library by telling your AI coding agent to run: + +```bash +npx @tanstack/intent scaffold +``` + +This prints a prompt that walks the agent through domain discovery, skill tree generation, and skill creation — one step at a time with your review at each stage. + +Validate your skill files: + +```bash +npx @tanstack/intent validate +``` + +Check for skills that have fallen behind their sources: + +```bash +npx @tanstack/intent stale +``` + +Copy CI workflow templates into your repo so validation and staleness checks run on every push: + +```bash +npx @tanstack/intent setup +``` + +## Keeping skills current + +The real risk with any derived artifact is staleness. `intent stale` flags skills whose source docs have changed, and CI templates catch drift before it ships. + +The feedback loop runs both directions. `intent feedback` lets users submit structured reports when a skill produces wrong output — which skill, which version, what broke. That context flows back to the maintainer, and the fix ships to everyone on the next `npm update`. + +## CLI Commands + +| Command | Description | +| ----------------------- | --------------------------------------------------- | +| `intent install` | Set up skill-to-task mappings in agent config files | +| `intent list [--json]` | Discover intent-enabled packages | +| `intent meta` | List meta-skills for library maintainers | +| `intent scaffold` | Print the guided skill generation prompt | +| `intent validate [dir]` | Validate SKILL.md files | +| `intent setup` | Copy CI templates, generate shim, create labels | +| `intent stale [--json]` | Check skills for version drift | +| `intent feedback` | Submit skill feedback | + +## License + +[MIT](./LICENSE) diff --git a/docs/intent/functions/checkStaleness.md b/docs/intent/functions/checkStaleness.md index ac01981a..08ece52d 100644 --- a/docs/intent/functions/checkStaleness.md +++ b/docs/intent/functions/checkStaleness.md @@ -1,26 +1,26 @@ ---- -id: checkStaleness -title: checkStaleness ---- - -# Function: checkStaleness() - -```ts -function checkStaleness(packageDir, packageName?): Promise; -``` - -Defined in: [staleness.ts:75](https://github.com/TanStack/intent/blob/main/packages/intent/src/staleness.ts#L75) - -## Parameters - -### packageDir - -`string` - -### packageName? - -`string` - -## Returns - -`Promise`\<[`StalenessReport`](../interfaces/StalenessReport.md)\> +--- +id: checkStaleness +title: checkStaleness +--- + +# Function: checkStaleness() + +```ts +function checkStaleness(packageDir, packageName?): Promise; +``` + +Defined in: [staleness.ts:75](https://github.com/TanStack/intent/blob/main/packages/intent/src/staleness.ts#L75) + +## Parameters + +### packageDir + +`string` + +### packageName? + +`string` + +## Returns + +`Promise`\<[`StalenessReport`](../interfaces/StalenessReport.md)\> diff --git a/docs/intent/functions/containsSecrets.md b/docs/intent/functions/containsSecrets.md index 93acabe4..a19eea4b 100644 --- a/docs/intent/functions/containsSecrets.md +++ b/docs/intent/functions/containsSecrets.md @@ -1,22 +1,22 @@ ---- -id: containsSecrets -title: containsSecrets ---- - -# Function: containsSecrets() - -```ts -function containsSecrets(text): boolean; -``` - -Defined in: [feedback.ts:26](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L26) - -## Parameters - -### text - -`string` - -## Returns - -`boolean` +--- +id: containsSecrets +title: containsSecrets +--- + +# Function: containsSecrets() + +```ts +function containsSecrets(text): boolean; +``` + +Defined in: [feedback.ts:26](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L26) + +## Parameters + +### text + +`string` + +## Returns + +`boolean` diff --git a/docs/intent/functions/findSkillFiles.md b/docs/intent/functions/findSkillFiles.md index d06d76b4..28f86538 100644 --- a/docs/intent/functions/findSkillFiles.md +++ b/docs/intent/functions/findSkillFiles.md @@ -1,24 +1,24 @@ ---- -id: findSkillFiles -title: findSkillFiles ---- - -# Function: findSkillFiles() - -```ts -function findSkillFiles(dir): string[]; -``` - -Defined in: [utils.ts:8](https://github.com/TanStack/intent/blob/main/packages/intent/src/utils.ts#L8) - -Recursively find all SKILL.md files under a directory. - -## Parameters - -### dir - -`string` - -## Returns - -`string`[] +--- +id: findSkillFiles +title: findSkillFiles +--- + +# Function: findSkillFiles() + +```ts +function findSkillFiles(dir): string[]; +``` + +Defined in: [utils.ts:8](https://github.com/TanStack/intent/blob/main/packages/intent/src/utils.ts#L8) + +Recursively find all SKILL.md files under a directory. + +## Parameters + +### dir + +`string` + +## Returns + +`string`[] diff --git a/docs/intent/functions/hasGhCli.md b/docs/intent/functions/hasGhCli.md index 6265d151..d9bb14f2 100644 --- a/docs/intent/functions/hasGhCli.md +++ b/docs/intent/functions/hasGhCli.md @@ -1,16 +1,16 @@ ---- -id: hasGhCli -title: hasGhCli ---- - -# Function: hasGhCli() - -```ts -function hasGhCli(): boolean; -``` - -Defined in: [feedback.ts:34](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L34) - -## Returns - -`boolean` +--- +id: hasGhCli +title: hasGhCli +--- + +# Function: hasGhCli() + +```ts +function hasGhCli(): boolean; +``` + +Defined in: [feedback.ts:34](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L34) + +## Returns + +`boolean` diff --git a/docs/intent/functions/metaToMarkdown.md b/docs/intent/functions/metaToMarkdown.md index a0185850..336aaf88 100644 --- a/docs/intent/functions/metaToMarkdown.md +++ b/docs/intent/functions/metaToMarkdown.md @@ -1,22 +1,22 @@ ---- -id: metaToMarkdown -title: metaToMarkdown ---- - -# Function: metaToMarkdown() - -```ts -function metaToMarkdown(payload): string; -``` - -Defined in: [feedback.ts:222](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L222) - -## Parameters - -### payload - -[`MetaFeedbackPayload`](../interfaces/MetaFeedbackPayload.md) - -## Returns - -`string` +--- +id: metaToMarkdown +title: metaToMarkdown +--- + +# Function: metaToMarkdown() + +```ts +function metaToMarkdown(payload): string; +``` + +Defined in: [feedback.ts:222](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L222) + +## Parameters + +### payload + +[`MetaFeedbackPayload`](../interfaces/MetaFeedbackPayload.md) + +## Returns + +`string` diff --git a/docs/intent/functions/parseFrontmatter.md b/docs/intent/functions/parseFrontmatter.md index 45dd5aaf..b40ba6dc 100644 --- a/docs/intent/functions/parseFrontmatter.md +++ b/docs/intent/functions/parseFrontmatter.md @@ -1,24 +1,24 @@ ---- -id: parseFrontmatter -title: parseFrontmatter ---- - -# Function: parseFrontmatter() - -```ts -function parseFrontmatter(filePath): Record; -``` - -Defined in: [utils.ts:25](https://github.com/TanStack/intent/blob/main/packages/intent/src/utils.ts#L25) - -Parse YAML frontmatter from a file. Returns null if no frontmatter or on error. - -## Parameters - -### filePath - -`string` - -## Returns - -`Record`\<`string`, `unknown`\> +--- +id: parseFrontmatter +title: parseFrontmatter +--- + +# Function: parseFrontmatter() + +```ts +function parseFrontmatter(filePath): Record; +``` + +Defined in: [utils.ts:25](https://github.com/TanStack/intent/blob/main/packages/intent/src/utils.ts#L25) + +Parse YAML frontmatter from a file. Returns null if no frontmatter or on error. + +## Parameters + +### filePath + +`string` + +## Returns + +`Record`\<`string`, `unknown`\> diff --git a/docs/intent/functions/resolveFrequency.md b/docs/intent/functions/resolveFrequency.md index 2f7f9f5a..567e4e0a 100644 --- a/docs/intent/functions/resolveFrequency.md +++ b/docs/intent/functions/resolveFrequency.md @@ -1,22 +1,22 @@ ---- -id: resolveFrequency -title: resolveFrequency ---- - -# Function: resolveFrequency() - -```ts -function resolveFrequency(root): string; -``` - -Defined in: [feedback.ts:54](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L54) - -## Parameters - -### root - -`string` - -## Returns - -`string` +--- +id: resolveFrequency +title: resolveFrequency +--- + +# Function: resolveFrequency() + +```ts +function resolveFrequency(root): string; +``` + +Defined in: [feedback.ts:54](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L54) + +## Parameters + +### root + +`string` + +## Returns + +`string` diff --git a/docs/intent/functions/runSetup.md b/docs/intent/functions/runSetup.md index bbfe125b..aa86aa99 100644 --- a/docs/intent/functions/runSetup.md +++ b/docs/intent/functions/runSetup.md @@ -1,33 +1,33 @@ ---- -id: runSetup -title: runSetup ---- - -# Function: runSetup() - -```ts -function runSetup( - root, - metaDir, - args): SetupResult; -``` - -Defined in: [setup.ts:164](https://github.com/TanStack/intent/blob/main/packages/intent/src/setup.ts#L164) - -## Parameters - -### root - -`string` - -### metaDir - -`string` - -### args - -`string`[] - -## Returns - -`SetupResult` +--- +id: runSetup +title: runSetup +--- + +# Function: runSetup() + +```ts +function runSetup( + root, + metaDir, + args): SetupResult; +``` + +Defined in: [setup.ts:164](https://github.com/TanStack/intent/blob/main/packages/intent/src/setup.ts#L164) + +## Parameters + +### root + +`string` + +### metaDir + +`string` + +### args + +`string`[] + +## Returns + +`SetupResult` diff --git a/docs/intent/functions/scanForIntents.md b/docs/intent/functions/scanForIntents.md index a337ce54..617a1f40 100644 --- a/docs/intent/functions/scanForIntents.md +++ b/docs/intent/functions/scanForIntents.md @@ -1,22 +1,22 @@ ---- -id: scanForIntents -title: scanForIntents ---- - -# Function: scanForIntents() - -```ts -function scanForIntents(root?): Promise; -``` - -Defined in: [scanner.ts:190](https://github.com/TanStack/intent/blob/main/packages/intent/src/scanner.ts#L190) - -## Parameters - -### root? - -`string` - -## Returns - -`Promise`\<[`ScanResult`](../interfaces/ScanResult.md)\> +--- +id: scanForIntents +title: scanForIntents +--- + +# Function: scanForIntents() + +```ts +function scanForIntents(root?): Promise; +``` + +Defined in: [scanner.ts:190](https://github.com/TanStack/intent/blob/main/packages/intent/src/scanner.ts#L190) + +## Parameters + +### root? + +`string` + +## Returns + +`Promise`\<[`ScanResult`](../interfaces/ScanResult.md)\> diff --git a/docs/intent/functions/submitFeedback.md b/docs/intent/functions/submitFeedback.md index c023ce16..45aeabf1 100644 --- a/docs/intent/functions/submitFeedback.md +++ b/docs/intent/functions/submitFeedback.md @@ -1,39 +1,39 @@ ---- -id: submitFeedback -title: submitFeedback ---- - -# Function: submitFeedback() - -```ts -function submitFeedback( - payload, - repo, - opts): SubmitResult; -``` - -Defined in: [feedback.ts:294](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L294) - -## Parameters - -### payload - -[`FeedbackPayload`](../interfaces/FeedbackPayload.md) - -### repo - -`string` - -### opts - -#### ghAvailable - -`boolean` - -#### outputPath? - -`string` - -## Returns - -`SubmitResult` +--- +id: submitFeedback +title: submitFeedback +--- + +# Function: submitFeedback() + +```ts +function submitFeedback( + payload, + repo, + opts): SubmitResult; +``` + +Defined in: [feedback.ts:294](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L294) + +## Parameters + +### payload + +[`FeedbackPayload`](../interfaces/FeedbackPayload.md) + +### repo + +`string` + +### opts + +#### ghAvailable + +`boolean` + +#### outputPath? + +`string` + +## Returns + +`SubmitResult` diff --git a/docs/intent/functions/submitMetaFeedback.md b/docs/intent/functions/submitMetaFeedback.md index 4a261fa5..a5687994 100644 --- a/docs/intent/functions/submitMetaFeedback.md +++ b/docs/intent/functions/submitMetaFeedback.md @@ -1,32 +1,32 @@ ---- -id: submitMetaFeedback -title: submitMetaFeedback ---- - -# Function: submitMetaFeedback() - -```ts -function submitMetaFeedback(payload, opts): SubmitResult; -``` - -Defined in: [feedback.ts:332](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L332) - -## Parameters - -### payload - -[`MetaFeedbackPayload`](../interfaces/MetaFeedbackPayload.md) - -### opts - -#### ghAvailable - -`boolean` - -#### outputPath? - -`string` - -## Returns - -`SubmitResult` +--- +id: submitMetaFeedback +title: submitMetaFeedback +--- + +# Function: submitMetaFeedback() + +```ts +function submitMetaFeedback(payload, opts): SubmitResult; +``` + +Defined in: [feedback.ts:332](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L332) + +## Parameters + +### payload + +[`MetaFeedbackPayload`](../interfaces/MetaFeedbackPayload.md) + +### opts + +#### ghAvailable + +`boolean` + +#### outputPath? + +`string` + +## Returns + +`SubmitResult` diff --git a/docs/intent/functions/toMarkdown.md b/docs/intent/functions/toMarkdown.md index a1bb7e31..809a040c 100644 --- a/docs/intent/functions/toMarkdown.md +++ b/docs/intent/functions/toMarkdown.md @@ -1,22 +1,22 @@ ---- -id: toMarkdown -title: toMarkdown ---- - -# Function: toMarkdown() - -```ts -function toMarkdown(payload): string; -``` - -Defined in: [feedback.ts:254](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L254) - -## Parameters - -### payload - -[`FeedbackPayload`](../interfaces/FeedbackPayload.md) - -## Returns - -`string` +--- +id: toMarkdown +title: toMarkdown +--- + +# Function: toMarkdown() + +```ts +function toMarkdown(payload): string; +``` + +Defined in: [feedback.ts:254](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L254) + +## Parameters + +### payload + +[`FeedbackPayload`](../interfaces/FeedbackPayload.md) + +## Returns + +`string` diff --git a/docs/intent/functions/validateMetaPayload.md b/docs/intent/functions/validateMetaPayload.md index be4f2e64..f6909f28 100644 --- a/docs/intent/functions/validateMetaPayload.md +++ b/docs/intent/functions/validateMetaPayload.md @@ -1,34 +1,34 @@ ---- -id: validateMetaPayload -title: validateMetaPayload ---- - -# Function: validateMetaPayload() - -```ts -function validateMetaPayload(payload): object; -``` - -Defined in: [feedback.ts:163](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L163) - -## Parameters - -### payload - -`unknown` - -## Returns - -`object` - -### errors - -```ts -errors: string[]; -``` - -### valid - -```ts -valid: boolean; -``` +--- +id: validateMetaPayload +title: validateMetaPayload +--- + +# Function: validateMetaPayload() + +```ts +function validateMetaPayload(payload): object; +``` + +Defined in: [feedback.ts:163](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L163) + +## Parameters + +### payload + +`unknown` + +## Returns + +`object` + +### errors + +```ts +errors: string[]; +``` + +### valid + +```ts +valid: boolean; +``` diff --git a/docs/intent/functions/validatePayload.md b/docs/intent/functions/validatePayload.md index 07ad18dc..b1303e72 100644 --- a/docs/intent/functions/validatePayload.md +++ b/docs/intent/functions/validatePayload.md @@ -1,34 +1,34 @@ ---- -id: validatePayload -title: validatePayload ---- - -# Function: validatePayload() - -```ts -function validatePayload(payload): object; -``` - -Defined in: [feedback.ts:97](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L97) - -## Parameters - -### payload - -`unknown` - -## Returns - -`object` - -### errors - -```ts -errors: string[]; -``` - -### valid - -```ts -valid: boolean; -``` +--- +id: validatePayload +title: validatePayload +--- + +# Function: validatePayload() + +```ts +function validatePayload(payload): object; +``` + +Defined in: [feedback.ts:97](https://github.com/TanStack/intent/blob/main/packages/intent/src/feedback.ts#L97) + +## Parameters + +### payload + +`unknown` + +## Returns + +`object` + +### errors + +```ts +errors: string[]; +``` + +### valid + +```ts +valid: boolean; +``` diff --git a/docs/intent/index.md b/docs/intent/index.md index 8affefe1..3d184ef7 100644 --- a/docs/intent/index.md +++ b/docs/intent/index.md @@ -1,40 +1,40 @@ ---- -id: "@tanstack/intent" -title: "@tanstack/intent" ---- - -# @tanstack/intent - -## Interfaces - -- [FeedbackPayload](interfaces/FeedbackPayload.md) -- [IntentConfig](interfaces/IntentConfig.md) -- [IntentPackage](interfaces/IntentPackage.md) -- [IntentProjectConfig](interfaces/IntentProjectConfig.md) -- [MetaFeedbackPayload](interfaces/MetaFeedbackPayload.md) -- [ScanResult](interfaces/ScanResult.md) -- [SkillEntry](interfaces/SkillEntry.md) -- [SkillStaleness](interfaces/SkillStaleness.md) -- [StalenessReport](interfaces/StalenessReport.md) - -## Type Aliases - -- [AgentName](type-aliases/AgentName.md) -- [MetaSkillName](type-aliases/MetaSkillName.md) - -## Functions - -- [checkStaleness](functions/checkStaleness.md) -- [containsSecrets](functions/containsSecrets.md) -- [findSkillFiles](functions/findSkillFiles.md) -- [hasGhCli](functions/hasGhCli.md) -- [metaToMarkdown](functions/metaToMarkdown.md) -- [parseFrontmatter](functions/parseFrontmatter.md) -- [resolveFrequency](functions/resolveFrequency.md) -- [runSetup](functions/runSetup.md) -- [scanForIntents](functions/scanForIntents.md) -- [submitFeedback](functions/submitFeedback.md) -- [submitMetaFeedback](functions/submitMetaFeedback.md) -- [toMarkdown](functions/toMarkdown.md) -- [validateMetaPayload](functions/validateMetaPayload.md) -- [validatePayload](functions/validatePayload.md) +--- +id: "@tanstack/intent" +title: "@tanstack/intent" +--- + +# @tanstack/intent + +## Interfaces + +- [FeedbackPayload](interfaces/FeedbackPayload.md) +- [IntentConfig](interfaces/IntentConfig.md) +- [IntentPackage](interfaces/IntentPackage.md) +- [IntentProjectConfig](interfaces/IntentProjectConfig.md) +- [MetaFeedbackPayload](interfaces/MetaFeedbackPayload.md) +- [ScanResult](interfaces/ScanResult.md) +- [SkillEntry](interfaces/SkillEntry.md) +- [SkillStaleness](interfaces/SkillStaleness.md) +- [StalenessReport](interfaces/StalenessReport.md) + +## Type Aliases + +- [AgentName](type-aliases/AgentName.md) +- [MetaSkillName](type-aliases/MetaSkillName.md) + +## Functions + +- [checkStaleness](functions/checkStaleness.md) +- [containsSecrets](functions/containsSecrets.md) +- [findSkillFiles](functions/findSkillFiles.md) +- [hasGhCli](functions/hasGhCli.md) +- [metaToMarkdown](functions/metaToMarkdown.md) +- [parseFrontmatter](functions/parseFrontmatter.md) +- [resolveFrequency](functions/resolveFrequency.md) +- [runSetup](functions/runSetup.md) +- [scanForIntents](functions/scanForIntents.md) +- [submitFeedback](functions/submitFeedback.md) +- [submitMetaFeedback](functions/submitMetaFeedback.md) +- [toMarkdown](functions/toMarkdown.md) +- [validateMetaPayload](functions/validateMetaPayload.md) +- [validatePayload](functions/validatePayload.md) diff --git a/docs/intent/interfaces/FeedbackPayload.md b/docs/intent/interfaces/FeedbackPayload.md index 9fa2a679..6c7865d8 100644 --- a/docs/intent/interfaces/FeedbackPayload.md +++ b/docs/intent/interfaces/FeedbackPayload.md @@ -1,108 +1,108 @@ ---- -id: FeedbackPayload -title: FeedbackPayload ---- - -# Interface: FeedbackPayload - -Defined in: [types.ts:59](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L59) - -## Properties - -### missing - -```ts -missing: string; -``` - -Defined in: [types.ts:66](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L66) - -*** - -### package - -```ts -package: string; -``` - -Defined in: [types.ts:61](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L61) - -*** - -### selfCorrections - -```ts -selfCorrections: string; -``` - -Defined in: [types.ts:67](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L67) - -*** - -### skill - -```ts -skill: string; -``` - -Defined in: [types.ts:60](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L60) - -*** - -### skillVersion - -```ts -skillVersion: string; -``` - -Defined in: [types.ts:62](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L62) - -*** - -### task - -```ts -task: string; -``` - -Defined in: [types.ts:63](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L63) - -*** - -### userComments? - -```ts -optional userComments: string; -``` - -Defined in: [types.ts:69](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L69) - -*** - -### userRating - -```ts -userRating: "good" | "mixed" | "bad"; -``` - -Defined in: [types.ts:68](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L68) - -*** - -### whatFailed - -```ts -whatFailed: string; -``` - -Defined in: [types.ts:65](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L65) - -*** - -### whatWorked - -```ts -whatWorked: string; -``` - -Defined in: [types.ts:64](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L64) +--- +id: FeedbackPayload +title: FeedbackPayload +--- + +# Interface: FeedbackPayload + +Defined in: [types.ts:59](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L59) + +## Properties + +### missing + +```ts +missing: string; +``` + +Defined in: [types.ts:66](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L66) + +*** + +### package + +```ts +package: string; +``` + +Defined in: [types.ts:61](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L61) + +*** + +### selfCorrections + +```ts +selfCorrections: string; +``` + +Defined in: [types.ts:67](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L67) + +*** + +### skill + +```ts +skill: string; +``` + +Defined in: [types.ts:60](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L60) + +*** + +### skillVersion + +```ts +skillVersion: string; +``` + +Defined in: [types.ts:62](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L62) + +*** + +### task + +```ts +task: string; +``` + +Defined in: [types.ts:63](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L63) + +*** + +### userComments? + +```ts +optional userComments: string; +``` + +Defined in: [types.ts:69](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L69) + +*** + +### userRating + +```ts +userRating: "good" | "mixed" | "bad"; +``` + +Defined in: [types.ts:68](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L68) + +*** + +### whatFailed + +```ts +whatFailed: string; +``` + +Defined in: [types.ts:65](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L65) + +*** + +### whatWorked + +```ts +whatWorked: string; +``` + +Defined in: [types.ts:64](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L64) diff --git a/docs/intent/interfaces/IntentConfig.md b/docs/intent/interfaces/IntentConfig.md index d1856351..c2e91053 100644 --- a/docs/intent/interfaces/IntentConfig.md +++ b/docs/intent/interfaces/IntentConfig.md @@ -1,48 +1,48 @@ ---- -id: IntentConfig -title: IntentConfig ---- - -# Interface: IntentConfig - -Defined in: [types.ts:5](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L5) - -## Properties - -### docs - -```ts -docs: string; -``` - -Defined in: [types.ts:8](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L8) - -*** - -### repo - -```ts -repo: string; -``` - -Defined in: [types.ts:7](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L7) - -*** - -### requires? - -```ts -optional requires: string[]; -``` - -Defined in: [types.ts:9](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L9) - -*** - -### version - -```ts -version: number; -``` - -Defined in: [types.ts:6](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L6) +--- +id: IntentConfig +title: IntentConfig +--- + +# Interface: IntentConfig + +Defined in: [types.ts:5](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L5) + +## Properties + +### docs + +```ts +docs: string; +``` + +Defined in: [types.ts:8](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L8) + +*** + +### repo + +```ts +repo: string; +``` + +Defined in: [types.ts:7](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L7) + +*** + +### requires? + +```ts +optional requires: string[]; +``` + +Defined in: [types.ts:9](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L9) + +*** + +### version + +```ts +version: number; +``` + +Defined in: [types.ts:6](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L6) diff --git a/docs/intent/interfaces/IntentPackage.md b/docs/intent/interfaces/IntentPackage.md index 68aa89fc..ca9dfa3b 100644 --- a/docs/intent/interfaces/IntentPackage.md +++ b/docs/intent/interfaces/IntentPackage.md @@ -1,48 +1,48 @@ ---- -id: IntentPackage -title: IntentPackage ---- - -# Interface: IntentPackage - -Defined in: [types.ts:22](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L22) - -## Properties - -### intent - -```ts -intent: IntentConfig; -``` - -Defined in: [types.ts:25](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L25) - -*** - -### name - -```ts -name: string; -``` - -Defined in: [types.ts:23](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L23) - -*** - -### skills - -```ts -skills: SkillEntry[]; -``` - -Defined in: [types.ts:26](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L26) - -*** - -### version - -```ts -version: string; -``` - -Defined in: [types.ts:24](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L24) +--- +id: IntentPackage +title: IntentPackage +--- + +# Interface: IntentPackage + +Defined in: [types.ts:22](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L22) + +## Properties + +### intent + +```ts +intent: IntentConfig; +``` + +Defined in: [types.ts:25](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L25) + +*** + +### name + +```ts +name: string; +``` + +Defined in: [types.ts:23](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L23) + +*** + +### skills + +```ts +skills: SkillEntry[]; +``` + +Defined in: [types.ts:26](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L26) + +*** + +### version + +```ts +version: string; +``` + +Defined in: [types.ts:24](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L24) diff --git a/docs/intent/interfaces/IntentProjectConfig.md b/docs/intent/interfaces/IntentProjectConfig.md index da6bca86..bc3b5a39 100644 --- a/docs/intent/interfaces/IntentProjectConfig.md +++ b/docs/intent/interfaces/IntentProjectConfig.md @@ -1,24 +1,24 @@ ---- -id: IntentProjectConfig -title: IntentProjectConfig ---- - -# Interface: IntentProjectConfig - -Defined in: [types.ts:101](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L101) - -## Properties - -### feedback - -```ts -feedback: object; -``` - -Defined in: [types.ts:102](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L102) - -#### frequency - -```ts -frequency: string; -``` +--- +id: IntentProjectConfig +title: IntentProjectConfig +--- + +# Interface: IntentProjectConfig + +Defined in: [types.ts:101](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L101) + +## Properties + +### feedback + +```ts +feedback: object; +``` + +Defined in: [types.ts:102](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L102) + +#### frequency + +```ts +frequency: string; +``` diff --git a/docs/intent/interfaces/MetaFeedbackPayload.md b/docs/intent/interfaces/MetaFeedbackPayload.md index 6550fb99..89e12c93 100644 --- a/docs/intent/interfaces/MetaFeedbackPayload.md +++ b/docs/intent/interfaces/MetaFeedbackPayload.md @@ -1,108 +1,108 @@ ---- -id: MetaFeedbackPayload -title: MetaFeedbackPayload ---- - -# Interface: MetaFeedbackPayload - -Defined in: [types.ts:84](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L84) - -## Properties - -### agentUsed - -```ts -agentUsed: AgentName; -``` - -Defined in: [types.ts:87](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L87) - -*** - -### artifactQuality - -```ts -artifactQuality: "good" | "mixed" | "bad"; -``` - -Defined in: [types.ts:88](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L88) - -*** - -### failureModeQuality? - -```ts -optional failureModeQuality: "good" | "mixed" | "bad" | "not-applicable"; -``` - -Defined in: [types.ts:90](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L90) - -*** - -### interviewQuality? - -```ts -optional interviewQuality: "skipped" | "good" | "mixed" | "bad"; -``` - -Defined in: [types.ts:89](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L89) - -*** - -### library - -```ts -library: string; -``` - -Defined in: [types.ts:86](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L86) - -*** - -### metaSkill - -```ts -metaSkill: MetaSkillName; -``` - -Defined in: [types.ts:85](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L85) - -*** - -### suggestions - -```ts -suggestions: string; -``` - -Defined in: [types.ts:93](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L93) - -*** - -### userRating - -```ts -userRating: "good" | "mixed" | "bad"; -``` - -Defined in: [types.ts:94](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L94) - -*** - -### whatFailed - -```ts -whatFailed: string; -``` - -Defined in: [types.ts:92](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L92) - -*** - -### whatWorked - -```ts -whatWorked: string; -``` - -Defined in: [types.ts:91](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L91) +--- +id: MetaFeedbackPayload +title: MetaFeedbackPayload +--- + +# Interface: MetaFeedbackPayload + +Defined in: [types.ts:84](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L84) + +## Properties + +### agentUsed + +```ts +agentUsed: AgentName; +``` + +Defined in: [types.ts:87](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L87) + +*** + +### artifactQuality + +```ts +artifactQuality: "good" | "mixed" | "bad"; +``` + +Defined in: [types.ts:88](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L88) + +*** + +### failureModeQuality? + +```ts +optional failureModeQuality: "good" | "mixed" | "bad" | "not-applicable"; +``` + +Defined in: [types.ts:90](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L90) + +*** + +### interviewQuality? + +```ts +optional interviewQuality: "skipped" | "good" | "mixed" | "bad"; +``` + +Defined in: [types.ts:89](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L89) + +*** + +### library + +```ts +library: string; +``` + +Defined in: [types.ts:86](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L86) + +*** + +### metaSkill + +```ts +metaSkill: MetaSkillName; +``` + +Defined in: [types.ts:85](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L85) + +*** + +### suggestions + +```ts +suggestions: string; +``` + +Defined in: [types.ts:93](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L93) + +*** + +### userRating + +```ts +userRating: "good" | "mixed" | "bad"; +``` + +Defined in: [types.ts:94](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L94) + +*** + +### whatFailed + +```ts +whatFailed: string; +``` + +Defined in: [types.ts:92](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L92) + +*** + +### whatWorked + +```ts +whatWorked: string; +``` + +Defined in: [types.ts:91](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L91) diff --git a/docs/intent/interfaces/ScanResult.md b/docs/intent/interfaces/ScanResult.md index 7db217fa..fc409af1 100644 --- a/docs/intent/interfaces/ScanResult.md +++ b/docs/intent/interfaces/ScanResult.md @@ -1,38 +1,38 @@ ---- -id: ScanResult -title: ScanResult ---- - -# Interface: ScanResult - -Defined in: [types.ts:16](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L16) - -## Properties - -### packageManager - -```ts -packageManager: "unknown" | "npm" | "pnpm" | "yarn" | "bun"; -``` - -Defined in: [types.ts:17](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L17) - -*** - -### packages - -```ts -packages: IntentPackage[]; -``` - -Defined in: [types.ts:18](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L18) - -*** - -### warnings - -```ts -warnings: string[]; -``` - -Defined in: [types.ts:19](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L19) +--- +id: ScanResult +title: ScanResult +--- + +# Interface: ScanResult + +Defined in: [types.ts:16](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L16) + +## Properties + +### packageManager + +```ts +packageManager: "unknown" | "npm" | "pnpm" | "yarn" | "bun"; +``` + +Defined in: [types.ts:17](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L17) + +*** + +### packages + +```ts +packages: IntentPackage[]; +``` + +Defined in: [types.ts:18](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L18) + +*** + +### warnings + +```ts +warnings: string[]; +``` + +Defined in: [types.ts:19](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L19) diff --git a/docs/intent/interfaces/SkillEntry.md b/docs/intent/interfaces/SkillEntry.md index d801101c..3a25260a 100644 --- a/docs/intent/interfaces/SkillEntry.md +++ b/docs/intent/interfaces/SkillEntry.md @@ -1,58 +1,58 @@ ---- -id: SkillEntry -title: SkillEntry ---- - -# Interface: SkillEntry - -Defined in: [types.ts:29](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L29) - -## Properties - -### description - -```ts -description: string; -``` - -Defined in: [types.ts:32](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L32) - -*** - -### framework? - -```ts -optional framework: string; -``` - -Defined in: [types.ts:34](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L34) - -*** - -### name - -```ts -name: string; -``` - -Defined in: [types.ts:30](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L30) - -*** - -### path - -```ts -path: string; -``` - -Defined in: [types.ts:31](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L31) - -*** - -### type? - -```ts -optional type: string; -``` - -Defined in: [types.ts:33](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L33) +--- +id: SkillEntry +title: SkillEntry +--- + +# Interface: SkillEntry + +Defined in: [types.ts:29](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L29) + +## Properties + +### description + +```ts +description: string; +``` + +Defined in: [types.ts:32](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L32) + +*** + +### framework? + +```ts +optional framework: string; +``` + +Defined in: [types.ts:34](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L34) + +*** + +### name + +```ts +name: string; +``` + +Defined in: [types.ts:30](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L30) + +*** + +### path + +```ts +path: string; +``` + +Defined in: [types.ts:31](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L31) + +*** + +### type? + +```ts +optional type: string; +``` + +Defined in: [types.ts:33](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L33) diff --git a/docs/intent/interfaces/SkillStaleness.md b/docs/intent/interfaces/SkillStaleness.md index 29324cc9..c9eed7b2 100644 --- a/docs/intent/interfaces/SkillStaleness.md +++ b/docs/intent/interfaces/SkillStaleness.md @@ -1,38 +1,38 @@ ---- -id: SkillStaleness -title: SkillStaleness ---- - -# Interface: SkillStaleness - -Defined in: [types.ts:49](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L49) - -## Properties - -### name - -```ts -name: string; -``` - -Defined in: [types.ts:50](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L50) - -*** - -### needsReview - -```ts -needsReview: boolean; -``` - -Defined in: [types.ts:52](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L52) - -*** - -### reasons - -```ts -reasons: string[]; -``` - -Defined in: [types.ts:51](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L51) +--- +id: SkillStaleness +title: SkillStaleness +--- + +# Interface: SkillStaleness + +Defined in: [types.ts:49](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L49) + +## Properties + +### name + +```ts +name: string; +``` + +Defined in: [types.ts:50](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L50) + +*** + +### needsReview + +```ts +needsReview: boolean; +``` + +Defined in: [types.ts:52](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L52) + +*** + +### reasons + +```ts +reasons: string[]; +``` + +Defined in: [types.ts:51](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L51) diff --git a/docs/intent/interfaces/StalenessReport.md b/docs/intent/interfaces/StalenessReport.md index 40057b4c..ca04ba0b 100644 --- a/docs/intent/interfaces/StalenessReport.md +++ b/docs/intent/interfaces/StalenessReport.md @@ -1,58 +1,58 @@ ---- -id: StalenessReport -title: StalenessReport ---- - -# Interface: StalenessReport - -Defined in: [types.ts:41](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L41) - -## Properties - -### currentVersion - -```ts -currentVersion: string; -``` - -Defined in: [types.ts:43](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L43) - -*** - -### library - -```ts -library: string; -``` - -Defined in: [types.ts:42](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L42) - -*** - -### skills - -```ts -skills: SkillStaleness[]; -``` - -Defined in: [types.ts:46](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L46) - -*** - -### skillVersion - -```ts -skillVersion: string; -``` - -Defined in: [types.ts:44](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L44) - -*** - -### versionDrift - -```ts -versionDrift: "major" | "minor" | "patch"; -``` - -Defined in: [types.ts:45](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L45) +--- +id: StalenessReport +title: StalenessReport +--- + +# Interface: StalenessReport + +Defined in: [types.ts:41](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L41) + +## Properties + +### currentVersion + +```ts +currentVersion: string; +``` + +Defined in: [types.ts:43](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L43) + +*** + +### library + +```ts +library: string; +``` + +Defined in: [types.ts:42](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L42) + +*** + +### skills + +```ts +skills: SkillStaleness[]; +``` + +Defined in: [types.ts:46](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L46) + +*** + +### skillVersion + +```ts +skillVersion: string; +``` + +Defined in: [types.ts:44](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L44) + +*** + +### versionDrift + +```ts +versionDrift: "major" | "minor" | "patch"; +``` + +Defined in: [types.ts:45](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L45) diff --git a/docs/intent/type-aliases/AgentName.md b/docs/intent/type-aliases/AgentName.md index 0f3a56c4..76519b81 100644 --- a/docs/intent/type-aliases/AgentName.md +++ b/docs/intent/type-aliases/AgentName.md @@ -1,12 +1,12 @@ ---- -id: AgentName -title: AgentName ---- - -# Type Alias: AgentName - -```ts -type AgentName = "claude-code" | "cursor" | "copilot" | "codex" | "other"; -``` - -Defined in: [types.ts:82](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L82) +--- +id: AgentName +title: AgentName +--- + +# Type Alias: AgentName + +```ts +type AgentName = "claude-code" | "cursor" | "copilot" | "codex" | "other"; +``` + +Defined in: [types.ts:82](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L82) diff --git a/docs/intent/type-aliases/MetaSkillName.md b/docs/intent/type-aliases/MetaSkillName.md index 570dd16b..8e534b90 100644 --- a/docs/intent/type-aliases/MetaSkillName.md +++ b/docs/intent/type-aliases/MetaSkillName.md @@ -1,16 +1,16 @@ ---- -id: MetaSkillName -title: MetaSkillName ---- - -# Type Alias: MetaSkillName - -```ts -type MetaSkillName = - | "domain-discovery" - | "tree-generator" - | "generate-skill" - | "skill-staleness-check"; -``` - -Defined in: [types.ts:76](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L76) +--- +id: MetaSkillName +title: MetaSkillName +--- + +# Type Alias: MetaSkillName + +```ts +type MetaSkillName = + | "domain-discovery" + | "tree-generator" + | "generate-skill" + | "skill-staleness-check"; +``` + +Defined in: [types.ts:76](https://github.com/TanStack/intent/blob/main/packages/intent/src/types.ts#L76) diff --git a/knip.json b/knip.json index 023c5fdf..b31558b4 100644 --- a/knip.json +++ b/knip.json @@ -1,13 +1,13 @@ -{ - "$schema": "https://unpkg.com/knip@5/schema.json", - "ignoreDependencies": ["@faker-js/faker"], - "ignoreBinaries": ["tsx"], - "workspaces": { - ".": { - "entry": ["scripts/*.ts"] - }, - "packages/intent": { - "ignore": ["meta/**"] - } - } -} +{ + "$schema": "https://unpkg.com/knip@5/schema.json", + "ignoreDependencies": ["@faker-js/faker"], + "ignoreBinaries": ["tsx"], + "workspaces": { + ".": { + "entry": ["scripts/*.ts"] + }, + "packages/intent": { + "ignore": ["meta/**"] + } + } +} diff --git a/package.json b/package.json index 54cc6177..ec16cbb5 100644 --- a/package.json +++ b/package.json @@ -1,69 +1,69 @@ -{ - "name": "root", - "private": true, - "repository": { - "type": "git", - "url": "git+https://github.com/TanStack/intent.git" - }, - "packageManager": "pnpm@10.26.1", - "type": "module", - "scripts": { - "build": "nx affected --skip-nx-cache --targets=build --exclude=examples/**", - "build:all": "nx run-many --targets=build --exclude=examples/**", - "build:core": "nx run-many --targets=build --projects=packages/agents", - "changeset": "changeset", - "changeset:publish": "changeset publish", - "changeset:version": "changeset version && pnpm install --no-frozen-lockfile && pnpm format", - "clean": "find agents -name 'dist' -type d -prune -exec rm -rf {} +", - "clean:node_modules": "find agents -name 'node_modules' -type d -prune -exec rm -rf {} +", - "clean:all": "pnpm run clean && pnpm run clean:node_modules", - "copy:readme": "cp README.md packages/intent/README.md", - "dev": "pnpm run watch", - "format": "prettier --experimental-cli --ignore-unknown '**/*' --write", - "lint:fix": "nx affected --target=lint:fix --exclude=examples/**", - "lint:fix:all": "nx run-many --targets=lint --fix", - "test": "pnpm run test:ci", - "test:ci": "tsc --noEmit && nx run-many --targets=test:eslint,test:sherif,test:knip,test:docs,test:lib,test:types,build", - "generate-docs": "node scripts/generate-docs.ts", - "test:docs": "node scripts/verify-links.ts", - "test:eslint": "nx affected --target=test:eslint --exclude=examples/**", - "test:knip": "knip", - "test:lib": "nx affected --targets=test:lib --exclude=examples/**", - "test:lib:dev": "pnpm test:lib && nx watch --all -- pnpm test:lib", - "test:pr": "tsc --noEmit && nx affected --targets=test:eslint,test:sherif,test:knip,test:docs,test:lib,test:types,build", - "test:sherif": "sherif", - "test:types": "nx affected --targets=test:types --exclude=examples/**", - "watch": "pnpm run build:all && nx watch --all -- pnpm run build:all" - }, - "nx": { - "includedScripts": [ - "test:docs", - "test:knip", - "test:sherif" - ] - }, - "devDependencies": { - "@changesets/cli": "^2.29.8", - "@faker-js/faker": "^10.2.0", - "@svitejs/changesets-changelog-github-compact": "^1.2.0", - "@tanstack/eslint-config": "0.3.4", - "@types/node": "^25.0.7", - "eslint": "^9.39.2", - "eslint-plugin-unused-imports": "^4.3.0", - "happy-dom": "^20.1.0", - "knip": "^5.80.2", - "markdown-link-extractor": "^4.0.3", - "nx": "^22.3.3", - "prettier": "^3.7.4", - "prettier-plugin-svelte": "^3.4.1", - "sherif": "^1.9.0", - "tinyglobby": "^0.2.15", - "typescript": "5.9.3", - "vitest": "^4.0.17", - "yaml": "^2.7.0" - }, - "overrides": {}, - "dependencies": { - "@tanstack/typedoc-config": "^0.3.3" - } -} +{ + "name": "root", + "private": true, + "repository": { + "type": "git", + "url": "git+https://github.com/TanStack/intent.git" + }, + "packageManager": "pnpm@10.26.1", + "type": "module", + "scripts": { + "build": "nx affected --skip-nx-cache --targets=build --exclude=examples/**", + "build:all": "nx run-many --targets=build --exclude=examples/**", + "build:core": "nx run-many --targets=build --projects=packages/agents", + "changeset": "changeset", + "changeset:publish": "changeset publish", + "changeset:version": "changeset version && pnpm install --no-frozen-lockfile && pnpm format", + "clean": "find agents -name 'dist' -type d -prune -exec rm -rf {} +", + "clean:node_modules": "find agents -name 'node_modules' -type d -prune -exec rm -rf {} +", + "clean:all": "pnpm run clean && pnpm run clean:node_modules", + "copy:readme": "cp README.md packages/intent/README.md", + "dev": "pnpm run watch", + "format": "prettier --experimental-cli --ignore-unknown '**/*' --write", + "lint:fix": "nx affected --target=lint:fix --exclude=examples/**", + "lint:fix:all": "nx run-many --targets=lint --fix", + "test": "pnpm run test:ci", + "test:ci": "tsc --noEmit && nx run-many --targets=test:eslint,test:sherif,test:knip,test:docs,test:lib,test:types,build", + "generate-docs": "node scripts/generate-docs.ts", + "test:docs": "node scripts/verify-links.ts", + "test:eslint": "nx affected --target=test:eslint --exclude=examples/**", + "test:knip": "knip", + "test:lib": "nx affected --targets=test:lib --exclude=examples/**", + "test:lib:dev": "pnpm test:lib && nx watch --all -- pnpm test:lib", + "test:pr": "tsc --noEmit && nx affected --targets=test:eslint,test:sherif,test:knip,test:docs,test:lib,test:types,build", + "test:sherif": "sherif", + "test:types": "nx affected --targets=test:types --exclude=examples/**", + "watch": "pnpm run build:all && nx watch --all -- pnpm run build:all" + }, + "nx": { + "includedScripts": [ + "test:docs", + "test:knip", + "test:sherif" + ] + }, + "devDependencies": { + "@changesets/cli": "^2.29.8", + "@faker-js/faker": "^10.2.0", + "@svitejs/changesets-changelog-github-compact": "^1.2.0", + "@tanstack/eslint-config": "0.3.4", + "@types/node": "^25.0.7", + "eslint": "^9.39.2", + "eslint-plugin-unused-imports": "^4.3.0", + "happy-dom": "^20.1.0", + "knip": "^5.80.2", + "markdown-link-extractor": "^4.0.3", + "nx": "^22.3.3", + "prettier": "^3.7.4", + "prettier-plugin-svelte": "^3.4.1", + "sherif": "^1.9.0", + "tinyglobby": "^0.2.15", + "typescript": "5.9.3", + "vitest": "^4.0.17", + "yaml": "^2.7.0" + }, + "overrides": {}, + "dependencies": { + "@tanstack/typedoc-config": "^0.3.3" + } +} diff --git a/packages/intent/CHANGELOG.md b/packages/intent/CHANGELOG.md index 17e41f3c..1d54b8a4 100644 --- a/packages/intent/CHANGELOG.md +++ b/packages/intent/CHANGELOG.md @@ -1,7 +1,7 @@ -# @tanstack/intent - -## 0.1.0 - -### Patch Changes - -- Add `intent-library` end-user CLI for library consumers. Libraries wire it up via a generated shim (`intent setup --shim`) to expose an `intent` bin. Running `intent list` recursively discovers skills across the library's dependency tree; `intent install` prints an agent-driven prompt to map skills to project tasks in CLAUDE.md. ([#9](https://github.com/TanStack/intent/pull/9)) +# @tanstack/intent + +## 0.1.0 + +### Patch Changes + +- Add `intent-library` end-user CLI for library consumers. Libraries wire it up via a generated shim (`intent setup --shim`) to expose an `intent` bin. Running `intent list` recursively discovers skills across the library's dependency tree; `intent install` prints an agent-driven prompt to map skills to project tasks in CLAUDE.md. ([#9](https://github.com/TanStack/intent/pull/9)) diff --git a/packages/intent/README.md b/packages/intent/README.md index 449db8af..70d1ba49 100644 --- a/packages/intent/README.md +++ b/packages/intent/README.md @@ -1,88 +1,88 @@ -# @tanstack/intent - -Ship compositional knowledge for AI coding agents alongside your npm packages. - -## The problem - -Your docs are good. Your types are solid. Your agent still gets it wrong. - -Docs target humans who browse. Types check individual API calls but can't encode intent. Training data snapshots the ecosystem as it _was_, mixing versions without flagging which applies. Once a breaking change ships, models contain _both_ versions forever with no way to disambiguate. - -The ecosystem already moves toward agent-readable knowledge — Cursor rules, CLAUDE.md files, skills directories. But delivery is stuck in copy-paste: hunt for a community-maintained rules file, paste it into your config, repeat for every tool. No versioning, no update path, no staleness signal. - -## Skills: the fourth artifact - -You ship code, docs, and types. Skills are the fourth artifact — knowledge encoded for the thing writing most of your code. - -Skills are npm packages of knowledge — encoding how tools compose, which patterns fit which goals, and what to avoid. When a library ships skills using `@tanstack/intent`, that knowledge travels with the tool via `npm update` — not the model's training cutoff. Versioned knowledge the maintainer owns, updated when the package updates. - -Each skill declares its source docs. When those docs change, the CLI flags the skill for review. One source of truth, one derived artifact that stays in sync. - -## Quick Start - -### For library consumers - -Set up skill-to-task mappings in your project's agent config files (CLAUDE.md, .cursorrules, etc.): - -```bash -npx @tanstack/intent install -``` - -No per-library setup. No hunting for rules files. Install the package, run `intent install`, and the agent understands the tool. Update the package, and skills update too. - -List available skills from installed packages: - -```bash -npx @tanstack/intent list -``` - -### For library maintainers - -Generate skills for your library by telling your AI coding agent to run: - -```bash -npx @tanstack/intent scaffold -``` - -This prints a prompt that walks the agent through domain discovery, skill tree generation, and skill creation — one step at a time with your review at each stage. - -Validate your skill files: - -```bash -npx @tanstack/intent validate -``` - -Check for skills that have fallen behind their sources: - -```bash -npx @tanstack/intent stale -``` - -Copy CI workflow templates into your repo so validation and staleness checks run on every push: - -```bash -npx @tanstack/intent setup -``` - -## Keeping skills current - -The real risk with any derived artifact is staleness. `intent stale` flags skills whose source docs have changed, and CI templates catch drift before it ships. - -The feedback loop runs both directions. `intent feedback` lets users submit structured reports when a skill produces wrong output — which skill, which version, what broke. That context flows back to the maintainer, and the fix ships to everyone on the next `npm update`. - -## CLI Commands - -| Command | Description | -| ----------------------- | --------------------------------------------------- | -| `intent install` | Set up skill-to-task mappings in agent config files | -| `intent list [--json]` | Discover intent-enabled packages | -| `intent meta` | List meta-skills for library maintainers | -| `intent scaffold` | Print the guided skill generation prompt | -| `intent validate [dir]` | Validate SKILL.md files | -| `intent setup` | Copy CI templates, generate shim, create labels | -| `intent stale [--json]` | Check skills for version drift | -| `intent feedback` | Submit skill feedback | - -## License - -[MIT](./LICENSE) +# @tanstack/intent + +Ship compositional knowledge for AI coding agents alongside your npm packages. + +## The problem + +Your docs are good. Your types are solid. Your agent still gets it wrong. + +Docs target humans who browse. Types check individual API calls but can't encode intent. Training data snapshots the ecosystem as it _was_, mixing versions without flagging which applies. Once a breaking change ships, models contain _both_ versions forever with no way to disambiguate. + +The ecosystem already moves toward agent-readable knowledge — Cursor rules, CLAUDE.md files, skills directories. But delivery is stuck in copy-paste: hunt for a community-maintained rules file, paste it into your config, repeat for every tool. No versioning, no update path, no staleness signal. + +## Skills: the fourth artifact + +You ship code, docs, and types. Skills are the fourth artifact — knowledge encoded for the thing writing most of your code. + +Skills are npm packages of knowledge — encoding how tools compose, which patterns fit which goals, and what to avoid. When a library ships skills using `@tanstack/intent`, that knowledge travels with the tool via `npm update` — not the model's training cutoff. Versioned knowledge the maintainer owns, updated when the package updates. + +Each skill declares its source docs. When those docs change, the CLI flags the skill for review. One source of truth, one derived artifact that stays in sync. + +## Quick Start + +### For library consumers + +Set up skill-to-task mappings in your project's agent config files (CLAUDE.md, .cursorrules, etc.): + +```bash +npx @tanstack/intent install +``` + +No per-library setup. No hunting for rules files. Install the package, run `intent install`, and the agent understands the tool. Update the package, and skills update too. + +List available skills from installed packages: + +```bash +npx @tanstack/intent list +``` + +### For library maintainers + +Generate skills for your library by telling your AI coding agent to run: + +```bash +npx @tanstack/intent scaffold +``` + +This prints a prompt that walks the agent through domain discovery, skill tree generation, and skill creation — one step at a time with your review at each stage. + +Validate your skill files: + +```bash +npx @tanstack/intent validate +``` + +Check for skills that have fallen behind their sources: + +```bash +npx @tanstack/intent stale +``` + +Copy CI workflow templates into your repo so validation and staleness checks run on every push: + +```bash +npx @tanstack/intent setup +``` + +## Keeping skills current + +The real risk with any derived artifact is staleness. `intent stale` flags skills whose source docs have changed, and CI templates catch drift before it ships. + +The feedback loop runs both directions. `intent feedback` lets users submit structured reports when a skill produces wrong output — which skill, which version, what broke. That context flows back to the maintainer, and the fix ships to everyone on the next `npm update`. + +## CLI Commands + +| Command | Description | +| ----------------------- | --------------------------------------------------- | +| `intent install` | Set up skill-to-task mappings in agent config files | +| `intent list [--json]` | Discover intent-enabled packages | +| `intent meta` | List meta-skills for library maintainers | +| `intent scaffold` | Print the guided skill generation prompt | +| `intent validate [dir]` | Validate SKILL.md files | +| `intent setup` | Copy CI templates, generate shim, create labels | +| `intent stale [--json]` | Check skills for version drift | +| `intent feedback` | Submit skill feedback | + +## License + +[MIT](./LICENSE) diff --git a/packages/intent/meta/domain-discovery/SKILL.md b/packages/intent/meta/domain-discovery/SKILL.md index 35480741..470dfd8f 100644 --- a/packages/intent/meta/domain-discovery/SKILL.md +++ b/packages/intent/meta/domain-discovery/SKILL.md @@ -1,3 +1,899 @@ +<<<<<<< HEAD:packages/intent/meta/domain-discovery/SKILL.md +--- +name: skill-domain-discovery +description: > + Analyze library documentation and source code, then interview maintainers + to discover capability domains and task-focused skills for AI coding + agents. Activate when creating skills for a new library, organizing + existing documentation into skill categories, or when a maintainer wants + help deciding how to structure their library's agent-facing knowledge. + Produces a domain_map.yaml and skill_spec.md that feed directly into + the skill-tree-generator skill. +metadata: + version: '3.0' + category: meta-tooling + output_artifacts: + - skills/_artifacts/domain_map.yaml + - skills/_artifacts/skill_spec.md + skills: + - tree-generator +--- + +# Domain Discovery & Maintainer Interview + +You are extracting domain knowledge for a library to produce a structured +domain map. Your job is not to summarize documentation — it is to build a +deep understanding of the library first, then use that understanding to +surface the implicit knowledge that maintainers carry but docs miss. + +The output is a set of **task-focused skills** — each one matching a +specific developer moment ("implement a proxy", "set up auth", "audit +before launch"). Domains are an intermediate conceptual grouping you use +during analysis; the final skills emerge from the intersection of domains +and developer tasks. + +There are five phases. Always run them in order — unless the lightweight +path applies (see below). + +1. **Quick scan** — orient yourself (autonomous) +2. **High-level interview** — extract the maintainer's task map +3. **Deep read** — fill in failure modes and detail (autonomous) +4. **Detail interview** — gap-targeted questions, AI-agent failures +5. **Finalize artifacts** + +### Lightweight path (small libraries) + +After Phase 1, if the library has **fewer than 5 client-facing skill +areas** (e.g. a focused utility library, a single-purpose tool, or a +library with only 2–3 distinct developer tasks), use a compressed flow: + +1. **Phase 1** — Quick scan (same as full flow) +2. **Phase 2+4 combined** — Single interview round. Combine the + high-level task map questions (Phase 2) with gap-targeted and + AI-agent-specific questions (Phase 4) into one interview session + of 4–8 questions total. Skip the draft-review step since the skill + set is small enough to confirm in one pass. +3. **Phase 3** — Deep read (same as full flow, but scope is smaller) +4. **Phase 5** — Finalize artifacts (same as full flow) + +The lightweight path produces identical output artifacts (domain_map.yaml +and skill_spec.md). It just avoids two separate interview rounds when the +library is small enough that one round covers everything. +### Hard rules — interview phases are mandatory and interactive + +These rules override any other reasoning. No exceptions. + +1. **Phases 2 and 4 are interactive interviews conducted with the + maintainer.** You must ask the questions specified in each sub-section + and wait for the maintainer's response before continuing. Documentation, + source code, and other automated analysis are NOT substitutes for the + maintainer's answers. +2. **Every question in Phases 2 and 4 must be asked as an open-ended + question and sent as a message to the maintainer.** You must then + STOP and WAIT for their reply. Do not answer your own questions. Do + not infer answers from documentation. Do not skip questions because + you believe you already know the answer. +3. **Do not convert open-ended questions into multiple-choice, + yes/no, or confirmation prompts.** The question templates in each + sub-section are open-ended by design. Present them as open-ended + questions. The maintainer's unprompted answers surface knowledge that + pre-structured options suppress. +4. **Minimum question counts are enforced.** Each sub-section specifies + a question count range (e.g. "2–4 questions"). You must ask at least + the minimum number. Asking zero questions in any sub-section is a + protocol violation. +5. **STOP gates are mandatory.** At the boundaries marked `── STOP ──` + below, you must halt execution and wait for the maintainer's response + or acknowledgment before proceeding. Do not continue past a STOP gate + in the same message. +6. **If the maintainer asks to skip an interview phase**, explain the + value of the phase and what will be lost. Proceed with skipping only + if they confirm a second time. +7. **Rich documentation makes interviews MORE valuable, not less.** + When docs are comprehensive, the interview surfaces what docs miss: + implicit knowledge, AI-specific failure modes, undocumented tradeoffs, + and the maintainer's prioritization of what matters most. Never + rationalize skipping interviews because documentation is thorough. + +--- + +## Phase 1 — Quick scan (autonomous, ~10 minutes) + +Orient yourself in the library. You are building a structural map, not +reading exhaustively yet. + +### 1a — Read orientation material + +1. **README** — vocabulary, mental model, what the library does +2. **Getting started / quickstart** — the happy path +3. **Package structure** — if monorepo, identify which packages are + client-facing vs internal. Focus on the 2–3 packages most relevant + to skill consumers (usually client SDKs and primary framework adapters) +4. **AGENTS.md or .cursorrules** — if the library already has agent + guidance, read it. This is high-signal for what the maintainer + considers important + +### 1b — Read peer dependency constraints + +Check `package.json` for `peerDependencies` and `peerDependenciesMeta`. +For each major peer dependency (React, Vue, Svelte, Next.js, etc.): + +1. Note the version range required +2. Read the peer's docs for integration constraints that affect this + library: SSR/hydration rules, component lifecycle boundaries, + browser-only APIs, singleton patterns, connection limits +3. Log framework-specific failure modes — these are the highest-impact + failure modes and cannot be discovered from the library's own source + +Examples of peer-dependency-driven failure modes: + +- SSR: calling browser-only APIs during server render +- React: breaking hook rules in library wrapper components +- Connection limits: opening multiple WebSocket connections per tab +- Singleton patterns: creating multiple client instances in dev mode + +### 1c — Note initial impressions + +Log (but do not group yet): + +- What the library does in one sentence +- The core abstractions a developer interacts with +- Which frameworks it supports +- Any existing skill files, agent configs, or intents +- Whether the library is a monorepo and which packages matter +- Peer dependency constraints — read `peerDependencies` and + `peerDependenciesMeta` from each client-facing package.json to + understand version ranges and optional integrations early + +Present your initial impressions to the maintainer as a brief summary +(3–5 bullets). This orients them on what you found and primes them for +the interview. + +**── STOP ── Do not proceed to Phase 2 until the maintainer has +acknowledged your summary or responded.** + +--- + +## Phase 2 — High-level interview (interactive — requires maintainer) + +The maintainer's mental model of developer tasks IS the skill map. Your +job in this phase is to extract it — not to propose your own structure. + +You must ask the questions below to the maintainer and wait for their +responses. Do not infer answers from documentation or source code. + +### Rules for Phase 2 + +1. One topic per message for open-ended questions. You may batch 2–3 + yes/no or short-confirmation questions together. +2. Ask each question as written (you may adapt phrasing to context, but + keep questions open-ended — never convert to multiple-choice). +3. Wait for the maintainer's response after each question before asking + the next. +4. Take notes silently. Do not summarize back unless asked. +5. If the maintainer gives a short answer, probe deeper before moving on. + +### 2a — Developer tasks (2–4 questions) + +Start with the maintainer's view of what developers do: + +> "Walk me through what a developer actually does with your library — +> not the elevator pitch, but the tasks they come to you for help with, +> from first install through production." + +Follow up to enumerate distinct tasks: + +> "If you listed every distinct thing a developer asks an agent to help +> with using your library, what would that list look like? I'm thinking +> things like 'set up the client', 'implement auth', 'debug sync issues' +> — each one a separate moment where they'd want focused guidance." + +For monorepo libraries, also ask about cross-package tasks: + +> "Are there tasks that touch multiple packages in your monorepo? For +> example, a getting-started flow that requires imports from both the +> client and server packages? I want to make sure skills that span +> package boundaries are captured correctly." + +### 2b — Developer journeys (1–2 questions) + +Surface lifecycle/journey skills that cross-cut task areas: + +> "Are there developer journeys that cut across multiple features? +> For example: a getting-started guide, a go-to-production checklist, +> a migrate-from-v4 walkthrough. Which of these exist in your docs +> or would be valuable as standalone skills?" + +### 2c — Composition and ecosystem (1–2 questions) + +> "Which other libraries does yours compose with most often? Are there +> integration patterns important enough to warrant their own skill — +> for example, using your library with [framework/ORM/router]?" + +### 2d — Confirm initial skill map + +Synthesize what you heard into a proposed skill list and present it: + +> "Based on what you've told me, here's my proposed skill list: +> [enumerate skills with one-line descriptions]. Does this match how +> you think about your library? What would you add, remove, or rename?" + +**── STOP ── Do not proceed to Phase 3 until the maintainer has +reviewed and confirmed (or corrected) the skill list.** + +--- + +## Phase 3 — Deep read (autonomous) + +You now have the maintainer's task map. Read docs and source to fill +each skill area with concrete content — failure modes, code patterns, +gotchas. + +### Reading order + +Read in this order. Each step builds context for the next. + +Before starting, list every file in the docs directory (and subdirectories). +Use this list as a checklist — every narrative file must be read. Do not +sample a subset and extrapolate. + +1. **Every narrative guide** — the how-to content, not API reference tables. + Read every guide file, not a representative sample. +2. **Migration guides** — highest-yield source for failure modes; every + breaking change is exactly what agents trained on older versions produce +3. **API reference** — scan for exports, type signatures, option shapes +4. **Changelog for major versions** — API renames, removed exports, + behavioral changes +5. **GitHub issues and discussions** — scan for frequently reported + confusion, common misunderstandings, recurring questions. Also look + for what users are implicitly arguing for architecturally — not just + "people are confused about X" but "users keep expecting X to work + like Y, which reveals a tension between [design force] and [design force]." + If no web access, check for FAQ.md, TROUBLESHOOTING.md, or docs/faq + as proxies. +6. **Source code** — verify ambiguities from docs, check defaults, find + assertions and invariant checks. For monorepos, read the 2–3 core + packages deeply. For adapter packages, read one representative adapter + deeply, then scan others for deviations from the pattern. + +### What to log + +Produce a flat concept inventory. One item per line. No grouping yet. + +Log every: + +- Named concept, abstraction, or lifecycle stage +- Public export: function, hook, class, type, constant +- Configuration key, its type, and its default value +- Constraint or invariant (especially any enforced by `throw` or assertion) +- Doc callout: any "note", "warning", "caution", "important", "avoid", "do not" +- Dual API: any place the library has two ways to do the same thing (old/new, + verbose/shorthand, lower-level/higher-level) +- Environment branch: any place behavior depends on SSR/CSR, dev/prod, + framework, bundler, or config flag +- Type gap: any type documented as accepting X but source shows X | Y or + rejects a subtype of X +- Source assertion: any `if (!x) throw`, `invariant()`, or `assert()` with + the error message text + +### What to extract from migration guides specifically + +For each breaking change between major versions: + +``` +Old pattern: [code that agents trained on older versions will produce] +New pattern: [current correct code] +What changed: [one sentence — the specific mechanism] +Version boundary: [e.g. "v4 → v5"] +``` + +These become high-priority failure modes. + +### 3a — Group concepts into domains + +Move concept inventory items into groups. Two items belong together when: + +- A developer reasons about them together when solving a problem +- Solving one correctly requires understanding how the other works +- They share a lifecycle, configuration scope, or architectural tradeoff +- Getting one wrong tends to produce bugs in the other + +Let library complexity drive the domain count — a focused library may need +only 2–3 domains, while a large framework may need 7+. Validate by asking: +"Would a developer working on a single feature need to load skills from +multiple domains? If so, merge those domains." These are conceptual +groupings, not the final skills. + +Do not create a group for: + +- A single hook, function, or class +- A single doc or reference page +- "Miscellaneous", "Advanced", or "Other" +- Configuration knobs that only affect another group's behavior + +Name each domain as work being performed, not what the library provides. + +**Validation step:** After grouping, check each domain by asking: +"Would a developer working on a single feature need to load skills from +multiple domains?" If yes, merge those domains. Group by developer tasks +(what they're trying to accomplish), not by architecture (how the library +is organized internally). For example, prefer "writing data" over +"producer lifecycle" — the former matches a developer's intent, the latter +matches the codebase structure. + +### 3b — Map domains × tasks → skills + +Merge your conceptual domains with the maintainer's task list from +Phase 2. Each skill should match a specific developer moment while +carrying the conceptual depth of its parent domain(s). + +A skill is well-shaped when: + +- A developer would ask for it by name ("help me set up sync") +- It covers enough for the agent to complete the task end-to-end +- It doesn't require loading 3 other skills to be useful + +Some domains produce multiple skills (a broad domain like "data access" +might yield "live-queries", "mutations", "offline-sync"). Some tasks +span domains (a "go-live" checklist touches security, performance, and +configuration). Both are fine. + +Also consider: + +- **Lifecycle/journey skills** — if the library's docs include a + quickstart guide, go-to-production checklist, or migration path, + suggest these as standalone skills. Don't force them if the docs + don't have the material. +- **Composition skills** — when peer deps or examples show consistent + co-usage with another library, output a full skill for the + integration, not a footnote on a domain. + +### 3c — Flag subsystems within skills + +Check each skill area for internal diversity. A skill may be +conceptually unified but contain multiple independent subsystems with +distinct config interfaces — for example, 5 sync adapters that all +solve "connectivity" but each with unique setup, options, and failure +modes. + +For each skill, ask: "Does this cover 3+ backends, adapters, drivers, +or providers with distinct configuration surfaces?" If yes, list them +as `subsystems`. These tell the skill-tree-generator to produce +per-subsystem reference files. + +Also flag dense API surfaces — if a topic has >10 distinct operators, +option shapes, or patterns (e.g. query operators, schema validation +rules), note it as a `reference_candidates` entry. + +### 3d — Extract failure modes + +For each skill, extract failure modes that pass all three tests: + +- **Plausible** — An agent would generate this because it looks correct + based on the library's design, a similar API, or an older version +- **Silent** — No immediate crash; fails at runtime or under specific conditions +- **Grounded** — Traceable to a specific doc page, source location, or issue + +**Where to find them:** + +| Source | What to extract | +| -------------------- | ------------------------------------------------------------------ | +| Migration guides | Every breaking change → old pattern is the wrong code | +| Doc callouts | Any "note", "warning", "avoid" with surrounding context | +| Source assertions | `throw` and `invariant()` messages describe the failure | +| Default values | Undocumented or surprising defaults that cause wrong behavior | +| Type precision | Source type more restrictive than docs imply | +| Environment branches | `typeof window`, SSR flags, `NODE_ENV` — behavior differs silently | + +Target 3 failure modes per skill minimum. Complex skills target 5–6. + +**Code patterns.** Every failure mode should include `wrong_pattern` and +`correct_pattern` fields with short code snippets (3–10 lines each). +The wrong pattern is what an agent would generate; the correct pattern +is the fix. These feed directly into SKILL.md Common Mistakes sections +as wrong/correct code pairs. If the failure mode is purely conceptual +(e.g. an architectural choice) rather than a code pattern, omit both +fields and explain in `mechanism` instead. + +**Cross-skill failure modes.** Some failure modes belong to multiple +skills. A developer doing SSR work and a developer doing state management +both need to know about "stale state during hydration" — they load +different skills but need the same advice. When a failure mode spans +skills, list all relevant skill slugs in its `skills` field. The +skill-tree-generator will write it into every corresponding SKILL file. + +List a cross-skill failure mode once, under its primary skill. Set +the `skills` field to all skill slugs it applies to. Do not duplicate +the entry in the YAML — the skill-tree-generator handles duplication +into multiple SKILL files at generation time. + +### 3e — Identify cross-skill tensions + +Look for places where design forces between skills conflict. A tension +is not a failure mode — it's a structural pull where optimizing for one +task makes another harder. Examples: + +- "Getting-started simplicity conflicts with production operational safety" +- "Type-safety strictness conflicts with rapid prototyping flexibility" +- "SSR correctness requires patterns that hurt client-side performance" + +Tensions are where agents fail most because they optimize for one task +without seeing the tradeoff. Each tension should name the skills in +conflict, describe the pull, and state what an agent gets wrong when it +only considers one side. + +Target 2–4 tensions. If you find none, the skills may be too isolated — +revisit whether you're missing cross-connections. + +### 3f — Map cross-references + +Beyond tensions (conflicts) and shared failure modes, identify skills +that illuminate each other without conflicting. A cross-reference means: +"an agent loading skill A would produce better code if it knew about +skill B." These become "See also" pointers in the generated SKILL.md +files. + +For each pair, note: + +- Which skill references which (can be bidirectional) +- Why awareness of the other skill improves output + +Examples: + +- A quickstart skill references the security checklist ("after setup, audit") +- A state management skill references an SSR skill ("state hydration + requires understanding SSR lifecycle") +- A data writing skill references a data reading skill ("writes affect + how queries invalidate") + +Output these in the `cross_references` section of domain_map.yaml. + +### 3g — Identify gaps + +For each skill, explicitly list what you could NOT determine from docs +and source alone. These become interview questions in Phase 4. + +Common gaps: + +- "Docs describe X but don't explain when you'd choose X over Y" +- "Migration guide mentions this changed but doesn't say what the old + behavior was" +- "Source has an assertion here but no doc explains what triggers it" +- "GitHub issues show confusion about X but docs don't address it" +- "I found two patterns for doing X — unclear which is current/preferred" + +### 3h — Discover composition targets + +Scan `package.json` for peer dependencies, optional dependencies, and +`peerDependenciesMeta`. Scan example directories and integration tests +for import patterns. For each frequently co-used library, log: + +- Library name and which features interact +- Whether it's a required or optional integration +- Any example code showing the integration pattern + +These become targeted composition questions in Phase 4e. + +### 3i — Produce the draft + +Write the full `domain_map.yaml` (format in Output Artifacts below) with +a `status: draft` field. Flag every gap in the `gaps` section. + +Present the draft to the maintainer before starting Phase 4: + +> "I've read the docs and source for [library] and produced a draft with +> [N] skills and [M] failure modes. I've flagged [K] specific gaps where +> I need your input." + +Include the full draft domain_map.yaml in your message so the maintainer +can review it. Also include a checklist of all docs files you read. + +**── STOP ── Do not proceed to Phase 4 until the maintainer has +reviewed the draft and responded. Their feedback on the draft informs +the detail interview questions.** + +--- + +## Phase 4 — Detail interview (interactive — requires maintainer) + +You have the maintainer's task map and a deep read. The interview now +fills gaps, validates your understanding, and surfaces implicit knowledge. + +You must ask the questions below to the maintainer and wait for their +responses. Do not infer answers from documentation or source code — +even for gaps you think you can answer from your reading. + +### Rules for Phase 4 + +1. One topic per message for open-ended questions. You may batch 2–3 + yes/no or short-confirmation questions together. +2. Ask each question as written (you may adapt phrasing to context, but + keep questions open-ended — never convert to multiple-choice). +3. Each question must reference something specific from your reading. +4. Wait for the maintainer's response after each question before asking + the next. +5. If the maintainer gives a short answer, probe deeper before moving on. +6. Take notes silently. Do not summarize back unless asked. + +### 4a — Draft review (2–3 questions) + +Start by confirming or correcting your skill list and failure modes: + +> "Here's the skill list I've built from our earlier conversation plus +> the deep read: [list skills with brief descriptions]. Does this still +> match your thinking? Anything to add, remove, or rename?" + +Follow up on any corrections. Then: + +> "I identified [M] failure modes from the docs and migration guides. Are +> there important ones I missed — especially patterns that look correct +> but fail silently?" + +### 4b — Gap-targeted questions (3–8 questions) + +For each gap flagged in Phase 3g, ask a specific question. These are not +generic — they reference what you found: + +**Instead of:** "What do developers get wrong?" +**Ask:** "I noticed the migration guide from v4 to v5 changed how [X] works, +but the docs don't show the old pattern. Do agents still commonly generate +the v4 pattern? What does it look like?" + +**Instead of:** "Are there surprising interactions?" +**Ask:** "The source throws an invariant error if [X] is called before [Y], +but the docs don't mention ordering. How often do developers hit this?" + +**Instead of:** "What's different in SSR vs client?" +**Ask:** "I found a `typeof window` check in [file] that changes behavior +for [feature]. What goes wrong when developers test only in the browser +and deploy with SSR?" + +Adapt from this bank of gap-targeted question templates: + +- "I found two patterns for [X] in the docs — [pattern A] and [pattern B]. + Which is current, and does the old one still work?" +- "The source defaults [config option] to [value], which seems surprising + for [reason]. Is this intentional? Do developers need to override it?" +- "GitHub issues show [N] reports of confusion about [X]. What's the + underlying misunderstanding?" +- "I couldn't find docs for how [feature A] interacts with [feature B]. + What should an agent know about using them together?" +- "The API reference shows [type signature], but the guide examples use + a different shape. Which is accurate?" + +### 4c — AI-agent-specific failure modes (2–4 questions) + +These target mistakes that AI coding agents make but human developers +typically don't. Agent-specific failures are often the highest-value +findings — in testing, maintainer answers to these questions produced +the most critical failure modes. + +- "What mistakes would an AI coding agent make that a human developer + wouldn't? Think about: hallucinating APIs that don't exist, defaulting + to language primitives instead of library abstractions, choosing the + wrong adapter or integration path." +- "When an agent generates code using your library, what's the first + thing you'd check? What pattern would make you immediately say + 'an AI wrote this'?" +- "Are there parts of your API where the naming or design is misleading + enough that an agent with no prior context would pick the wrong + approach? What would it pick, and what should it pick instead?" +- "Are there features where the docs are comprehensive for human + developers but would still mislead an agent? For example, features + that require understanding unstated context, or where the 'obvious' + approach from reading the API surface is wrong." + +### 4d — Implicit knowledge extraction (3–5 questions) + +These surface knowledge that doesn't appear in any docs: + +- "What does a senior developer using your library know that a mid-level + developer doesn't — something that isn't written down anywhere?" +- "Are there patterns that work fine for prototyping but are dangerous + in production? What makes them dangerous?" +- "What question do you answer most often in Discord or GitHub issues + that the docs technically cover but people still miss?" +- "Is there anything you'd change about the API design if you could break + backwards compatibility? What's the current workaround?" + +### 4e — Composition questions (if library interacts with others) + +Use what you discovered in Phase 3h. For each integration target +identified from peer dependencies and example code, ask targeted +questions: + +- "I see [library] is a peer dependency and [N] examples import it + alongside yours. What's the most common integration mistake?" +- "When developers use [your library] with [other library], are there + patterns that only matter when both are present?" +- "I found [specific integration pattern] in the examples. Is this the + recommended approach, or is there a better way that isn't documented?" + +--- + +## Phase 5 — Finalize artifacts + +Merge interview findings into the draft. For each interview answer: + +1. If it confirms a skill or failure mode — no action needed +2. If it corrects something — update the map +3. If it adds a new failure mode — add it with source "maintainer interview" +4. If it reveals a new skill — add it +5. If it fills a gap — remove from gaps section + +Update `status: draft` to `status: reviewed`. + +--- + +## Output artifacts + +If the maintainer uses a custom skills root, replace `skills/` in the paths +below with their chosen directory. + +**Monorepo layout:** For monorepos, domain map artifacts go at the REPO ROOT +(e.g. `_artifacts/domain_map.yaml`) since they describe the whole library. +Skills are generated per-package later by the tree-generator and generate-skill +steps. + +### 1. skills/\_artifacts/domain_map.yaml + +```yaml +# domain_map.yaml +# Generated by skill-domain-discovery +# Library: [name] +# Version: [version this map targets] +# Date: [ISO date] +# Status: [draft | reviewed] + +library: + name: '[package-name]' + version: '[version]' + repository: '[repo URL]' + description: '[one line]' + primary_framework: '[React | Vue | Svelte | framework-agnostic]' + +domains: + - name: '[work-oriented domain name]' + slug: '[kebab-case]' + description: '[conceptual grouping — what a developer is reasoning about]' + +skills: + - name: '[task-focused skill name]' + slug: '[kebab-case]' + domain: '[parent domain slug]' + description: '[what a developer is doing — matches a specific task/moment]' + type: '[core | framework | lifecycle | composition]' + packages: # required for monorepo; omit for single-package libraries + - '[primary package name]' + - '[secondary package name, if skill spans multiple packages]' + covers: + - '[API/hook/concept 1]' + - '[API/hook/concept 2]' + tasks: + - '[example task 1]' + - '[example task 2]' + - '[example task 3]' + subsystems: # omit if skill has no independent subsystems + - name: '[adapter/backend name]' + package: '[npm package if separate]' + config_surface: '[brief description of unique config]' + reference_candidates: # omit if no dense API surfaces + - topic: '[e.g. query operators, schema validation]' + reason: '[e.g. >10 distinct operators with signatures]' + failure_modes: + - mistake: '[5-10 word phrase]' + mechanism: '[one sentence]' + wrong_pattern: | # the code an agent would incorrectly generate + [short code snippet showing the mistake] + correct_pattern: | # the code that should be generated instead + [short code snippet showing the fix] + source: '[doc page, source file, issue link, or maintainer interview]' + priority: '[CRITICAL | HIGH | MEDIUM]' + status: '[active | fixed-but-legacy-risk | removed]' + version_context: "[e.g. 'Fixed in v5.2 but agents trained on older code still generate this']" + skills: ['[this-skill-slug]'] # list all skills this belongs to; omit if single-skill + compositions: + - library: '[other library name]' + skill: '[composition skill name if applicable]' + +tensions: + - name: '[short phrase describing the pull]' + skills: ['[skill-slug-a]', '[skill-slug-b]'] + description: '[what conflicts — one sentence]' + implication: '[what an agent gets wrong when it only considers one side]' + +cross_references: + - from: '[skill-slug]' + to: '[skill-slug]' + reason: '[why loading one skill benefits from awareness of the other]' + +gaps: + - skill: '[skill slug]' + question: '[what still needs input]' + context: '[why this matters]' + status: '[open | resolved]' +``` + +### 2. skills/\_artifacts/skill_spec.md + +A human-readable companion document. Follow this structure: + +```markdown +# [Library Name] — Skill Spec + +[2–3 sentences: what this library is, what problem it solves. Factual, +not promotional.] + +## Domains + +| Domain | Description | Skills | +| ------ | --------------------- | ----------------------- | +| [name] | [conceptual grouping] | [skill-1, skill-2, ...] | + +## Skill Inventory + +| Skill | Type | Domain | What it covers | Failure modes | +| ------ | -------------------------------------- | -------- | -------------- | ------------- | +| [name] | [core/framework/lifecycle/composition] | [domain] | [list] | [count] | + +## Failure Mode Inventory + +### [Skill name] ([count] failure modes) + +| # | Mistake | Priority | Source | Cross-skill? | +| --- | -------- | -------- | ---------------------- | ------------------------ | +| 1 | [phrase] | CRITICAL | [doc/source/interview] | [other skill slugs or —] | + +[Repeat table for each skill.] + +## Tensions + +| Tension | Skills | Agent implication | +| -------------- | ------------------- | ----------------------- | +| [short phrase] | [slug-a] ↔ [slug-b] | [what agents get wrong] | + +## Cross-References + +| From | To | Reason | +| ------ | ------ | ----------------------------------------- | +| [slug] | [slug] | [why awareness of one improves the other] | + +## Subsystems & Reference Candidates + +| Skill | Subsystems | Reference candidates | +| ------ | ------------------------------ | -------------------------- | +| [slug] | [adapter1, adapter2, ...] or — | [topic needing depth] or — | + +## Remaining Gaps + +| Skill | Question | Status | +| ------ | ------------------------ | ------ | +| [slug] | [what still needs input] | open | + +[Omit this section if all gaps were resolved in the interview.] + +## Recommended Skill File Structure + +- **Core skills:** [list which skills are framework-agnostic] +- **Framework skills:** [list per-framework skills needed] +- **Lifecycle skills:** [list journey/lifecycle skills if applicable] +- **Composition skills:** [list integration seams needing composition skills] +- **Reference files:** [list skills needing references/ based on subsystems + or dense API surfaces] + +## Composition Opportunities + +| Library | Integration points | Composition skill needed? | +| ------- | ------------------ | ----------------------------- | +| [name] | [what interacts] | [yes/no — if yes, skill name] | +``` + +--- + +## Constraints + +| Check | Rule | +| ------------------------------------- | -------------------------------------------------------------------------- | +| Quick scan before interview | Never interview without at least reading README and package structure | +| High-level interview before deep read | The maintainer's task map informs what you read deeply | +| **Interview phases are interactive** | Phases 2 and 4 require sending questions to the maintainer and waiting | +| **Docs are not a substitute** | Documentation cannot replace maintainer answers — even comprehensive docs | +| **Open-ended questions stay open** | Never convert interview questions to multiple-choice or yes/no | +| **Minimum question counts enforced** | Each sub-section's minimum count must be met; zero questions = violation | +| **STOP gates are mandatory** | Do not proceed past a STOP gate without maintainer response | +| Batch only confirmations | Yes/no questions may batch 2–3; open-ended questions get their own message | +| Questions reference findings | No generic questions — cite what you found | +| Skills are task-focused | Each skill matches a developer moment, not a conceptual area | +| 3+ failure modes per skill | Complex skills target 5–6 | +| Every failure mode sourced | Doc page, source file, issue link, or maintainer interview | +| Gaps are explicit | Unknown areas flagged, not guessed | +| No marketing prose | Library description is factual, not promotional | +| domain_map.yaml is valid YAML | Parseable by any YAML parser | +| Draft before detail interview | Present draft for review before Phase 4 | +| **Draft reviewed before Phase 4** | Maintainer must acknowledge or respond to draft before detail interview | +| Agent-specific failures probed | Always ask AI-agent-specific questions in Phase 4c | +| Compositions discovered from code | Scan peer deps and examples before asking composition questions | +| Cross-skill failure modes tagged | Failure modes spanning skills list all relevant slugs | +| Tensions identified | 2–4 cross-skill tensions; if none found, revisit skill boundaries | +| Subsystems flagged | Skills with 3+ adapters/backends list them as subsystems | +| Dense surfaces flagged | Topics with >10 patterns noted as reference_candidates | +| Lifecycle skills considered | Suggest journey skills when docs have the material | +| Cross-references mapped | Skills that illuminate each other get "See also" pointers | +| **All docs files read** | List docs directory contents and read every narrative file — no sampling | + +--- + +## Cross-model compatibility notes + +This skill is designed to produce consistent results across Claude, GPT-4+, +Gemini, and open-source models. To achieve this: + +- All instructions use imperative sentences, not suggestions +- Interview phases use explicit STOP gates to prevent models from + continuing autonomously past interactive checkpoints +- Hard rules at the top override any model tendency to rationalize + skipping interactive phases when documentation is available +- Open-ended questions are explicitly protected from conversion to + multiple-choice or confirmation prompts, which models default to + when they have enough context to pre-populate answers +- Output formats use YAML (universally parsed) and Markdown tables + (universally rendered) +- Examples use concrete values, not placeholders like "[your value here]" +- Section boundaries use Markdown headers (##) for navigation and --- for + phase separation +- No model-specific features (no XML tags in output, no tool_use assumptions) + +--- + +## Meta-skill feedback (mandatory — do not skip) + +**This step is required.** Agents routinely skip feedback collection +because it appears at the end of the skill. You must complete this step +before the domain discovery process is considered finished. + +After finalizing artifacts, ask the maintainer for feedback on the domain +discovery process. Do not silently create the feedback template — present +it to the maintainer and ask them to fill in the Domain Discovery section. + +**── STOP ── Ask the maintainer to provide feedback. Wait for their +response before writing the feedback file.** + +Create or update a single Markdown feedback draft +for all three meta skills used in scaffolding. Use this exact template and +fill only the **Domain Discovery** section now. Leave the other sections in +place for later steps to complete. + +``` +# Intent Meta Skill Feedback + +## Domain Discovery +- What worked well: +- What was confusing or missing: +- Suggestions for improvement: +- Overall rating: good | mixed | bad + +## Tree Generator +- What worked well: +- What was confusing or missing: +- Suggestions for improvement: +- Overall rating: good | mixed | bad + +## Generate Skill +- What worked well: +- What was confusing or missing: +- Suggestions for improvement: +- Overall rating: good | mixed | bad + +## Context (optional) +- Library: +- Repo: +- Docs: +- Notes: +``` + +Do not submit feedback yet. Tell the maintainer to carry this draft forward +to the next meta skill step. +======= --- name: skill-domain-discovery description: > @@ -31,8 +927,7 @@ before launch"). Domains are an intermediate conceptual grouping you use during analysis; the final skills emerge from the intersection of domains and developer tasks. -There are five phases. Always run them in order — unless the lightweight -path applies (see below). +There are five phases. Always run them in order. 1. **Quick scan** — orient yourself (autonomous) 2. **High-level interview** — extract the maintainer's task map @@ -40,24 +935,41 @@ path applies (see below). 4. **Detail interview** — gap-targeted questions, AI-agent failures 5. **Finalize artifacts** -### Lightweight path (small libraries) - -After Phase 1, if the library has **fewer than 5 client-facing skill -areas** (e.g. a focused utility library, a single-purpose tool, or a -library with only 2–3 distinct developer tasks), use a compressed flow: - -1. **Phase 1** — Quick scan (same as full flow) -2. **Phase 2+4 combined** — Single interview round. Combine the - high-level task map questions (Phase 2) with gap-targeted and - AI-agent-specific questions (Phase 4) into one interview session - of 4–8 questions total. Skip the draft-review step since the skill - set is small enough to confirm in one pass. -3. **Phase 3** — Deep read (same as full flow, but scope is smaller) -4. **Phase 5** — Finalize artifacts (same as full flow) - -The lightweight path produces identical output artifacts (domain_map.yaml -and skill_spec.md). It just avoids two separate interview rounds when the -library is small enough that one round covers everything. +### Hard rules — interview phases are mandatory and interactive + +These rules override any other reasoning. No exceptions. + +1. **Phases 2 and 4 are interactive interviews conducted with the + maintainer.** You must ask the questions specified in each sub-section + and wait for the maintainer's response before continuing. Documentation, + source code, and other automated analysis are NOT substitutes for the + maintainer's answers. +2. **Every question in Phases 2 and 4 must be asked as an open-ended + question and sent as a message to the maintainer.** You must then + STOP and WAIT for their reply. Do not answer your own questions. Do + not infer answers from documentation. Do not skip questions because + you believe you already know the answer. +3. **Do not convert open-ended questions into multiple-choice, + yes/no, or confirmation prompts.** The question templates in each + sub-section are open-ended by design. Present them as open-ended + questions. The maintainer's unprompted answers surface knowledge that + pre-structured options suppress. +4. **Minimum question counts are enforced.** Each sub-section specifies + a question count range (e.g. "2–4 questions"). You must ask at least + the minimum number. Asking zero questions in any sub-section is a + protocol violation. +5. **STOP gates are mandatory.** At the boundaries marked `── STOP ──` + below, you must halt execution and wait for the maintainer's response + or acknowledgment before proceeding. Do not continue past a STOP gate + in the same message. +6. **If the maintainer asks to skip an interview phase**, explain the + value of the phase and what will be lost. Proceed with skipping only + if they confirm a second time. +7. **Rich documentation makes interviews MORE valuable, not less.** + When docs are comprehensive, the interview surfaces what docs miss: + implicit knowledge, AI-specific failure modes, undocumented tradeoffs, + and the maintainer's prioritization of what matters most. Never + rationalize skipping interviews because documentation is thorough. --- @@ -77,48 +989,46 @@ reading exhaustively yet. guidance, read it. This is high-signal for what the maintainer considers important -### 1b — Read peer dependency constraints - -Check `package.json` for `peerDependencies` and `peerDependenciesMeta`. -For each major peer dependency (React, Vue, Svelte, Next.js, etc.): - -1. Note the version range required -2. Read the peer's docs for integration constraints that affect this - library: SSR/hydration rules, component lifecycle boundaries, - browser-only APIs, singleton patterns, connection limits -3. Log framework-specific failure modes — these are the highest-impact - failure modes and cannot be discovered from the library's own source - -Examples of peer-dependency-driven failure modes: - -- SSR: calling browser-only APIs during server render -- React: breaking hook rules in library wrapper components -- Connection limits: opening multiple WebSocket connections per tab -- Singleton patterns: creating multiple client instances in dev mode - -### 1c — Note initial impressions +### 1b — Note initial impressions Log (but do not group yet): - What the library does in one sentence - The core abstractions a developer interacts with - Which frameworks it supports -- Any existing skill files, agent configs, or intents +- Any existing skill files, agent configs, or playbooks - Whether the library is a monorepo and which packages matter +- Peer dependency constraints — read `peerDependencies` and + `peerDependenciesMeta` from each client-facing package.json to + understand version ranges and optional integrations early + +Present your initial impressions to the maintainer as a brief summary +(3–5 bullets). This orients them on what you found and primes them for +the interview. + +**── STOP ── Do not proceed to Phase 2 until the maintainer has +acknowledged your summary or responded.** --- -## Phase 2 — High-level interview +## Phase 2 — High-level interview (interactive — requires maintainer) The maintainer's mental model of developer tasks IS the skill map. Your job in this phase is to extract it — not to propose your own structure. +You must ask the questions below to the maintainer and wait for their +responses. Do not infer answers from documentation or source code. + ### Rules for Phase 2 1. One topic per message for open-ended questions. You may batch 2–3 yes/no or short-confirmation questions together. -2. Take notes silently. Do not summarize back unless asked. -3. If the maintainer gives a short answer, probe deeper before moving on. +2. Ask each question as written (you may adapt phrasing to context, but + keep questions open-ended — never convert to multiple-choice). +3. Wait for the maintainer's response after each question before asking + the next. +4. Take notes silently. Do not summarize back unless asked. +5. If the maintainer gives a short answer, probe deeper before moving on. ### 2a — Developer tasks (2–4 questions) @@ -135,6 +1045,14 @@ Follow up to enumerate distinct tasks: > things like 'set up the client', 'implement auth', 'debug sync issues' > — each one a separate moment where they'd want focused guidance." +For monorepo libraries, also ask about cross-package tasks: + +> "Are there tasks that touch multiple packages in your monorepo? For +> example, a getting-started flow that requires imports from both the +> client and server packages? Since skills ship inside each package, +> I need to know which package should own cross-cutting skills and +> which other packages they reference." + ### 2b — Developer journeys (1–2 questions) Surface lifecycle/journey skills that cross-cut task areas: @@ -158,6 +1076,9 @@ Synthesize what you heard into a proposed skill list and present it: > [enumerate skills with one-line descriptions]. Does this match how > you think about your library? What would you add, remove, or rename?" +**── STOP ── Do not proceed to Phase 3 until the maintainer has +reviewed and confirmed (or corrected) the skill list.** + --- ## Phase 3 — Deep read (autonomous) @@ -170,7 +1091,12 @@ gotchas. Read in this order. Each step builds context for the next. -1. **Every narrative guide** — the how-to content, not API reference tables +Before starting, list every file in the docs directory (and subdirectories). +Use this list as a checklist — every narrative file must be read. Do not +sample a subset and extrapolate. + +1. **Every narrative guide** — the how-to content, not API reference tables. + Read every guide file, not a representative sample. 2. **Migration guides** — highest-yield source for failure modes; every breaking change is exactly what agents trained on older versions produce 3. **API reference** — scan for exports, type signatures, option shapes @@ -230,11 +1156,7 @@ Move concept inventory items into groups. Two items belong together when: - They share a lifecycle, configuration scope, or architectural tradeoff - Getting one wrong tends to produce bugs in the other -Let library complexity drive the domain count — a focused library may need -only 2–3 domains, while a large framework may need 7+. Validate by asking: -"Would a developer working on a single feature need to load skills from -multiple domains? If so, merge those domains." These are conceptual -groupings, not the final skills. +Target 4–7 domains. These are conceptual groupings, not the final skills. Do not create a group for: @@ -245,14 +1167,6 @@ Do not create a group for: Name each domain as work being performed, not what the library provides. -**Validation step:** After grouping, check each domain by asking: -"Would a developer working on a single feature need to load skills from -multiple domains?" If yes, merge those domains. Group by developer tasks -(what they're trying to accomplish), not by architecture (how the library -is organized internally). For example, prefer "writing data" over -"producer lifecycle" — the former matches a developer's intent, the latter -matches the codebase structure. - ### 3b — Map domains × tasks → skills Merge your conceptual domains with the maintainer's task list from @@ -319,14 +1233,6 @@ For each skill, extract failure modes that pass all three tests: Target 3 failure modes per skill minimum. Complex skills target 5–6. -**Code patterns.** Every failure mode should include `wrong_pattern` and -`correct_pattern` fields with short code snippets (3–10 lines each). -The wrong pattern is what an agent would generate; the correct pattern -is the fix. These feed directly into SKILL.md Common Mistakes sections -as wrong/correct code pairs. If the failure mode is purely conceptual -(e.g. an architectural choice) rather than a code pattern, omit both -fields and explain in `mechanism` instead. - **Cross-skill failure modes.** Some failure modes belong to multiple skills. A developer doing SSR work and a developer doing state management both need to know about "stale state during hydration" — they load @@ -357,30 +1263,7 @@ only considers one side. Target 2–4 tensions. If you find none, the skills may be too isolated — revisit whether you're missing cross-connections. -### 3f — Map cross-references - -Beyond tensions (conflicts) and shared failure modes, identify skills -that illuminate each other without conflicting. A cross-reference means: -"an agent loading skill A would produce better code if it knew about -skill B." These become "See also" pointers in the generated SKILL.md -files. - -For each pair, note: - -- Which skill references which (can be bidirectional) -- Why awareness of the other skill improves output - -Examples: - -- A quickstart skill references the security checklist ("after setup, audit") -- A state management skill references an SSR skill ("state hydration - requires understanding SSR lifecycle") -- A data writing skill references a data reading skill ("writes affect - how queries invalidate") - -Output these in the `cross_references` section of domain_map.yaml. - -### 3g — Identify gaps +### 3f — Identify gaps For each skill, explicitly list what you could NOT determine from docs and source alone. These become interview questions in Phase 4. @@ -394,7 +1277,7 @@ Common gaps: - "GitHub issues show confusion about X but docs don't address it" - "I found two patterns for doing X — unclear which is current/preferred" -### 3h — Discover composition targets +### 3g — Discover composition targets Scan `package.json` for peer dependencies, optional dependencies, and `peerDependenciesMeta`. Scan example directories and integration tests @@ -406,7 +1289,7 @@ for import patterns. For each frequently co-used library, log: These become targeted composition questions in Phase 4e. -### 3i — Produce the draft +### 3h — Produce the draft Write the full `domain_map.yaml` (format in Output Artifacts below) with a `status: draft` field. Flag every gap in the `gaps` section. @@ -417,20 +1300,35 @@ Present the draft to the maintainer before starting Phase 4: > [N] skills and [M] failure modes. I've flagged [K] specific gaps where > I need your input." +Include the full draft domain_map.yaml in your message so the maintainer +can review it. Also include a checklist of all docs files you read. + +**── STOP ── Do not proceed to Phase 4 until the maintainer has +reviewed the draft and responded. Their feedback on the draft informs +the detail interview questions.** + --- -## Phase 4 — Detail interview (builds on Phase 1–3) +## Phase 4 — Detail interview (interactive — requires maintainer) You have the maintainer's task map and a deep read. The interview now fills gaps, validates your understanding, and surfaces implicit knowledge. +You must ask the questions below to the maintainer and wait for their +responses. Do not infer answers from documentation or source code — +even for gaps you think you can answer from your reading. + ### Rules for Phase 4 1. One topic per message for open-ended questions. You may batch 2–3 yes/no or short-confirmation questions together. -2. Each question must reference something specific from your reading. -3. If the maintainer gives a short answer, probe deeper before moving on. -4. Take notes silently. Do not summarize back unless asked. +2. Ask each question as written (you may adapt phrasing to context, but + keep questions open-ended — never convert to multiple-choice). +3. Each question must reference something specific from your reading. +4. Wait for the maintainer's response after each question before asking + the next. +5. If the maintainer gives a short answer, probe deeper before moving on. +6. Take notes silently. Do not summarize back unless asked. ### 4a — Draft review (2–3 questions) @@ -448,7 +1346,7 @@ Follow up on any corrections. Then: ### 4b — Gap-targeted questions (3–8 questions) -For each gap flagged in Phase 3g, ask a specific question. These are not +For each gap flagged in Phase 3f, ask a specific question. These are not generic — they reference what you found: **Instead of:** "What do developers get wrong?" @@ -515,7 +1413,7 @@ These surface knowledge that doesn't appear in any docs: ### 4e — Composition questions (if library interacts with others) -Use what you discovered in Phase 3h. For each integration target +Use what you discovered in Phase 3g. For each integration target identified from peer dependencies and example code, ask targeted questions: @@ -547,11 +1445,6 @@ Update `status: draft` to `status: reviewed`. If the maintainer uses a custom skills root, replace `skills/` in the paths below with their chosen directory. -**Monorepo layout:** For monorepos, domain map artifacts go at the REPO ROOT -(e.g. `_artifacts/domain_map.yaml`) since they describe the whole library. -Skills are generated per-package later by the tree-generator and generate-skill -steps. - ### 1. skills/\_artifacts/domain_map.yaml ```yaml @@ -580,6 +1473,9 @@ skills: domain: '[parent domain slug]' description: '[what a developer is doing — matches a specific task/moment]' type: '[core | framework | lifecycle | composition]' + packages: # required for monorepo; omit for single-package libraries + - '[package where this skill ships]' + - '[additional package, if skill is relevant to multiple packages]' covers: - '[API/hook/concept 1]' - '[API/hook/concept 2]' @@ -597,10 +1493,6 @@ skills: failure_modes: - mistake: '[5-10 word phrase]' mechanism: '[one sentence]' - wrong_pattern: | # the code an agent would incorrectly generate - [short code snippet showing the mistake] - correct_pattern: | # the code that should be generated instead - [short code snippet showing the fix] source: '[doc page, source file, issue link, or maintainer interview]' priority: '[CRITICAL | HIGH | MEDIUM]' status: '[active | fixed-but-legacy-risk | removed]' @@ -616,11 +1508,6 @@ tensions: description: '[what conflicts — one sentence]' implication: '[what an agent gets wrong when it only considers one side]' -cross_references: - - from: '[skill-slug]' - to: '[skill-slug]' - reason: '[why loading one skill benefits from awareness of the other]' - gaps: - skill: '[skill slug]' question: '[what still needs input]' @@ -666,12 +1553,6 @@ not promotional.] | -------------- | ------------------- | ----------------------- | | [short phrase] | [slug-a] ↔ [slug-b] | [what agents get wrong] | -## Cross-References - -| From | To | Reason | -| ------ | ------ | ----------------------------------------- | -| [slug] | [slug] | [why awareness of one improves the other] | - ## Subsystems & Reference Candidates | Skill | Subsystems | Reference candidates | @@ -710,6 +1591,11 @@ not promotional.] | ------------------------------------- | -------------------------------------------------------------------------- | | Quick scan before interview | Never interview without at least reading README and package structure | | High-level interview before deep read | The maintainer's task map informs what you read deeply | +| **Interview phases are interactive** | Phases 2 and 4 require sending questions to the maintainer and waiting | +| **Docs are not a substitute** | Documentation cannot replace maintainer answers — even comprehensive docs | +| **Open-ended questions stay open** | Never convert interview questions to multiple-choice or yes/no | +| **Minimum question counts enforced** | Each sub-section's minimum count must be met; zero questions = violation | +| **STOP gates are mandatory** | Do not proceed past a STOP gate without maintainer response | | Batch only confirmations | Yes/no questions may batch 2–3; open-ended questions get their own message | | Questions reference findings | No generic questions — cite what you found | | Skills are task-focused | Each skill matches a developer moment, not a conceptual area | @@ -719,6 +1605,7 @@ not promotional.] | No marketing prose | Library description is factual, not promotional | | domain_map.yaml is valid YAML | Parseable by any YAML parser | | Draft before detail interview | Present draft for review before Phase 4 | +| **Draft reviewed before Phase 4** | Maintainer must acknowledge or respond to draft before detail interview | | Agent-specific failures probed | Always ask AI-agent-specific questions in Phase 4c | | Compositions discovered from code | Scan peer deps and examples before asking composition questions | | Cross-skill failure modes tagged | Failure modes spanning skills list all relevant slugs | @@ -726,7 +1613,7 @@ not promotional.] | Subsystems flagged | Skills with 3+ adapters/backends list them as subsystems | | Dense surfaces flagged | Topics with >10 patterns noted as reference_candidates | | Lifecycle skills considered | Suggest journey skills when docs have the material | -| Cross-references mapped | Skills that illuminate each other get "See also" pointers | +| **All docs files read** | List docs directory contents and read every narrative file — no sampling | --- @@ -736,6 +1623,13 @@ This skill is designed to produce consistent results across Claude, GPT-4+, Gemini, and open-source models. To achieve this: - All instructions use imperative sentences, not suggestions +- Interview phases use explicit STOP gates to prevent models from + continuing autonomously past interactive checkpoints +- Hard rules at the top override any model tendency to rationalize + skipping interactive phases when documentation is available +- Open-ended questions are explicitly protected from conversion to + multiple-choice or confirmation prompts, which models default to + when they have enough context to pre-populate answers - Output formats use YAML (universally parsed) and Markdown tables (universally rendered) - Examples use concrete values, not placeholders like "[your value here]" @@ -745,15 +1639,26 @@ Gemini, and open-source models. To achieve this: --- -## Meta-skill feedback (alpha default) +## Meta-skill feedback (mandatory — do not skip) + +**This step is required.** Agents routinely skip feedback collection +because it appears at the end of the skill. You must complete this step +before the domain discovery process is considered finished. + +After finalizing artifacts, ask the maintainer for feedback on the domain +discovery process. Do not silently create the feedback template — present +it to the maintainer and ask them to fill in the Domain Discovery section. + +**── STOP ── Ask the maintainer to provide feedback. Wait for their +response before writing the feedback file.** -After finalizing artifacts, create or update a single Markdown feedback draft +Create or update a single Markdown feedback draft for all three meta skills used in scaffolding. Use this exact template and fill only the **Domain Discovery** section now. Leave the other sections in place for later steps to complete. ``` -# Intent Meta Skill Feedback +# Playbook Meta Skill Feedback ## Domain Discovery - What worked well: @@ -782,3 +1687,4 @@ place for later steps to complete. Do not submit feedback yet. Tell the maintainer to carry this draft forward to the next meta skill step. +>>>>>>> 54555c4 (feat: enhance SKILL.md with clarifications on package ownership and skill generation process):packages/playbooks/meta/domain-discovery/SKILL.md diff --git a/packages/intent/meta/feedback-collection/SKILL.md b/packages/intent/meta/feedback-collection/SKILL.md index d3704a74..d426aabd 100644 --- a/packages/intent/meta/feedback-collection/SKILL.md +++ b/packages/intent/meta/feedback-collection/SKILL.md @@ -1,188 +1,188 @@ ---- -name: skill-feedback-collection -description: > - Collect structured feedback about skill usage after completing a coding task. - Activate at the end of any session where one or more SKILL.md files were - loaded. Captures agent signals (gaps, errors, corrections, human interventions) - and brief human input, then submits directly via gh CLI or provides manual - submission instructions. -metadata: - version: '2.0' - category: meta-tooling ---- - -# Skill Feedback Collection - -Run this at the end of any session where you loaded one or more SKILL.md files. -The goal is to capture what worked, what didn't, and what was missing — so skill -maintainers can improve future versions. - ---- - -## Phase 1 — Automated Signal Collection - -Review your own session transcript. No human interaction needed yet. - -### 1a: Gap detection - -Identify moments where the skill was silent and you had to bridge the gap -yourself — via code reading, search, trial-and-error, or general knowledge. - -For each gap, note: - -- What you needed to do -- What the skill should have told you -- How you solved it (code reading, web search, guessing) - -### 1b: Error/correction tracking - -Identify moments where the skill prescribed an approach that produced an error. - -For each error, note: - -- What the skill said to do -- The error or incorrect behavior that resulted -- The fix you applied - -### 1c: Human intervention events - -Identify moments where the human clarified, corrected, or overrode your approach. - -For each intervention, note: - -- What you were doing when the human intervened -- What the human said or changed -- Whether the skill could have prevented this - -### 1d: Step duration anomalies - -Identify steps that consumed disproportionate effort compared to their apparent -complexity. These signal that the skill should provide a template, snippet, or -more detailed guidance. - ---- - -## Phase 2 — Human Interview - -Ask the human up to 4 questions. Keep it brief — skip questions if the session -already provided clear answers. Respect if they decline. - -1. "Was anything unclear about what was happening during the task?" -2. "Did anything feel frustrating or take longer than expected?" -3. "Were you uncertain about the output quality at any point?" -4. "Anything you'd want done differently next time?" - -Derive `userRating` from overall sentiment: - -- Mostly positive → `good` -- Mixed signals → `mixed` -- Mostly negative → `bad` - -If the human gives an explicit rating, use that instead. - ---- - -## Phase 3 — Build the Feedback - -Write one Markdown feedback file per skill used. Only include skills that were -actually used during the session — skip any that were loaded but never -referenced. - -### Template - -```markdown -# Skill Feedback: [skill name from SKILL.md frontmatter] - -**Package:** [npm package name that contains the skill] -**Skill version:** [metadata.version or library_version from frontmatter] -**Rating:** [good | mixed | bad] - -## Task - -[one-sentence summary of what the human asked you to do] - -## What Worked - -[patterns/instructions from the skill that were accurate and helpful] - -## What Failed - -[from 1b — skill instructions that produced errors] - -## Missing - -[from 1a — gaps where the skill should have covered] - -## Self-Corrections - -[from 1b fixes + 1c human interventions, combined] - -## User Comments - -[optional — direct quotes or paraphrased human input from Phase 2] -``` - -### Field derivation guide - -| Field | Source | -| ---------------- | ------------------------------------------------------------------ | -| Skill name | Frontmatter `name` field of the SKILL.md you loaded | -| Package | The npm package the skill lives in (e.g. `@tanstack/query-intent`) | -| Skill version | Frontmatter `metadata.version` or `library_version` | -| Task | Summarize the human's original request in one sentence | -| What Worked | List skill sections/patterns that were correct and useful | -| What Failed | From 1b — skill instructions that produced errors | -| Missing | From 1a — gaps where the skill was silent | -| Self-Corrections | From 1b fixes + 1c human interventions, combined | -| Rating | From Phase 2 sentiment analysis or explicit rating | -| User Comments | From Phase 2 answers, keep brief | - ---- - -## Phase 4 — Submit - -Determine the target repo from the skill's package. The repo is typically -derivable from the `repository` field in the package's `package.json`, or -from the `sources` field in the SKILL.md frontmatter. - -### Privacy check - -Before submitting, determine whether the user's project is public or private. -Check with `gh repo view --json visibility` or look for a `private` field in -the project's `package.json`. If you can't determine visibility, assume private. - -**Private repos:** Feedback is submitted to a public issue tracker, so it must -not contain project-specific details. Before submission: - -1. Strip any project-specific code, file paths, internal API names, service - URLs, or business logic from all fields -2. Rewrite the "Task" field to describe the _type_ of task generically - (e.g. "set up authenticated data fetching" not "set up auth for our - internal billing API at api.acme.corp/billing") -3. Rewrite "What Failed" and "Missing" entries to reference only the - skill's own APIs and patterns, not the user's code -4. Show the sanitized feedback to the user and ask them to confirm it's - safe to submit before proceeding - -**Public repos:** No sanitization needed. Proceed directly to submission. - -### If `gh` CLI is available - -Submit directly as a GitHub issue: - -```bash -gh issue create --repo [owner/repo] --title "Skill Feedback: [skill-name] ([rating])" --label "feedback:[skill-name]" --body-file intent-feedback.md -``` - -If the label doesn't exist, omit the `--label` flag — don't let a missing -label block submission. - -If submission succeeds, delete the feedback file. - -### If `gh` CLI is not available - -Tell the human: - -> "I've written skill feedback to `intent-feedback.md`. To submit it, -> open an issue at https://github.com/[owner/repo]/issues and paste the -> contents." +--- +name: skill-feedback-collection +description: > + Collect structured feedback about skill usage after completing a coding task. + Activate at the end of any session where one or more SKILL.md files were + loaded. Captures agent signals (gaps, errors, corrections, human interventions) + and brief human input, then submits directly via gh CLI or provides manual + submission instructions. +metadata: + version: '2.0' + category: meta-tooling +--- + +# Skill Feedback Collection + +Run this at the end of any session where you loaded one or more SKILL.md files. +The goal is to capture what worked, what didn't, and what was missing — so skill +maintainers can improve future versions. + +--- + +## Phase 1 — Automated Signal Collection + +Review your own session transcript. No human interaction needed yet. + +### 1a: Gap detection + +Identify moments where the skill was silent and you had to bridge the gap +yourself — via code reading, search, trial-and-error, or general knowledge. + +For each gap, note: + +- What you needed to do +- What the skill should have told you +- How you solved it (code reading, web search, guessing) + +### 1b: Error/correction tracking + +Identify moments where the skill prescribed an approach that produced an error. + +For each error, note: + +- What the skill said to do +- The error or incorrect behavior that resulted +- The fix you applied + +### 1c: Human intervention events + +Identify moments where the human clarified, corrected, or overrode your approach. + +For each intervention, note: + +- What you were doing when the human intervened +- What the human said or changed +- Whether the skill could have prevented this + +### 1d: Step duration anomalies + +Identify steps that consumed disproportionate effort compared to their apparent +complexity. These signal that the skill should provide a template, snippet, or +more detailed guidance. + +--- + +## Phase 2 — Human Interview + +Ask the human up to 4 questions. Keep it brief — skip questions if the session +already provided clear answers. Respect if they decline. + +1. "Was anything unclear about what was happening during the task?" +2. "Did anything feel frustrating or take longer than expected?" +3. "Were you uncertain about the output quality at any point?" +4. "Anything you'd want done differently next time?" + +Derive `userRating` from overall sentiment: + +- Mostly positive → `good` +- Mixed signals → `mixed` +- Mostly negative → `bad` + +If the human gives an explicit rating, use that instead. + +--- + +## Phase 3 — Build the Feedback + +Write one Markdown feedback file per skill used. Only include skills that were +actually used during the session — skip any that were loaded but never +referenced. + +### Template + +```markdown +# Skill Feedback: [skill name from SKILL.md frontmatter] + +**Package:** [npm package name that contains the skill] +**Skill version:** [metadata.version or library_version from frontmatter] +**Rating:** [good | mixed | bad] + +## Task + +[one-sentence summary of what the human asked you to do] + +## What Worked + +[patterns/instructions from the skill that were accurate and helpful] + +## What Failed + +[from 1b — skill instructions that produced errors] + +## Missing + +[from 1a — gaps where the skill should have covered] + +## Self-Corrections + +[from 1b fixes + 1c human interventions, combined] + +## User Comments + +[optional — direct quotes or paraphrased human input from Phase 2] +``` + +### Field derivation guide + +| Field | Source | +| ---------------- | ------------------------------------------------------------------ | +| Skill name | Frontmatter `name` field of the SKILL.md you loaded | +| Package | The npm package the skill lives in (e.g. `@tanstack/query-intent`) | +| Skill version | Frontmatter `metadata.version` or `library_version` | +| Task | Summarize the human's original request in one sentence | +| What Worked | List skill sections/patterns that were correct and useful | +| What Failed | From 1b — skill instructions that produced errors | +| Missing | From 1a — gaps where the skill was silent | +| Self-Corrections | From 1b fixes + 1c human interventions, combined | +| Rating | From Phase 2 sentiment analysis or explicit rating | +| User Comments | From Phase 2 answers, keep brief | + +--- + +## Phase 4 — Submit + +Determine the target repo from the skill's package. The repo is typically +derivable from the `repository` field in the package's `package.json`, or +from the `sources` field in the SKILL.md frontmatter. + +### Privacy check + +Before submitting, determine whether the user's project is public or private. +Check with `gh repo view --json visibility` or look for a `private` field in +the project's `package.json`. If you can't determine visibility, assume private. + +**Private repos:** Feedback is submitted to a public issue tracker, so it must +not contain project-specific details. Before submission: + +1. Strip any project-specific code, file paths, internal API names, service + URLs, or business logic from all fields +2. Rewrite the "Task" field to describe the _type_ of task generically + (e.g. "set up authenticated data fetching" not "set up auth for our + internal billing API at api.acme.corp/billing") +3. Rewrite "What Failed" and "Missing" entries to reference only the + skill's own APIs and patterns, not the user's code +4. Show the sanitized feedback to the user and ask them to confirm it's + safe to submit before proceeding + +**Public repos:** No sanitization needed. Proceed directly to submission. + +### If `gh` CLI is available + +Submit directly as a GitHub issue: + +```bash +gh issue create --repo [owner/repo] --title "Skill Feedback: [skill-name] ([rating])" --label "feedback:[skill-name]" --body-file intent-feedback.md +``` + +If the label doesn't exist, omit the `--label` flag — don't let a missing +label block submission. + +If submission succeeds, delete the feedback file. + +### If `gh` CLI is not available + +Tell the human: + +> "I've written skill feedback to `intent-feedback.md`. To submit it, +> open an issue at https://github.com/[owner/repo]/issues and paste the +> contents." diff --git a/packages/intent/meta/generate-skill/SKILL.md b/packages/intent/meta/generate-skill/SKILL.md index fb69eaae..a4006460 100644 --- a/packages/intent/meta/generate-skill/SKILL.md +++ b/packages/intent/meta/generate-skill/SKILL.md @@ -1,3 +1,433 @@ +<<<<<<< HEAD:packages/intent/meta/generate-skill/SKILL.md +--- +name: skill-generate +description: > + Generate a complete SKILL.md file for a library from source documentation + and skill tree artifacts. Activate when bootstrapping skills for a new + library, regenerating a stale skill after source changes, or producing a + skill from a skill_tree.yaml entry. Takes a skill name, description, and + source docs as inputs; outputs a validated SKILL.md that conforms to the + tree-generator spec. +metadata: + version: '1.0' + category: meta-tooling + input_artifacts: + - skills/_artifacts/skill_tree.yaml + - skills/_artifacts/domain_map.yaml + - skills/_artifacts/skill_spec.md + - source documentation + output_artifacts: + - SKILL.md + skills: + - skill-tree-generator + - skill-domain-discovery +--- + +# Skill Generation + +You are generating a SKILL.md file for the `@tanstack/intent` agent skills +repo. Skills in this repo are written for coding agents (Claude Code, Cursor, +Copilot, Warp Oz, Codex), not for human readers. Your output will be loaded +into an agent's context window and used to guide code generation. + +There are two modes. Detect which applies. + +**Mode A — Generate from domain map:** A `domain_map.yaml` and `skill_spec.md` +exist. Generate the skill specified by name from these artifacts plus the +source documentation they reference. + +**Mode B — Generate from raw docs:** No domain map exists. Generate directly +from source documentation provided as input. + +--- + +## Inputs + +You will receive: + +If the maintainer uses a custom skills root, replace `skills/` in any paths +below with their chosen directory. + +**Monorepo:** When the skill tree entry has a `package` field, write the +SKILL.md into that package's skills directory (e.g. +`packages/client/skills/core/SKILL.md`), not a shared root. + +1. **Skill name** — format `library-group/skill-name` (e.g. `tanstack-query/core`, + `tanstack-router/loaders`, `db/core/live-queries`) +2. **Skill description** — what the skill covers and when an agent should load it +3. **Source documentation** — the docs, guides, API references, and/or source + files to distill from +4. **Domain map entry** (Mode A only) — the skill's entry from `domain_map.yaml` + including failure modes, subsystems, compositions, and source references + +--- + +## Step 1 — Determine skill type + +Read the inputs and classify the skill type: + +| Type | When to use | +| ------------- | ---------------------------------------------------------- | +| `core` | Framework-agnostic concepts, configuration, patterns | +| `sub-skill` | A focused sub-topic within a core or framework skill | +| `framework` | Framework-specific bindings, hooks, components | +| `lifecycle` | Cross-cutting developer journey (getting started, go-live) | +| `composition` | Integration between two or more libraries | +| `security` | Audit checklist or security validation | + +The skill type determines the frontmatter and body structure. See +skill-tree-generator for the full spec of each type. + +--- + +## Step 2 — Extract content from sources + +**Line budget:** Each SKILL.md must stay under 500 lines. Before writing, +estimate the content size. If a skill has 5+ failure modes, 3+ primary +patterns, and subsystem details, proactively plan reference files during +extraction — don't wait until the skill exceeds the limit. + +Read through the source documentation. Extract only what a coding agent +cannot already know: + +### What to extract + +- **API shapes** — function signatures, hook parameters, option objects, + return types. Use the actual TypeScript types from source. +- **Setup patterns** — minimum viable initialization code +- **Primary patterns** — the 2–4 most important usage patterns +- **Configuration** — defaults that matter, options that change behavior +- **Failure modes** — patterns that look correct but break. Prioritize: + - Migration-boundary mistakes (old API that agents trained on older data produce) + - Silent failures (no crash, wrong behavior) + - Framework-specific gotchas (hydration, hook rules, provider ordering) +- **Constraints and invariants** — ordering requirements, lifecycle rules, + things enforced by runtime assertions + +### What NOT to extract + +- TypeScript basics, React hooks concepts, general web dev knowledge +- Marketing copy, motivational prose, "why this library is great" +- Exhaustive API tables (move these to `references/` if needed) +- Content that duplicates another skill (reference it instead) + +--- + +## Step 3 — Write the frontmatter + +### Core skill frontmatter + +```yaml +--- +name: [library]/[skill-name] +description: > + [1–3 sentences. What this skill covers and exactly when an agent should + load it. Written for the agent — include the keywords an agent would + encounter when it needs this skill. Dense routing key.] +type: core +library: [library] +library_version: "[version this targets]" +sources: + - "[Owner/repo]:docs/[path].md" + - "[Owner/repo]:src/[path].ts" +--- +``` + +### Sub-skill frontmatter + +```yaml +--- +name: [library]/[parent]/[skill-name] +description: > + [1–3 sentences. What this sub-topic covers and when to load it.] +type: sub-skill +library: [library] +library_version: "[version]" +sources: + - "[Owner/repo]:docs/[path].md" +--- +``` + +### Framework skill frontmatter + +```yaml +--- +name: [library]/[framework] +description: > + [1–3 sentences. Framework-specific bindings. Name the hooks, components, + providers.] +type: framework +library: [library] +framework: [react | vue | solid | svelte | angular] +library_version: "[version]" +requires: + - [library]/core +sources: + - "[Owner/repo]:docs/framework/[framework]/[path].md" +--- +``` + +### Frontmatter rules + +- `description` must be written so the agent loads this skill at the right + time — not too broad (triggers on everything) and not too narrow (never + triggers). Pack with function names, option names, concept keywords. +- `sources` uses the format `Owner/repo:relative-path`. Glob patterns are + supported (e.g. `TanStack/query:docs/framework/react/guides/*.md`). +- `library_version` is the version of the source library this skill targets. +- `requires` lists skills that must be loaded before this one. + +--- + +## Step 4 — Write the body + +### Standard body (core, sub-skill, framework) + +Follow this section order exactly: + +**1. Dependency note** (framework and sub-skills only) + +```markdown +This skill builds on [parent-skill]. Read it first for foundational concepts. +``` + +**2. Setup** + +A complete, copy-pasteable code block showing minimum viable usage. + +- Real package imports with exact names (`@tanstack/react-query`, not `react-query`) +- No `// ...` or `[your code here]` — complete and runnable +- No unnecessary boilerplate — include exactly the context needed +- For framework skills: framework-specific setup (provider, hook wiring) +- For core skills: framework-agnostic setup (no hooks, no components) + +**3. Core Patterns** (or "Hooks and Components" for framework skills) + +2–4 patterns. For each: + +- One-line heading: what it accomplishes +- Complete code block +- One sentence of explanation only if not self-explanatory + +**4. Common Mistakes** + +Minimum 3 entries. Complex skills target 5–6. Format: + +````markdown +### [PRIORITY] [What goes wrong — 5–8 word phrase] + +Wrong: + +```[lang] +// code that looks correct but isn't +``` +```` + +Correct: + +```[lang] +// code that works +``` + +[One sentence: the specific mechanism by which the wrong version fails.] + +Source: [doc page or source file:line] + +```` + +Priority levels: +- **CRITICAL** — Breaks in production. Security risk or data loss. +- **HIGH** — Incorrect behavior under common conditions. +- **MEDIUM** — Incorrect under specific conditions or edge cases. + +Every mistake must be: +- **Plausible** — an agent would generate it +- **Silent** — no immediate crash +- **Grounded** — traceable to a doc page, source file, or issue + +If the domain map includes failure modes with a `skills` list naming +multiple skills, include those failure modes in every SKILL file listed. + +**5. References** (only when needed) + +```markdown +## References + +- [Full option reference](references/options.md) +```` + +Create reference files when the skill would exceed 500 lines, when the +domain covers 3+ independent adapters/backends, or when a topic has >10 +distinct API patterns. + +### Checklist body (security, go-live, audit) + +Use when the primary action is "check these things" not "learn patterns": + +````markdown +# [Library Name] — [Security | Go-Live] Checklist + +Run through each section before [deploying | releasing]. + +## [Category] Checks + +### Check: [what to verify] + +Expected: + +```[lang] +// correct configuration +``` +```` + +Fail condition: [what indicates this check failed] +Fix: [one-line remediation] + +## Common Security Mistakes + +[Wrong/correct pairs, same format as standard Common Mistakes] + +## Pre-Deploy Summary + +- [ ] [Verification 1] +- [ ] [Verification 2] + +``` + +--- + +## Step 5 — Validate + +Run every check before outputting. Fix any failures. + +| Check | Rule | +|-------|------| +| Under 500 lines | Move excess to references/ | +| Real imports in every code block | Exact package name, correct adapter | +| No external concept explanations | No "TypeScript is...", no "React hooks are..." | +| No marketing prose | No "powerful", "elegant", "best-in-class" | +| Every code block is complete | Works without modification when pasted | +| Common Mistakes are silent | Not obvious compile errors | +| Common Mistakes are library-specific | Not generic TS/React mistakes | +| Common Mistakes are sourced | Traceable to doc or source | +| `name` matches expected directory path | `db/core/live-queries` → `db/core/live-queries/SKILL.md` | +| `sources` filled for sub-skills | At least one Owner/repo:path | +| Framework skills have `requires` | Lists core dependency | +| Framework skills open with dependency note | First prose line references core | +| Description is a dense routing key | Not a human summary — agent-facing | + +--- + +## Step 6 — Output + +Output the complete SKILL.md file content. If reference files are needed, +output those as well with their relative paths. + +If generating multiple skills in a batch (e.g. all skills for a library), +output in this order: + +1. Core overview SKILL.md +2. Core sub-skills in domain order +3. Framework overview SKILL.md for each framework +4. Framework sub-skills +5. Composition skills +6. Security/checklist skills +7. Reference files + +--- + +## Regeneration mode + +When regenerating a stale skill (triggered by skill-staleness-check): + +1. Read the existing SKILL.md and the source diff that triggered staleness +2. Determine which sections are affected by the change +3. Update only affected sections — preserve all other content +4. If a breaking change occurred, add the old pattern as a new Common + Mistake entry (wrong/correct pair) +5. Bump `library_version` in frontmatter +6. Validate the complete file against Step 5 checks + +Do not rewrite the entire skill for a minor source change. Surgical +updates preserve review effort and reduce diff noise. + +--- + +## Constraints + +| Rule | Detail | +|------|--------| +| Match the library's framework support | Generate framework skills only for adapters the library actually provides. If the library supports only React, only generate React examples. If it supports multiple frameworks, generate one skill per adapter. | +| All imports use real package names | `@tanstack/react-query`, not `react-query` | +| No placeholder code | No `// ...`, `[your value]`, or `...rest`. Idiomatic framework patterns like `{children}` or `{props.title}` in JSX are not placeholders — they are real code and are acceptable. | +| Agent-first writing | Only write what the agent cannot already know | +| Examples are minimal | No unnecessary boilerplate or wrapper components | +| Failure modes are high-value | Focus on plausible-but-broken, not obvious errors | + +--- + +## Cross-model compatibility + +Output is consumed by all major AI coding agents. To ensure consistency: + +- Markdown with YAML frontmatter — universally parsed +- No XML tags in generated skill content +- Code blocks use triple backticks with language annotation +- Section boundaries use ## headers +- Descriptions are keyword-packed for routing +- Examples show concrete values, never placeholders +- Positive instructions ("Use X") over negative ("Don't use Y") +- Critical info at start or end of sections (not buried in middle) +- Each SKILL.md is self-contained except for declared `requires` + +--- + +## Meta-skill feedback (alpha default) + +After generating the first iteration of skills, complete a single Markdown +feedback draft for all three meta skills used in scaffolding. If a draft +exists from previous steps, keep it and fill the **Generate Skill** section. +If no draft exists, create it using this exact template. + +``` + +# Intent Meta Skill Feedback + +## Domain Discovery + +- What worked well: +- What was confusing or missing: +- Suggestions for improvement: +- Overall rating: good | mixed | bad + +## Tree Generator + +- What worked well: +- What was confusing or missing: +- Suggestions for improvement: +- Overall rating: good | mixed | bad + +## Generate Skill + +- What worked well: +- What was confusing or missing: +- Suggestions for improvement: +- Overall rating: good | mixed | bad + +## Context (optional) + +- Library: +- Repo: +- Docs: +- Notes: + +``` + +Ask the maintainer if they want to edit the feedback. Then ask if you should +send it as a GitHub issue to TanStack/intent. Use the issue title: +`[meta-feedback] intent meta skill`. Only submit if they confirm. +``` +======= --- name: skill-generate description: > @@ -24,7 +454,7 @@ metadata: # Skill Generation -You are generating a SKILL.md file for the `@tanstack/intent` agent skills +You are generating a SKILL.md file for the `@tanstack/playbooks` agent skills repo. Skills in this repo are written for coding agents (Claude Code, Cursor, Copilot, Warp Oz, Codex), not for human readers. Your output will be loaded into an agent's context window and used to guide code generation. @@ -47,12 +477,15 @@ You will receive: If the maintainer uses a custom skills root, replace `skills/` in any paths below with their chosen directory. -**Monorepo:** When the skill tree entry has a `package` field, write the -SKILL.md into that package's skills directory (e.g. -`packages/client/skills/core/SKILL.md`), not a shared root. +For monorepo libraries, skills ship inside the package they belong to. +Each package has its own `skills/` directory so that when a developer +installs a package (e.g. `@tanstack/react-router`), the skills are +available locally. Cross-package skills live in whichever package is the +primary entry point for that task, with references to the other packages. 1. **Skill name** — format `library-group/skill-name` (e.g. `tanstack-query/core`, - `tanstack-router/loaders`, `db/core/live-queries`) + `tanstack-router/loaders`, `db/core/live-queries`). The name determines the + output file path: `skills/[name]/SKILL.md` relative to the package root. 2. **Skill description** — what the skill covers and when an agent should load it 3. **Source documentation** — the docs, guides, API references, and/or source files to distill from @@ -81,11 +514,6 @@ skill-tree-generator for the full spec of each type. ## Step 2 — Extract content from sources -**Line budget:** Each SKILL.md must stay under 500 lines. Before writing, -estimate the content size. If a skill has 5+ failure modes, 3+ primary -patterns, and subsystem details, proactively plan reference files during -extraction — don't wait until the skill exceeds the limit. - Read through the source documentation. Extract only what a coding agent cannot already know: @@ -126,6 +554,9 @@ description: > type: core library: [library] library_version: "[version this targets]" +packages: # required for monorepo; omit for single-package libraries + - "[package where this skill ships]" + - "[additional package, if skill is relevant to multiple packages]" sources: - "[Owner/repo]:docs/[path].md" - "[Owner/repo]:src/[path].ts" @@ -323,9 +754,17 @@ Output the complete SKILL.md file content. If reference files are needed, output those as well with their relative paths. If generating multiple skills in a batch (e.g. all skills for a library), -output in this order: +generate and present the first core overview SKILL.md to the maintainer +before writing the rest. + +**── STOP ── Wait for the maintainer to review the first generated skill. +Their feedback on structure, tone, and detail level applies to every +subsequent skill. Catching issues early avoids rewriting the entire batch.** -1. Core overview SKILL.md +After the maintainer confirms (or provides corrections), generate the +remaining skills in this order: + +1. Core overview SKILL.md (already reviewed above) 2. Core sub-skills in domain order 3. Framework overview SKILL.md for each framework 4. Framework sub-skills @@ -356,9 +795,10 @@ updates preserve review effort and reduce diff noise. | Rule | Detail | |------|--------| -| Match the library's framework support | Generate framework skills only for adapters the library actually provides. If the library supports only React, only generate React examples. If it supports multiple frameworks, generate one skill per adapter. | +| **First skill reviewed before batch** | In batch mode, present the first core skill for maintainer review before generating the rest | +| React adapter only (Phase 1) | No Vue, Solid, Svelte, Angular examples unless generating a framework skill for that adapter | | All imports use real package names | `@tanstack/react-query`, not `react-query` | -| No placeholder code | No `// ...`, `[your value]`, or `...rest`. Idiomatic framework patterns like `{children}` or `{props.title}` in JSX are not placeholders — they are real code and are acceptable. | +| No placeholder code | No `// ...`, `[your value]`, or `...rest` | | Agent-first writing | Only write what the agent cannot already know | | Examples are minimal | No unnecessary boilerplate or wrapper components | | Failure modes are high-value | Focus on plausible-but-broken, not obvious errors | @@ -381,16 +821,21 @@ Output is consumed by all major AI coding agents. To ensure consistency: --- -## Meta-skill feedback (alpha default) +## Meta-skill feedback (alpha — temporary) + +During the alpha period, collect feedback from the maintainer on the +skill generation process. Ask if they'd like to share what worked well, +what was confusing, or suggestions for improvement. If they decline or +want to move on, that's fine. -After generating the first iteration of skills, complete a single Markdown +Complete a single Markdown feedback draft for all three meta skills used in scaffolding. If a draft exists from previous steps, keep it and fill the **Generate Skill** section. If no draft exists, create it using this exact template. ``` -# Intent Meta Skill Feedback +# Playbook Meta Skill Feedback ## Domain Discovery @@ -423,6 +868,7 @@ If no draft exists, create it using this exact template. ``` Ask the maintainer if they want to edit the feedback. Then ask if you should -send it as a GitHub issue to TanStack/intent. Use the issue title: -`[meta-feedback] intent meta skill`. Only submit if they confirm. +send it as a GitHub issue to TanStack/playbooks. Use the issue title: +`[meta-feedback] playbook meta skill`. Only submit if they confirm. ``` +>>>>>>> 54555c4 (feat: enhance SKILL.md with clarifications on package ownership and skill generation process):packages/playbooks/meta/generate-skill/SKILL.md diff --git a/packages/intent/meta/skill-staleness-check/SKILL.md b/packages/intent/meta/skill-staleness-check/SKILL.md index 0e36f6a2..9155becd 100644 --- a/packages/intent/meta/skill-staleness-check/SKILL.md +++ b/packages/intent/meta/skill-staleness-check/SKILL.md @@ -1,282 +1,282 @@ ---- -name: skill-staleness-check -description: > - Evaluate intent skills for staleness when source files change in upstream - TanStack package repos. Matches changed files against metadata.sources, - evaluates whether diffs affect documented behavior, rewrites stale skills - using skill-generate, checks cross-skill references, and opens PRs. - Silent when nothing needs updating. -metadata: - version: '1.0' - category: meta-tooling - input_artifacts: - - webhook payload (package name, commit SHA, changed files) - output_artifacts: - - updated SKILL.md files - - pull requests - skills: - - skill-generate - - skill-tree-generator ---- - -# Skill Staleness Check - -You are a coding agent. Your job is to evaluate whether intent skills are -stale after upstream source changes, and if so, update them and open PRs. -You act autonomously end-to-end. PRs contain already-updated skill -content, not suggestions. - -If nothing needs updating, exit silently. No PR, no notification. - ---- - -## Inputs - -Webhook payload from an upstream package repo merge to main: - -```json -{ - "package": "@tanstack/query", - "sha": "abc123", - "changed_files": ["docs/framework/react/guides/queries.md", "src/query.ts"] -} -``` - ---- - -## Step 1 — Match changed files to skills - -Read all SKILL.md files under `packages/intent/skills/`. For each skill, -extract `sources` from the frontmatter. - -Match `changed_files` from the webhook against `sources` entries across all -skills. Source references use the format `Owner/repo:relative-path` and -support glob patterns. - -A skill is a **candidate** if any of its `sources` entries match a changed -file. - -If no skills match, exit silently. - -### Using sync-skills.mjs - -The repo includes `scripts/sync-skills.mjs` for programmatic staleness -detection. For a given library: - -```bash -node scripts/sync-skills.mjs -``` - -This checks: - -- Source file SHA drift (compares stored SHAs in `sync-state.json` against - current remote SHAs via GitHub API) -- Library version drift (frontmatter `library_version` vs current published - version) -- Tree-generator changes (whether the meta skill has been updated since - last sync) - -Use `--report` to write a structured `staleness_report.yaml`: - -```bash -node scripts/sync-skills.mjs --report -``` - -The report classifies skills as needing regeneration (source changed) or -version bump only. - ---- - -## Step 2 — Evaluate each candidate - -For each matched skill: - -1. Read the current SKILL.md content -2. Fetch the file diff from the triggering commit in the source repo -3. Classify the change: - -| Classification | Criteria | Action | -| --------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------- | -| **No impact** | Diff is typo fix, comment change, test-only, or internal refactor with no API/behavior change | Skip — no update needed | -| **Version bump only** | Diff changes version numbers, dependency ranges, or metadata but no documented behavior | Bump `library_version` in frontmatter | -| **Content update** | Diff changes API shape, behavior, defaults, types, or patterns that the skill documents | Rewrite affected sections | -| **Breaking change** | Diff removes, renames, or fundamentally changes an API the skill documents | Rewrite + add old pattern as Common Mistake | - -### Two-pass classification - -**Pass 1 — Quick scan:** Read the diff summary (files changed, insertions, -deletions). Identify which skill sections could be affected. - -**Pass 2 — Detail evaluation:** For each potentially affected section, read -the full diff hunks and compare against the skill content. Determine if the -change actually affects what the skill documents. - -This prevents over-updating. A 200-line diff to a source file may only -affect one line of one skill, or none at all. - ---- - -## Step 3 — Update stale skills - -For skills classified as needing content updates: - -1. Load the skill-generate meta skill -2. Provide it with: - - The existing SKILL.md content - - The source diff - - The current source documentation (fetch the updated file) -3. Use regeneration mode (surgical update, not full rewrite) -4. Validate the updated skill against all checks - -For version bump only: - -```bash -node scripts/sync-skills.mjs --bump-version -``` - -This updates `library_version` in all frontmatter for the library and -records the new version in `sync-state.json`. - ---- - -## Step 4 — Check cross-skill references - -After updating skills in Step 3, check for cross-skill staleness: - -1. For each skill that was updated, read its `name` -2. Scan all other skills for `requires` entries or `sources` that reference - the updated skill -3. For each skill that references an updated skill, evaluate whether the - update makes the referencing skill stale or inconsistent -4. If stale → update using the same process as Step 3 -5. If not → skip - -This cascade is bounded to **one level**. Skills that reference a -second-order dependency are not automatically re-checked. - ---- - -## Step 5 — Mark skills as synced - -After updating, mark the affected skills as synced so future staleness -checks have a clean baseline: - -```bash -# Mark specific skills -node scripts/sync-skills.mjs --mark-synced - -# Mark all skills for a library -node scripts/sync-skills.mjs --mark-synced --all -``` - -This updates `sync-state.json` with current source file SHAs, the -tree-generator SHA, and the sync timestamp. - ---- - -## Step 6 — Open PRs - -For each skill (or group of skills) that was updated: - -1. Create branch: `skill-update/-` -2. Commit updated SKILL.md file(s) -3. Open PR with structured body - -### PR format - -**Title:** `skill: update (@)` - -**Body:** - -```markdown -### Triggered by - -Changes to: - -### What changed in the source - - - -### What changed in the skill - - - -### Cross-skill impact - - - -### Review checklist - -- [ ] Skill content is accurate -- [ ] Code examples are complete and copy-pasteable -- [ ] No other skills need corresponding updates -- [ ] Under 500 lines -``` - -### Grouping PRs - -- If multiple skills for the same library are affected by the same commit, - group them in a single PR -- If a cross-skill update is needed (Step 4), open a separate PR for the - downstream skill to keep review scopes clean -- Never mix skills from different libraries in the same PR - ---- - -## No-op behavior - -Exit silently (no PR, no notification, no issue) when ANY of these are true: - -- No changed files match any skill's `sources` -- All matched diffs are classified as "no impact" in Step 2 -- The sync-skills.mjs report shows all skills are current - ---- - -## Operational notes - -### GitHub API usage - -The `sync-skills.mjs` script uses the `gh` CLI for GitHub API access. It -requires: - -- `gh` CLI installed and authenticated -- Read access to upstream TanStack package repos (query, router, db, form, - table) -- Write access to the intent repo for creating branches and PRs - -### Rate limiting - -When checking multiple libraries or many source files, the script makes -one API call per source file per skill. For large batches, the GitHub API -rate limit (5000 requests/hour for authenticated users) may apply. The -script does not currently batch or cache API responses — if this becomes -an issue, add caching at the `getRemoteFileSha` level. - -### Manual triggering - -Maintainers can run staleness detection manually: - -```bash -# Check a specific library -node scripts/sync-skills.mjs db - -# Check and write a report -node scripts/sync-skills.mjs db --report - -# After reviewing and regenerating, mark as synced -node scripts/sync-skills.mjs db --mark-synced --all -``` - ---- - -## Constraints - -| Rule | Detail | -| ----------------------------------------------- | --------------------------------------------------- | -| Silent when nothing changes | No noise — exit cleanly if no updates needed | -| Surgical updates over full rewrites | Only change sections affected by the diff | -| One cascade level | Cross-skill checks go one level deep, not recursive | -| PRs scoped to one library | Never mix libraries in a single PR | -| Version bumps are separate from content updates | A version-only bump doesn't require regeneration | -| Commit messages include co-author | Include the coding agent's co-author tag | +--- +name: skill-staleness-check +description: > + Evaluate intent skills for staleness when source files change in upstream + TanStack package repos. Matches changed files against metadata.sources, + evaluates whether diffs affect documented behavior, rewrites stale skills + using skill-generate, checks cross-skill references, and opens PRs. + Silent when nothing needs updating. +metadata: + version: '1.0' + category: meta-tooling + input_artifacts: + - webhook payload (package name, commit SHA, changed files) + output_artifacts: + - updated SKILL.md files + - pull requests + skills: + - skill-generate + - skill-tree-generator +--- + +# Skill Staleness Check + +You are a coding agent. Your job is to evaluate whether intent skills are +stale after upstream source changes, and if so, update them and open PRs. +You act autonomously end-to-end. PRs contain already-updated skill +content, not suggestions. + +If nothing needs updating, exit silently. No PR, no notification. + +--- + +## Inputs + +Webhook payload from an upstream package repo merge to main: + +```json +{ + "package": "@tanstack/query", + "sha": "abc123", + "changed_files": ["docs/framework/react/guides/queries.md", "src/query.ts"] +} +``` + +--- + +## Step 1 — Match changed files to skills + +Read all SKILL.md files under `packages/intent/skills/`. For each skill, +extract `sources` from the frontmatter. + +Match `changed_files` from the webhook against `sources` entries across all +skills. Source references use the format `Owner/repo:relative-path` and +support glob patterns. + +A skill is a **candidate** if any of its `sources` entries match a changed +file. + +If no skills match, exit silently. + +### Using sync-skills.mjs + +The repo includes `scripts/sync-skills.mjs` for programmatic staleness +detection. For a given library: + +```bash +node scripts/sync-skills.mjs +``` + +This checks: + +- Source file SHA drift (compares stored SHAs in `sync-state.json` against + current remote SHAs via GitHub API) +- Library version drift (frontmatter `library_version` vs current published + version) +- Tree-generator changes (whether the meta skill has been updated since + last sync) + +Use `--report` to write a structured `staleness_report.yaml`: + +```bash +node scripts/sync-skills.mjs --report +``` + +The report classifies skills as needing regeneration (source changed) or +version bump only. + +--- + +## Step 2 — Evaluate each candidate + +For each matched skill: + +1. Read the current SKILL.md content +2. Fetch the file diff from the triggering commit in the source repo +3. Classify the change: + +| Classification | Criteria | Action | +| --------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------- | +| **No impact** | Diff is typo fix, comment change, test-only, or internal refactor with no API/behavior change | Skip — no update needed | +| **Version bump only** | Diff changes version numbers, dependency ranges, or metadata but no documented behavior | Bump `library_version` in frontmatter | +| **Content update** | Diff changes API shape, behavior, defaults, types, or patterns that the skill documents | Rewrite affected sections | +| **Breaking change** | Diff removes, renames, or fundamentally changes an API the skill documents | Rewrite + add old pattern as Common Mistake | + +### Two-pass classification + +**Pass 1 — Quick scan:** Read the diff summary (files changed, insertions, +deletions). Identify which skill sections could be affected. + +**Pass 2 — Detail evaluation:** For each potentially affected section, read +the full diff hunks and compare against the skill content. Determine if the +change actually affects what the skill documents. + +This prevents over-updating. A 200-line diff to a source file may only +affect one line of one skill, or none at all. + +--- + +## Step 3 — Update stale skills + +For skills classified as needing content updates: + +1. Load the skill-generate meta skill +2. Provide it with: + - The existing SKILL.md content + - The source diff + - The current source documentation (fetch the updated file) +3. Use regeneration mode (surgical update, not full rewrite) +4. Validate the updated skill against all checks + +For version bump only: + +```bash +node scripts/sync-skills.mjs --bump-version +``` + +This updates `library_version` in all frontmatter for the library and +records the new version in `sync-state.json`. + +--- + +## Step 4 — Check cross-skill references + +After updating skills in Step 3, check for cross-skill staleness: + +1. For each skill that was updated, read its `name` +2. Scan all other skills for `requires` entries or `sources` that reference + the updated skill +3. For each skill that references an updated skill, evaluate whether the + update makes the referencing skill stale or inconsistent +4. If stale → update using the same process as Step 3 +5. If not → skip + +This cascade is bounded to **one level**. Skills that reference a +second-order dependency are not automatically re-checked. + +--- + +## Step 5 — Mark skills as synced + +After updating, mark the affected skills as synced so future staleness +checks have a clean baseline: + +```bash +# Mark specific skills +node scripts/sync-skills.mjs --mark-synced + +# Mark all skills for a library +node scripts/sync-skills.mjs --mark-synced --all +``` + +This updates `sync-state.json` with current source file SHAs, the +tree-generator SHA, and the sync timestamp. + +--- + +## Step 6 — Open PRs + +For each skill (or group of skills) that was updated: + +1. Create branch: `skill-update/-` +2. Commit updated SKILL.md file(s) +3. Open PR with structured body + +### PR format + +**Title:** `skill: update (@)` + +**Body:** + +```markdown +### Triggered by + +Changes to: + +### What changed in the source + + + +### What changed in the skill + + + +### Cross-skill impact + + + +### Review checklist + +- [ ] Skill content is accurate +- [ ] Code examples are complete and copy-pasteable +- [ ] No other skills need corresponding updates +- [ ] Under 500 lines +``` + +### Grouping PRs + +- If multiple skills for the same library are affected by the same commit, + group them in a single PR +- If a cross-skill update is needed (Step 4), open a separate PR for the + downstream skill to keep review scopes clean +- Never mix skills from different libraries in the same PR + +--- + +## No-op behavior + +Exit silently (no PR, no notification, no issue) when ANY of these are true: + +- No changed files match any skill's `sources` +- All matched diffs are classified as "no impact" in Step 2 +- The sync-skills.mjs report shows all skills are current + +--- + +## Operational notes + +### GitHub API usage + +The `sync-skills.mjs` script uses the `gh` CLI for GitHub API access. It +requires: + +- `gh` CLI installed and authenticated +- Read access to upstream TanStack package repos (query, router, db, form, + table) +- Write access to the intent repo for creating branches and PRs + +### Rate limiting + +When checking multiple libraries or many source files, the script makes +one API call per source file per skill. For large batches, the GitHub API +rate limit (5000 requests/hour for authenticated users) may apply. The +script does not currently batch or cache API responses — if this becomes +an issue, add caching at the `getRemoteFileSha` level. + +### Manual triggering + +Maintainers can run staleness detection manually: + +```bash +# Check a specific library +node scripts/sync-skills.mjs db + +# Check and write a report +node scripts/sync-skills.mjs db --report + +# After reviewing and regenerating, mark as synced +node scripts/sync-skills.mjs db --mark-synced --all +``` + +--- + +## Constraints + +| Rule | Detail | +| ----------------------------------------------- | --------------------------------------------------- | +| Silent when nothing changes | No noise — exit cleanly if no updates needed | +| Surgical updates over full rewrites | Only change sections affected by the diff | +| One cascade level | Cross-skill checks go one level deep, not recursive | +| PRs scoped to one library | Never mix libraries in a single PR | +| Version bumps are separate from content updates | A version-only bump doesn't require regeneration | +| Commit messages include co-author | Include the coding agent's co-author tag | diff --git a/packages/intent/meta/templates/workflows/check-skills.yml b/packages/intent/meta/templates/workflows/check-skills.yml index 602d01e1..8445d931 100644 --- a/packages/intent/meta/templates/workflows/check-skills.yml +++ b/packages/intent/meta/templates/workflows/check-skills.yml @@ -1,143 +1,143 @@ -# check-skills.yml — Drop this into your library repo's .github/workflows/ -# -# Checks for stale intent skills after a release and opens a review PR -# if any skills need attention. The PR body includes a prompt you can -# paste into Claude Code, Cursor, or any coding agent to update them. -# -# Triggers: new release published, or manual workflow_dispatch. -# -# Template variables (replaced by `intent setup`): -# {{PACKAGE_NAME}} — e.g. @tanstack/query - -name: Check Skills - -on: - release: - types: [published] - workflow_dispatch: {} - -permissions: - contents: write - pull-requests: write - -jobs: - check: - name: Check for stale skills - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Install intent - run: npm install {{PACKAGE_NAME}} - - - name: Check staleness - id: stale - run: | - OUTPUT=$(npx @tanstack/intent stale --json 2>&1) || true - echo "$OUTPUT" - - # Check if any skills need review - NEEDS_REVIEW=$(echo "$OUTPUT" | node -e " - const input = require('fs').readFileSync('/dev/stdin','utf8'); - try { - const reports = JSON.parse(input); - const stale = reports.flatMap(r => - r.skills.filter(s => s.needsReview).map(s => ({ library: r.library, skill: s.name, reasons: s.reasons })) - ); - if (stale.length > 0) { - console.log(JSON.stringify(stale)); - } - } catch {} - ") - - if [ -z "$NEEDS_REVIEW" ]; then - echo "has_stale=false" >> "$GITHUB_OUTPUT" - else - echo "has_stale=true" >> "$GITHUB_OUTPUT" - # Escape for multiline GH output - EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) - echo "stale_json<<$EOF" >> "$GITHUB_OUTPUT" - echo "$NEEDS_REVIEW" >> "$GITHUB_OUTPUT" - echo "$EOF" >> "$GITHUB_OUTPUT" - fi - - - name: Build summary - if: steps.stale.outputs.has_stale == 'true' - id: summary - run: | - node -e " - const stale = JSON.parse(process.env.STALE_JSON); - const lines = stale.map(s => - '- **' + s.skill + '** (' + s.library + '): ' + s.reasons.join(', ') - ); - const summary = lines.join('\n'); - - const prompt = [ - 'Review and update the following stale intent skills for {{PACKAGE_NAME}}:', - '', - ...stale.map(s => '- ' + s.skill + ': ' + s.reasons.join(', ')), - '', - 'For each stale skill:', - '1. Read the current SKILL.md file', - '2. Check what changed in the library since the skill was last updated', - '3. Update the skill content to reflect current APIs and behavior', - '4. Run \`npx @tanstack/intent validate\` to verify the updated skill', - ].join('\n'); - - // Write outputs - const fs = require('fs'); - const env = fs.readFileSync(process.env.GITHUB_OUTPUT, 'utf8'); - const eof = require('crypto').randomBytes(15).toString('base64'); - fs.appendFileSync(process.env.GITHUB_OUTPUT, - 'summary<<' + eof + '\n' + summary + '\n' + eof + '\n' + - 'prompt<<' + eof + '\n' + prompt + '\n' + eof + '\n' - ); - " - env: - STALE_JSON: ${{ steps.stale.outputs.stale_json }} - - - name: Open review PR - if: steps.stale.outputs.has_stale == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - VERSION="${{ github.event.release.tag_name || 'manual' }}" - BRANCH="skills/review-${VERSION}" - - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git checkout -b "$BRANCH" - git commit --allow-empty -m "chore: review stale skills for ${VERSION}" - git push origin "$BRANCH" - - gh pr create \ - --title "Review stale skills (${VERSION})" \ - --body "$(cat <<'PREOF' - ## Stale Skills Detected - - The following skills may need updates after the latest release: - - ${{ steps.summary.outputs.summary }} - - --- - - ### Update Prompt - - Paste this into your coding agent (Claude Code, Cursor, etc.): - - ~~~ - ${{ steps.summary.outputs.prompt }} - ~~~ - - PREOF - )" \ - --head "$BRANCH" \ - --base main +# check-skills.yml — Drop this into your library repo's .github/workflows/ +# +# Checks for stale intent skills after a release and opens a review PR +# if any skills need attention. The PR body includes a prompt you can +# paste into Claude Code, Cursor, or any coding agent to update them. +# +# Triggers: new release published, or manual workflow_dispatch. +# +# Template variables (replaced by `intent setup`): +# {{PACKAGE_NAME}} — e.g. @tanstack/query + +name: Check Skills + +on: + release: + types: [published] + workflow_dispatch: {} + +permissions: + contents: write + pull-requests: write + +jobs: + check: + name: Check for stale skills + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install intent + run: npm install {{PACKAGE_NAME}} + + - name: Check staleness + id: stale + run: | + OUTPUT=$(npx @tanstack/intent stale --json 2>&1) || true + echo "$OUTPUT" + + # Check if any skills need review + NEEDS_REVIEW=$(echo "$OUTPUT" | node -e " + const input = require('fs').readFileSync('/dev/stdin','utf8'); + try { + const reports = JSON.parse(input); + const stale = reports.flatMap(r => + r.skills.filter(s => s.needsReview).map(s => ({ library: r.library, skill: s.name, reasons: s.reasons })) + ); + if (stale.length > 0) { + console.log(JSON.stringify(stale)); + } + } catch {} + ") + + if [ -z "$NEEDS_REVIEW" ]; then + echo "has_stale=false" >> "$GITHUB_OUTPUT" + else + echo "has_stale=true" >> "$GITHUB_OUTPUT" + # Escape for multiline GH output + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + echo "stale_json<<$EOF" >> "$GITHUB_OUTPUT" + echo "$NEEDS_REVIEW" >> "$GITHUB_OUTPUT" + echo "$EOF" >> "$GITHUB_OUTPUT" + fi + + - name: Build summary + if: steps.stale.outputs.has_stale == 'true' + id: summary + run: | + node -e " + const stale = JSON.parse(process.env.STALE_JSON); + const lines = stale.map(s => + '- **' + s.skill + '** (' + s.library + '): ' + s.reasons.join(', ') + ); + const summary = lines.join('\n'); + + const prompt = [ + 'Review and update the following stale intent skills for {{PACKAGE_NAME}}:', + '', + ...stale.map(s => '- ' + s.skill + ': ' + s.reasons.join(', ')), + '', + 'For each stale skill:', + '1. Read the current SKILL.md file', + '2. Check what changed in the library since the skill was last updated', + '3. Update the skill content to reflect current APIs and behavior', + '4. Run \`npx @tanstack/intent validate\` to verify the updated skill', + ].join('\n'); + + // Write outputs + const fs = require('fs'); + const env = fs.readFileSync(process.env.GITHUB_OUTPUT, 'utf8'); + const eof = require('crypto').randomBytes(15).toString('base64'); + fs.appendFileSync(process.env.GITHUB_OUTPUT, + 'summary<<' + eof + '\n' + summary + '\n' + eof + '\n' + + 'prompt<<' + eof + '\n' + prompt + '\n' + eof + '\n' + ); + " + env: + STALE_JSON: ${{ steps.stale.outputs.stale_json }} + + - name: Open review PR + if: steps.stale.outputs.has_stale == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + VERSION="${{ github.event.release.tag_name || 'manual' }}" + BRANCH="skills/review-${VERSION}" + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git checkout -b "$BRANCH" + git commit --allow-empty -m "chore: review stale skills for ${VERSION}" + git push origin "$BRANCH" + + gh pr create \ + --title "Review stale skills (${VERSION})" \ + --body "$(cat <<'PREOF' + ## Stale Skills Detected + + The following skills may need updates after the latest release: + + ${{ steps.summary.outputs.summary }} + + --- + + ### Update Prompt + + Paste this into your coding agent (Claude Code, Cursor, etc.): + + ~~~ + ${{ steps.summary.outputs.prompt }} + ~~~ + + PREOF + )" \ + --head "$BRANCH" \ + --base main diff --git a/packages/intent/meta/templates/workflows/notify-playbooks.yml b/packages/intent/meta/templates/workflows/notify-playbooks.yml index cc186856..edc4b5b2 100644 --- a/packages/intent/meta/templates/workflows/notify-playbooks.yml +++ b/packages/intent/meta/templates/workflows/notify-playbooks.yml @@ -1,52 +1,52 @@ -# notify-intent.yml — Drop this into your library repo's .github/workflows/ -# -# Fires a repository_dispatch event to TanStack/intent whenever docs or -# source files change on merge to main. This triggers the skill staleness -# check workflow in the intent repo. -# -# Requirements: -# - A fine-grained PAT with contents:write on TanStack/intent stored -# as the INTENT_NOTIFY_TOKEN repository secret. -# -# Template variables (replaced by `intent setup`): -# {{PACKAGE_NAME}} — e.g. @tanstack/query -# {{DOCS_PATH}} — e.g. docs/** -# {{SRC_PATH}} — e.g. packages/query-core/src/** - -name: Notify Intent - -on: - push: - branches: [main] - paths: - - '{{DOCS_PATH}}' - - '{{SRC_PATH}}' - -jobs: - notify: - name: Notify TanStack Intent - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - - name: Collect changed files - id: changes - run: | - FILES=$(git diff --name-only HEAD~1 HEAD | jq -R -s -c 'split("\n") | map(select(length > 0))') - echo "files=$FILES" >> "$GITHUB_OUTPUT" - - - name: Dispatch to intent repo - uses: peter-evans/repository-dispatch@v3 - with: - token: ${{ secrets.INTENT_NOTIFY_TOKEN }} - repository: TanStack/intent - event-type: skill-check - client-payload: | - { - "package": "{{PACKAGE_NAME}}", - "sha": "${{ github.sha }}", - "changed_files": ${{ steps.changes.outputs.files }} - } +# notify-intent.yml — Drop this into your library repo's .github/workflows/ +# +# Fires a repository_dispatch event to TanStack/intent whenever docs or +# source files change on merge to main. This triggers the skill staleness +# check workflow in the intent repo. +# +# Requirements: +# - A fine-grained PAT with contents:write on TanStack/intent stored +# as the INTENT_NOTIFY_TOKEN repository secret. +# +# Template variables (replaced by `intent setup`): +# {{PACKAGE_NAME}} — e.g. @tanstack/query +# {{DOCS_PATH}} — e.g. docs/** +# {{SRC_PATH}} — e.g. packages/query-core/src/** + +name: Notify Intent + +on: + push: + branches: [main] + paths: + - '{{DOCS_PATH}}' + - '{{SRC_PATH}}' + +jobs: + notify: + name: Notify TanStack Intent + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Collect changed files + id: changes + run: | + FILES=$(git diff --name-only HEAD~1 HEAD | jq -R -s -c 'split("\n") | map(select(length > 0))') + echo "files=$FILES" >> "$GITHUB_OUTPUT" + + - name: Dispatch to intent repo + uses: peter-evans/repository-dispatch@v3 + with: + token: ${{ secrets.INTENT_NOTIFY_TOKEN }} + repository: TanStack/intent + event-type: skill-check + client-payload: | + { + "package": "{{PACKAGE_NAME}}", + "sha": "${{ github.sha }}", + "changed_files": ${{ steps.changes.outputs.files }} + } diff --git a/packages/intent/meta/templates/workflows/validate-skills.yml b/packages/intent/meta/templates/workflows/validate-skills.yml index 8f39716a..ac6a1eae 100644 --- a/packages/intent/meta/templates/workflows/validate-skills.yml +++ b/packages/intent/meta/templates/workflows/validate-skills.yml @@ -1,52 +1,52 @@ -# validate-skills.yml — Drop this into your library repo's .github/workflows/ -# -# Validates skill files on PRs that touch the skills/ directory. -# Ensures frontmatter is correct, names match paths, and files stay under -# the 500-line limit. - -name: Validate Skills - -on: - pull_request: - paths: - - 'skills/**' - - '**/skills/**' - -jobs: - validate: - name: Validate skill files - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Install intent CLI - run: npm install -g @tanstack/intent - - - name: Find and validate skills - run: | - # Find all directories containing SKILL.md files - SKILLS_DIR="" - if [ -d "skills" ]; then - SKILLS_DIR="skills" - elif [ -d "packages" ]; then - # Monorepo — find skills/ under packages - for dir in packages/*/skills; do - if [ -d "$dir" ]; then - echo "Validating $dir..." - intent validate "$dir" - fi - done - exit 0 - fi - - if [ -n "$SKILLS_DIR" ]; then - intent validate "$SKILLS_DIR" - else - echo "No skills/ directory found — skipping validation." - fi +# validate-skills.yml — Drop this into your library repo's .github/workflows/ +# +# Validates skill files on PRs that touch the skills/ directory. +# Ensures frontmatter is correct, names match paths, and files stay under +# the 500-line limit. + +name: Validate Skills + +on: + pull_request: + paths: + - 'skills/**' + - '**/skills/**' + +jobs: + validate: + name: Validate skill files + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install intent CLI + run: npm install -g @tanstack/intent + + - name: Find and validate skills + run: | + # Find all directories containing SKILL.md files + SKILLS_DIR="" + if [ -d "skills" ]; then + SKILLS_DIR="skills" + elif [ -d "packages" ]; then + # Monorepo — find skills/ under packages + for dir in packages/*/skills; do + if [ -d "$dir" ]; then + echo "Validating $dir..." + intent validate "$dir" + fi + done + exit 0 + fi + + if [ -n "$SKILLS_DIR" ]; then + intent validate "$SKILLS_DIR" + else + echo "No skills/ directory found — skipping validation." + fi diff --git a/packages/intent/meta/tree-generator/SKILL.md b/packages/intent/meta/tree-generator/SKILL.md index 1954a705..6ab598e2 100644 --- a/packages/intent/meta/tree-generator/SKILL.md +++ b/packages/intent/meta/tree-generator/SKILL.md @@ -1,3 +1,897 @@ +<<<<<<< HEAD:packages/intent/meta/tree-generator/SKILL.md +--- +name: skill-tree-generator +description: > + Generate, update, and version a complete skill tree (collection of SKILL.md + files) for any JavaScript or TypeScript library. Produces core skills + (framework-agnostic) and framework skills (React, Solid, Vue bindings) + with dependency linking. Activate when producing skill files from a domain + map, updating existing skills after a library version change, or auditing + skill accuracy. Takes domain_map.yaml and skill_spec.md from + skill-domain-discovery as primary inputs. +metadata: + version: '3.0' + category: meta-tooling + input_artifacts: + - skills/_artifacts/domain_map.yaml + - skills/_artifacts/skill_spec.md + output_artifacts: + - skills/_artifacts/skill_tree.yaml + skills: + - skill-domain-discovery +--- + +# Skill Tree Generator + +You produce and maintain a tree of SKILL.md files for a library. Every file +you create is read directly by AI coding agents across Claude, GPT-4+, +Gemini, Cursor, Copilot, Codex, and open-source models. Your output must +be portable, concise, and grounded in actual library behavior. + +### Skill types + +Every skill has a `type` field in its frontmatter. Valid types: + +| Type | Purpose | Example | +| ------------- | ---------------------------------------------------------- | ------------------------- | +| `core` | Framework-agnostic concepts, configuration, patterns | `db-core` | +| `sub-skill` | A focused sub-topic within a core or framework skill | `db-core/live-queries` | +| `framework` | Framework-specific bindings, hooks, components | `react-db` | +| `lifecycle` | Cross-cutting developer journey (getting started, go-live) | `electric-quickstart` | +| `composition` | Integration between two or more libraries | `electric-drizzle` | +| `security` | Audit checklist or security validation | `electric-security-check` | + +Agents discover skills via `tanstack intent list` and read them directly +from `node_modules`. Framework skills declare a `requires` dependency on +their core skill so agents load them in the right order. + +There are two workflows. Detect which applies. + +**Workflow A — Generate:** Build a complete skill tree from a domain map. +**Workflow B — Update:** Diff a library version change and update skills. + +--- + +## Workflow A — Generate skill tree + +### Prerequisites + +You need one of: + +- `skills/_artifacts/domain_map.yaml` and `skills/_artifacts/skill_spec.md` + from skill-domain-discovery +- Raw library documentation and source code (run a compressed domain + discovery first) + +If starting from raw docs without a domain map, run a compressed +discovery. This produces lower-fidelity output than the full +skill-domain-discovery skill — prefer running that when time permits. + +1. Build a concept inventory (every export, config key, constraint, warning) +2. Group into capability domains using work-oriented names (let library complexity drive the count — 2–3 for focused libraries, more for large frameworks) +3. Enumerate 10–20 task-focused skills from the intersection of domains + and developer tasks +4. Extract 3+ failure modes per skill (plausible, silent, grounded) +5. Proceed to Step 1 below + +### Scaffold flow output + +If the maintainer uses a custom skills root, replace `skills/` in the paths +below with their chosen directory. + +For the scaffold workflow, produce a single artifact before writing any +SKILL.md files: + +- `skills/_artifacts/skill_tree.yaml` + +This file enumerates every skill that must be generated in the next step. +Do not write SKILL.md files yet unless explicitly asked. + +Use this format: + +```yaml +# skills/_artifacts/skill_tree.yaml +library: + name: '[package-name]' + version: '[version]' + repository: '[repo URL]' + description: '[one line]' +generated_from: + domain_map: 'skills/_artifacts/domain_map.yaml' + skill_spec: 'skills/_artifacts/skill_spec.md' +generated_at: '[ISO date]' + +skills: + - name: '[task-focused skill name]' + slug: '[kebab-case]' + type: 'core | sub-skill | framework | lifecycle | composition | security' + domain: '[domain slug]' + path: 'skills/[path]/SKILL.md' + package: '[package directory, e.g. packages/client]' # monorepo only — which package this skill belongs to + description: '[1–2 sentence agent-facing routing key]' + requires: + - '[other skill slugs]' # omit if none + sources: + - '[Owner/repo]:docs/[path].md' + - '[Owner/repo]:src/[path].ts' + subsystems: + - '[adapter/backend name]' # omit if none + references: + - 'references/[file].md' # omit if none +``` + +**Monorepo layout:** For monorepos, each skill's `path` is relative to its +package directory (e.g. `packages/client/skills/core/SKILL.md`). Set the +`package` field so generate-skill knows where to write the file. The domain +map artifacts stay at the repo root. + +### Minimal library fast path + +If the domain map contains **fewer than 5 skills** and no framework +adapter packages, skip the core overview + sub-skill registry pattern. +Instead: + +- Use **flat structure** — each skill gets its own `skills/[skill-name]/SKILL.md` +- **No router skill** — the intent CLI `list` command is sufficient for discovery +- **No core overview skill** — go directly to individual skill files +- Each skill is type `core` (not `sub-skill`) and stands alone without + a parent registry +- Skip Step 2 (core overview) and Step 3 (sub-skills) — go directly to + writing individual skills as standalone core skills using Step 3's body + format + +This avoids unnecessary scaffolding for focused libraries where the +overhead of a hierarchical skill tree exceeds the navigation benefit. + +### Step 1 — Plan the file tree + +From the domain map, each entry in the `skills` list becomes a SKILL.md +file. The `type` field on each skill (`core`, `framework`, `lifecycle`, +`composition`) determines where it goes. Determine the file tree: + +**Core vs framework decision:** + +| Content | Goes in... | +| ---------------------------------------------- | ---------- | +| Mental models, concepts, lifecycle | Core | +| Configuration options and their effects | Core | +| Type system, generics, inference | Core | +| Common mistakes that apply to all frameworks | Core | +| Hooks (`useX`, `createX`) | Framework | +| Components (``, ``) | Framework | +| Provider setup and wiring | Framework | +| SSR/hydration patterns specific to a framework | Framework | +| Framework-specific gotchas | Framework | + +If a library has no framework adapters (e.g. Store, DB), produce only +core skills. + +**Framework-integration domain decomposition:** If the domain map from +skill-domain-discovery contains a single "Framework Integration" domain +and the library has separate framework adapter packages, decompose it +into per-framework skills co-located with each adapter package. Do not +produce a single monolithic framework-integration skill that covers +React, Vue, Solid, etc. in one file. + +**Adapter-heavy domains:** When a domain covers multiple backends or +adapters with distinct config interfaces (e.g. 5 sync adapters, 3 +database drivers), keep one SKILL.md for the shared patterns but +produce one reference file per adapter with its specific config, +setup, and gotchas. The SKILL.md covers what's common; each +`references/[adapter].md` covers what's unique. + +**Flat vs nested structure:** + +Choose the structure that matches how the domain map's skills are shaped. + +Use **nested** (`[lib]-core/[domain]/SKILL.md`) when: + +- Developer tasks cluster cleanly into 3–5 conceptual domains +- The library has a clear core + framework adapter split +- Skills build on each other in a layered way + +Use **flat** (`skills/[skill-name]/SKILL.md`) when: + +- Developer tasks are task-focused and don't nest into domains +- The domain discovery process recommended task-focused skills +- Skills map 1:1 to distinct developer intents with minimal overlap + +Both are valid. The domain map's `type` field and structure will signal +which fits. When in doubt, prefer flat — it's simpler and each skill +is independently discoverable. + +**Nested structure:** + +``` +skills/ +├── [lib]-core/ # Core skill for the library +│ ├── SKILL.md # Core overview + sub-skill registry +│ ├── [domain-1]/ +│ │ └── SKILL.md # Core sub-skill +│ ├── [domain-2]/ +│ │ └── SKILL.md +│ └── references/ # Optional overflow content +│ └── options.md +├── react-[lib]/ # React framework skill +│ ├── SKILL.md # React overview + sub-skill registry +│ ├── [domain-1]/ +│ │ └── SKILL.md # React-specific sub-skill +│ └── references/ +├── solid-[lib]/ # Solid framework skill (if applicable) +│ └── SKILL.md +├── vue-[lib]/ # Vue framework skill (if applicable) +│ └── SKILL.md +``` + +**Flat structure:** + +``` +skills/ +├── [lib]-shapes/ # Task-focused skill +│ ├── SKILL.md +│ └── references/ +│ └── shape-options.md +├── [lib]-auth/ # Another task skill +│ └── SKILL.md +├── [lib]-proxy/ +│ └── SKILL.md +├── [lib]-quickstart/ # Lifecycle skill +│ └── SKILL.md +├── [lib]-go-live/ # Lifecycle skill +│ └── SKILL.md +├── [lib]-drizzle/ # Composition skill +│ └── SKILL.md +``` + +**Router skill:** A router skill (lightweight entry point with a decision +table) is optional. If the intent CLI provides `list` and `show` +commands, agents can discover skills directly without a router. Only +create a router skill if the skill set is large enough (15+) that +browsing the list is insufficient, or if the nested structure needs +an entry point to guide agents to the right sub-skill. Libraries with +fewer than 5 skills should never have a router skill. + +**Source repository layout for npm distribution:** + +Skills must ship with their respective packages so they're available in +`node_modules` after install. In a monorepo, co-locate skills with the +package they document: + +``` +packages/ +├── [lib]/ # Core package +│ ├── src/ +│ ├── skills/ # Core skills live here +│ │ ├── [lib]-core/ +│ │ │ ├── SKILL.md +│ │ │ └── [domain]/SKILL.md +│ │ └── compositions/ # Composition skills with co-used libs +│ └── package.json # Add "skills" to files array +├── react-[lib]/ # React adapter package +│ ├── src/ +│ ├── skills/ # React framework skills live here +│ │ └── react-[lib]/ +│ │ └── SKILL.md +│ └── package.json # Add "skills" to files array +``` + +Add `"skills"` to each package's `files` array in `package.json` so +skill files are included in the published npm tarball: + +```json +{ + "files": ["dist", "src", "skills"] +} +``` + +### Step 2 — Write the core skill + +The core skill is the foundational overview for the library. It covers +framework-agnostic concepts and contains the sub-skill registry. + +**Frontmatter:** + +```yaml +--- +name: [lib]-core +description: > + [1–3 sentences. What this library does and the framework-agnostic + concepts it provides. Pack with keywords: function names, config + options, concepts. This is a routing key, not a human summary.] +type: core +library: [lib] +library_version: "[version this targets]" +--- +``` + +**Body template:** + +```markdown +# [Library Name] — Core Concepts + +[One paragraph: what this library is, what problem it solves. Factual, +not promotional. Framework-agnostic.] + +## Sub-Skills + +| Need to... | Read | +| ---------- | ------------------------------ | +| [task 1] | [lib]-core/[domain-1]/SKILL.md | +| [task 2] | [lib]-core/[domain-2]/SKILL.md | + +## Quick Decision Tree + +- Setting up for the first time? → [lib]-core/[setup-domain] +- Working with [concept]? → [lib]-core/[concept-domain] +- Debugging [issue]? → [lib]-core/[domain] § Common Mistakes + +## Version + +Targets [library] v[X.Y.Z]. +``` + +### Step 3 — Write core sub-skills + +One SKILL.md per domain. Follow this structure exactly. + +**Frontmatter:** + +```yaml +--- +name: [lib]-core/[domain-slug] +description: > + [1–3 sentences. What this domain covers AND when to load it. Name + specific functions, options, or APIs. Dense routing key.] +type: sub-skill +library: [lib] +library_version: "[version]" +sources: + - "[repo]:docs/[path].md" + - "[repo]:src/[path].ts" +--- +``` + +**Body sections — in this order:** + +**1. Setup** + +Minimum working example for this domain. + +- Use the library's core API, not framework-specific hooks +- Real package imports with exact names +- No `// ...` or `[your code here]` — complete and copy-pasteable +- If a concept is better explained with a framework hook, reference the + framework skill: "For React usage, see `react-[lib]/SKILL.md`" + +**2. Core Patterns** + +2–4 patterns. For each: + +- One-line heading: what it accomplishes +- Complete code block using core API +- One sentence of explanation only if not self-explanatory +- No framework-specific code — use core abstractions + +**3. Common Mistakes** + +Each `failure_mode` entry from the domain map becomes a Common Mistake +entry in the SKILL file. Minimum 3 entries. Complex domains target 5–6. + +**Cross-skill failure modes:** The domain map may contain failure modes +with a `skills` list naming multiple skill slugs. Write these into +every SKILL file whose skill is listed. A developer loading the SSR +skill and a developer loading the state management skill both need to +see "stale state during hydration" — the same advice must appear in +both files. Do not deduplicate across skills at the cost of coverage. + +Format: + +````markdown +### [PRIORITY] [What goes wrong — 5–8 word phrase] + +Wrong: + +```[lang] +// code that looks correct but isn't +``` +```` + +Correct: + +```[lang] +// code that works +``` + +[One sentence: the specific mechanism by which the wrong version fails.] + +Source: [doc page or source file:line] + +```` + +Priority levels: +- **CRITICAL** — Breaks in production. Security risk or data loss. +- **HIGH** — Incorrect behavior under common conditions. +- **MEDIUM** — Incorrect under specific conditions or edge cases. + +Every mistake must be plausible (an agent would generate it), silent +(no immediate crash), and grounded (traceable to doc or source). + +**Failure mode status from domain map:** The domain map may include a +`status` field on failure modes. Handle as follows: +- `active` — Include as a normal Common Mistake entry +- `fixed-but-legacy-risk` — Include with a note: "Fixed in v[X] but + agents trained on older code may still generate this pattern" +- `removed` — Do not include. The bug is fixed and the pattern is no + longer relevant. + +**4. References** (only when needed) + +```markdown +## References + +- [Complete option reference](references/options.md) +```` + +Create reference files when any of these apply — not just length overflow: + +- **Length:** The skill would exceed 500 lines without them +- **Multiple subsystems:** The domain covers 3+ independent backends, + adapters, or providers with distinct config interfaces. Create one + reference file per subsystem (e.g. `references/electric-adapter.md`, + `references/query-adapter.md`) +- **Dense API surface:** A topic has >10 distinct API patterns, operators, + or option shapes that agents need for implementation. Move the full + reference to `references/` and keep only the most common 2–3 in the + SKILL.md +- **Deep validation/schema patterns:** If the library has schema + validation, type transforms (TInput/TOutput), or similar deep + configuration surfaces, give them a dedicated reference file even if + they technically fit in the parent skill + +### Step 4 — Write framework skills + +Framework skills build on their core skill. They cover only what is +specific to the framework — hooks, components, providers, and +framework-specific patterns and mistakes. + +**Frontmatter:** + +```yaml +--- +name: react-[lib] +description: > + [1–3 sentences. React-specific bindings for [library]. Name the hooks, + components, and providers. Mention React-specific patterns like SSR + hydration if applicable.] +type: framework +library: [lib] +framework: react +library_version: "[version]" +requires: + - [lib]-core +--- +``` + +**Body template:** + +```markdown +This skill builds on [lib]-core. Read [lib]-core first for foundational +concepts before applying React-specific patterns. + +# [Library Name] — React + +## Setup + +[React-specific setup: provider, hook wiring, app entry point] + +## Hooks and Components + +[React hooks and components with complete examples] + +## React-Specific Patterns + +[Patterns that only apply in React: concurrent features, Suspense +integration, SSR/hydration, etc.] + +## Common Mistakes + +[Only React-specific mistakes. Do not repeat core mistakes. Examples: +calling hooks outside provider, missing Suspense boundary, hydration +mismatch, etc.] +``` + +**Framework sub-skills** follow the same pattern as core sub-skills but +with the framework frontmatter: + +```yaml +--- +name: react-[lib]/[domain-slug] +description: > + [React-specific description for this domain.] +type: sub-skill +library: [lib] +framework: react +library_version: "[version]" +requires: + - [lib]-core + - [lib]-core/[domain-slug] +--- + +This skill builds on [lib]-core/[domain-slug]. Read the core skill first. +``` + +### Step 5 — Write cross-domain tension notes + +The domain map may contain a `tensions` section listing design conflicts +between domains. For each tension, add a brief note to the Common +Mistakes section of every SKILL file whose domain is involved. Format: + +```markdown +### HIGH Tension: [short phrase] + +This domain's patterns conflict with [other domain]. [One sentence +describing the pull.] Agents optimizing for [this domain's goal] +tend to [specific mistake] because they don't account for [other +domain's constraint]. + +See also: [lib]-core/[other-domain]/SKILL.md § Common Mistakes +``` + +The cross-reference ensures agents that load one skill are pointed +toward the related skill where the other side of the tension lives. + +Also check the domain map's `cross_references` section for non-tension +relationships between skills. For each cross-reference, add a "See also" +line at the end of the relevant skill's body: + +```markdown +See also: [other-skill]/SKILL.md — [reason] +``` + +### Step 6 — Write composition skills (if applicable) + +Use the `compositions` entries from `domain_map.yaml` (populated during +skill-domain-discovery Phase 3h) to identify which composition skills +to produce. + +Composition skills cover how two or more libraries work together. These +are framework-specific by default (the integration patterns depend on +framework hooks and providers). + +**Frontmatter:** + +```yaml +--- +name: compositions/[lib-a]-[lib-b] +description: > + [How lib-a and lib-b wire together. Name the specific integration + points: functions, hooks, patterns.] +type: composition +library_version: "[version of primary lib]" +requires: + - [lib-a]-core + - react-[lib-a] + - [lib-b]-core + - react-[lib-b] +--- + +This skill requires familiarity with both [lib-a] and [lib-b]. +Read their core and framework skills first. +``` + +**Body structure:** + +1. **Integration Setup** — How to wire the two libraries together +2. **Core Integration Patterns** — 2–4 patterns showing them working in concert +3. **Common Mistakes** — Mistakes that only occur at the integration boundary + +Do not duplicate content from either library's individual skills. Focus +exclusively on the seam between them. + +### Step 7 — Write checklist/audit skills (where applicable) + +Some skills don't fit the standard body structure (Setup → Core Patterns +→ Common Mistakes). Security, go-live, and some lifecycle skills are +audit-oriented — the agent runs through a checklist to verify correctness +rather than learning patterns. Use the alternative body structure below +for these skill types. + +**When to use the checklist body:** + +- `security` type skills — pre-deploy security validation +- `lifecycle` type skills focused on verification (go-live, migration) +- Any skill where the primary action is "check these things" not "learn + these patterns" + +**Frontmatter:** + +```yaml +--- +name: react-[lib]/security +description: > + Go-live security validation for [library]. Checks [specific concerns]. +type: security +library: [lib] +framework: react +library_version: '[version]' +requires: + - react-[lib] +--- +``` + +**Alternative body template (checklist/audit):** + +````markdown +# [Library Name] — [Security | Go-Live | Migration] Checklist + +Run through each section before [deploying | releasing | migrating]. + +## [Category 1] Checks + +### Check: [what to verify] + +Expected: + +```[lang] +// correct configuration or code +``` +```` + +Fail condition: [what indicates this check failed] +Fix: [one-line remediation] + +### Check: [what to verify] + +[same structure] + +## [Category 2] Checks + +[same structure] + +## Common Security Mistakes + +[Wrong/correct pairs specific to this library, same format as +Common Mistakes in standard skills] + +## Pre-Deploy Summary + +- [ ] [Verification 1] +- [ ] [Verification 2] +- [ ] [Verification 3] + +```` + +The key differences from the standard body: +- No "Setup" section — the agent already has the app running +- Checks replace "Core Patterns" — each check is a verification, not a + teaching pattern +- The summary checklist at the end gives agents a quick pass/fail list +- Common Mistakes section is still present for wrong/correct pairs + +### Step 8 — Validate the complete tree + +Run every check before outputting. Fix any failures before proceeding. + +| Check | Rule | +|-------|------| +| Every skill from domain_map has a SKILL.md | No orphaned skills | +| Core/framework split is clean | No framework hooks in core skills | +| Every framework skill has `requires` | Links to its core skill | +| Framework skill opens with dependency note | "builds on [core]" prose line | +| Every skill under 500 lines | Move excess to references/ | +| Every code block has real imports | Exact package name, correct adapter | +| No concept explanations | No "TypeScript is...", no "React hooks are..." | +| No marketing prose | First body line is heading or dependency note | +| Every code block is complete | Works without modification when pasted | +| Common Mistakes are silent | Not obvious compile errors | +| Common Mistakes are library-specific | Not generic TS/React mistakes | +| Common Mistakes are sourced | Every mistake traceable to doc or source | +| Core skills reference framework skills | "For React usage, see..." | +| Framework skills don't repeat core content | Only framework-specific | +| Composition skills don't repeat individual skills | Only the seam | +| `name` matches directory path | `router-core/search-params` → `router-core/search-params/SKILL.md` | +| `sources` filled in sub-skills | At least one repo:path per sub-skill | +| Cross-skill failures in all relevant files | Failure modes with multiple `skills` appear in each listed SKILL.md | +| Tensions noted in affected skills | Each tension has notes in all involved domain skills | +| Framework domains decomposed per-package | No single skill covering multiple framework adapters | +| Adapter-heavy domains have references | 3+ adapters/backends → one reference file per adapter | +| Dense API surfaces in references | >10 distinct patterns → reference file, not inline | +| Checklist skills use audit body | Security/go-live skills use checklist template, not Setup → Core Patterns → Common Mistakes | + +--- + +## Workflow B — Update existing skills + +### Trigger conditions + +Run when: +- The library has released a new version +- A maintainer reports skills produce outdated code +- A changelog or migration guide has been published since skill creation +- Feedback reports indicate skill content is inaccurate + +### Step 1 — Detect staleness + +Compare each skill's `library_version` against the current library version. + +1. Read changelog entries between the two versions +2. Read migration guide (if one exists) +3. For each skill, check if its `sources` files have changed + +Produce a staleness report: + +```yaml +# staleness_report.yaml +library: "[name]" +library_version_in_skills: "[old]" +library_version_current: "[new]" + +stale_skills: + - skill: "[skill name]" + reason: "[what changed]" + severity: "[BREAKING | DEPRECATION | BEHAVIORAL | ADDITIVE]" + changelog_entry: "[relevant entry]" + affected_sections: + - "[Setup | Core Patterns | Common Mistakes]" + +current_skills: + - skill: "[skill name]" + reason: "[no changes affect this domain]" +```` + +### Step 2 — Update stale skills + +**BREAKING changes:** + +1. Old pattern becomes a new Common Mistake entry (wrong/correct pair) +2. Update Setup if initialization changed +3. Update Core Patterns if idiomatic approach changed +4. Bump `library_version` in frontmatter +5. Check both core AND framework skills — breaking changes may affect both + +**DEPRECATION changes:** + +1. Add Common Mistake: deprecated API as wrong, replacement as correct +2. Update Core Patterns to use non-deprecated API +3. Bump `library_version` + +**BEHAVIORAL changes:** + +1. Default value changed → add Common Mistake entry +2. Type signature more restrictive → add Common Mistake entry +3. Update affected code blocks +4. Bump `library_version` + +**ADDITIVE changes:** + +1. Evaluate if new feature belongs in existing domain or needs a new skill +2. If existing: add to Core Patterns or references/ +3. If new skill needed: create it and update the parent skill's sub-skill + registry +4. Bump `library_version` + +### Step 3 — Produce a changelog entry + +```markdown +## [date] + +### Updated for [library] v[new version] + +**Breaking changes:** + +- [skill name]: [what changed and why] + +**Deprecation updates:** + +- [skill name]: [old API] → [new API] + +**New skills:** + +- [skill name]: [what it covers] +``` + +--- + +## Constraints — verify for every file + +| Check | Rule | +| ------------------------------------------- | ----------------------------------------------------------------------------------- | +| Under 500 lines per SKILL.md | Move excess to references/; also create references for content depth | +| Real imports in every code block | Exact package, correct adapter | +| No external concept explanations | No "TypeScript is...", no "React hooks are..." — library-specific concepts are fine | +| No marketing prose | First body line is heading, code, or dependency note | +| Complete code blocks | Every block works without modification | +| Common Mistakes are silent | Not obvious compile errors | +| Common Mistakes are library-specific | Not generic TS/React mistakes | +| Common Mistakes are sourced | Traceable to doc or source | +| Core skills are framework-agnostic | No hooks, no components, no providers | +| Framework skills have `requires` | Lists core dependency | +| Framework skills open with dependency note | First prose line references core | +| Composition skills require all dependencies | Lists all core + framework skills | +| `name` matches directory | `router-core/search-params` → file at that path | +| `library_version` in every frontmatter | Which version the skill targets | +| Cross-skill failures duplicated | Each listed skill gets the failure mode | +| Tensions cross-referenced | Tension notes in each involved skill point to the other | +| Skills ship with packages | `"skills"` in package.json `files` array | +| Checklist skills use audit template | Security/go-live skills use checklist body, not standard body | + +--- + +## Cross-model compatibility + +Output is consumed by all major AI coding agents. To ensure consistency: + +- Markdown with YAML frontmatter — universally parsed +- No XML tags in generated skill content +- Code blocks use triple backticks with language annotation +- Section boundaries use ## headers +- Descriptions are keyword-packed for routing +- Examples show concrete values, never placeholders +- Positive instructions ("Use X") over negative ("Don't use Y") +- Critical info at start or end of sections (not buried in middle) +- Each SKILL.md is self-contained except for declared `requires` + +--- + +## Output order + +When generating a complete skill tree: + +1. Core overview SKILL.md — entry point for the library +2. Core sub-skills in domain order +3. Framework overview SKILL.md for each framework +4. Framework sub-skills +5. Composition skills (if applicable) +6. Security skills (if applicable) +7. references/ files for any skill that needs them +8. CHANGELOG.md entry + +When updating: + +1. staleness_report.yaml +2. Updated SKILL.md files (core then framework) +3. CHANGELOG.md entry + +--- + +## Meta-skill feedback (alpha default) + +After producing the skill tree artifact, update a single Markdown feedback +draft for all three meta skills used in scaffolding. If a draft exists from +Domain Discovery, keep it and fill only the **Tree Generator** section. If +no draft exists, create it using this exact template. + +``` +# Intent Meta Skill Feedback + +## Domain Discovery +- What worked well: +- What was confusing or missing: +- Suggestions for improvement: +- Overall rating: good | mixed | bad + +## Tree Generator +- What worked well: +- What was confusing or missing: +- Suggestions for improvement: +- Overall rating: good | mixed | bad + +## Generate Skill +- What worked well: +- What was confusing or missing: +- Suggestions for improvement: +- Overall rating: good | mixed | bad + +## Context (optional) +- Library: +- Repo: +- Docs: +- Notes: +``` + +Do not submit feedback yet. Carry this draft forward to the generate-skill +step. +======= --- name: skill-tree-generator description: > @@ -40,7 +934,7 @@ Every skill has a `type` field in its frontmatter. Valid types: | `composition` | Integration between two or more libraries | `electric-drizzle` | | `security` | Audit checklist or security validation | `electric-security-check` | -Agents discover skills via `tanstack intent list` and read them directly +Agents discover skills via `tanstack playbook list` and read them directly from `node_modules`. Framework skills declare a `requires` dependency on their core skill so agents load them in the right order. @@ -63,11 +957,16 @@ You need one of: discovery first) If starting from raw docs without a domain map, run a compressed -discovery. This produces lower-fidelity output than the full -skill-domain-discovery skill — prefer running that when time permits. +discovery. **Warning:** This produces significantly lower-fidelity +output than the full skill-domain-discovery skill. The maintainer +interview in domain discovery surfaces implicit knowledge, failure +modes, and prioritization that cannot be inferred from docs alone. +Always prefer running the full discovery when possible. Only use +compressed discovery when the maintainer has explicitly confirmed +they want to skip domain discovery. 1. Build a concept inventory (every export, config key, constraint, warning) -2. Group into capability domains using work-oriented names (let library complexity drive the count — 2–3 for focused libraries, more for large frameworks) +2. Group into 4–7 capability domains using work-oriented names 3. Enumerate 10–20 task-focused skills from the intersection of domains and developer tasks 4. Extract 3+ failure modes per skill (plausible, silent, grounded) @@ -106,8 +1005,10 @@ skills: type: 'core | sub-skill | framework | lifecycle | composition | security' domain: '[domain slug]' path: 'skills/[path]/SKILL.md' - package: '[package directory, e.g. packages/client]' # monorepo only — which package this skill belongs to description: '[1–2 sentence agent-facing routing key]' + packages: # required for monorepo; omit for single-package libraries + - '[package where this skill ships]' + - '[additional package, if skill is relevant to multiple packages]' requires: - '[other skill slugs]' # omit if none sources: @@ -119,34 +1020,22 @@ skills: - 'references/[file].md' # omit if none ``` -**Monorepo layout:** For monorepos, each skill's `path` is relative to its -package directory (e.g. `packages/client/skills/core/SKILL.md`). Set the -`package` field so generate-skill knows where to write the file. The domain -map artifacts stay at the repo root. - -### Minimal library fast path - -If the domain map contains **fewer than 5 skills** and no framework -adapter packages, skip the core overview + sub-skill registry pattern. -Instead: - -- Use **flat structure** — each skill gets its own `skills/[skill-name]/SKILL.md` -- **No router skill** — the intent CLI `list` command is sufficient for discovery -- **No core overview skill** — go directly to individual skill files -- Each skill is type `core` (not `sub-skill`) and stands alone without - a parent registry -- Skip Step 2 (core overview) and Step 3 (sub-skills) — go directly to - writing individual skills as standalone core skills using Step 3's body - format - -This avoids unnecessary scaffolding for focused libraries where the -overhead of a hierarchical skill tree exceeds the navigation benefit. - ### Step 1 — Plan the file tree From the domain map, each entry in the `skills` list becomes a SKILL.md file. The `type` field on each skill (`core`, `framework`, `lifecycle`, -`composition`) determines where it goes. Determine the file tree: +`composition`) determines where it goes. Determine the file tree. + +Present the planned file tree to the maintainer before writing any files. +Include the full `skill_tree.yaml` content and explain any structural +decisions (flat vs nested, which skills get reference files, how +cross-package skills are handled). + +**── STOP ── Wait for the maintainer to review and approve the file tree +before proceeding to Step 2. A bad tree means rewriting every generated +file.** + +Determine the file tree: **Core vs framework decision:** @@ -199,6 +1088,31 @@ Both are valid. The domain map's `type` field and structure will signal which fits. When in doubt, prefer flat — it's simpler and each skill is independently discoverable. +**Monorepo placement:** Skills ship inside each package so they are +available when developers install the package. Each package has its +own `skills/` directory. Cross-package skills live in whichever +package is the primary entry point for that task. For example: + +``` +packages/ +├── react-router/ +│ └── skills/ +│ ├── router-core/ +│ │ ├── SKILL.md +│ │ └── navigation/ +│ │ └── SKILL.md +│ └── react-router/ +│ └── SKILL.md +├── start/ +│ └── skills/ +│ ├── start-core/ +│ │ └── SKILL.md +│ └── start-server-functions/ +│ └── SKILL.md +``` + +The examples below show the `skills/` tree within a single package. + **Nested structure:** ``` @@ -243,12 +1157,11 @@ skills/ ``` **Router skill:** A router skill (lightweight entry point with a decision -table) is optional. If the intent CLI provides `list` and `show` +table) is optional. If the playbook CLI provides `list` and `show` commands, agents can discover skills directly without a router. Only create a router skill if the skill set is large enough (15+) that browsing the list is insufficient, or if the nested structure needs -an entry point to guide agents to the right sub-skill. Libraries with -fewer than 5 skills should never have a router skill. +an entry point to guide agents to the right sub-skill. **Source repository layout for npm distribution:** @@ -539,18 +1452,10 @@ See also: [lib]-core/[other-domain]/SKILL.md § Common Mistakes The cross-reference ensures agents that load one skill are pointed toward the related skill where the other side of the tension lives. -Also check the domain map's `cross_references` section for non-tension -relationships between skills. For each cross-reference, add a "See also" -line at the end of the relevant skill's body: - -```markdown -See also: [other-skill]/SKILL.md — [reason] -``` - ### Step 6 — Write composition skills (if applicable) Use the `compositions` entries from `domain_map.yaml` (populated during -skill-domain-discovery Phase 3h) to identify which composition skills +skill-domain-discovery Phase 2h) to identify which composition skills to produce. Composition skills cover how two or more libraries work together. These @@ -670,6 +1575,11 @@ The key differences from the standard body: ### Step 8 — Validate the complete tree Run every check before outputting. Fix any failures before proceeding. +Present the validation results to the maintainer — list any checks that +required fixes and what was changed. + +**── STOP ── Wait for the maintainer to acknowledge the validation +results before proceeding to the feedback step.** | Check | Rule | |-------|------| @@ -795,6 +1705,8 @@ current_skills: | Check | Rule | | ------------------------------------------- | ----------------------------------------------------------------------------------- | +| **File tree reviewed by maintainer** | Present skill_tree.yaml for approval before writing SKILL.md files | +| **Validation results presented** | Show check results to maintainer before finalizing | | Under 500 lines per SKILL.md | Move excess to references/; also create references for content depth | | Real imports in every code block | Exact package, correct adapter | | No external concept explanations | No "TypeScript is...", no "React hooks are..." — library-specific concepts are fine | @@ -853,15 +1765,20 @@ When updating: --- -## Meta-skill feedback (alpha default) +## Meta-skill feedback (alpha — temporary) + +During the alpha period, collect feedback from the maintainer on the +tree generation process. Ask if they'd like to share what worked well, +what was confusing, or suggestions for improvement. If they decline or +want to move on, that's fine — proceed to the next step. -After producing the skill tree artifact, update a single Markdown feedback +Update the single Markdown feedback draft for all three meta skills used in scaffolding. If a draft exists from Domain Discovery, keep it and fill only the **Tree Generator** section. If no draft exists, create it using this exact template. ``` -# Intent Meta Skill Feedback +# Playbook Meta Skill Feedback ## Domain Discovery - What worked well: @@ -890,3 +1807,4 @@ no draft exists, create it using this exact template. Do not submit feedback yet. Carry this draft forward to the generate-skill step. +>>>>>>> 54555c4 (feat: enhance SKILL.md with clarifications on package ownership and skill generation process):packages/playbooks/meta/tree-generator/SKILL.md diff --git a/packages/intent/package.json b/packages/intent/package.json index eee10b22..88361074 100644 --- a/packages/intent/package.json +++ b/packages/intent/package.json @@ -1,40 +1,40 @@ -{ - "name": "@tanstack/intent", - "version": "0.0.9", - "description": "Ship compositional knowledge for AI coding agents alongside your npm packages", - "license": "MIT", - "type": "module", - "repository": { - "type": "git", - "url": "https://github.com/tanstack/intent" - }, - "exports": { - ".": { - "import": "./dist/index.mjs", - "types": "./dist/index.d.mts" - }, - "./intent-library": { - "import": "./dist/intent-library.mjs" - } - }, - "bin": { - "intent": "dist/cli.mjs", - "intent-library": "dist/intent-library.mjs" - }, - "files": [ - "dist", - "meta" - ], - "dependencies": { - "yaml": "^2.7.0" - }, - "devDependencies": { - "tsdown": "^0.19.0" - }, - "scripts": { - "prepack": "pnpm run build", - "build": "tsdown src/index.ts src/cli.ts src/setup.ts src/intent-library.ts src/library-scanner.ts --format esm --dts", - "test:lib": "vitest run", - "test:types": "tsc --noEmit" - } -} +{ + "name": "@tanstack/intent", + "version": "0.0.9", + "description": "Ship compositional knowledge for AI coding agents alongside your npm packages", + "license": "MIT", + "type": "module", + "repository": { + "type": "git", + "url": "https://github.com/tanstack/intent" + }, + "exports": { + ".": { + "import": "./dist/index.mjs", + "types": "./dist/index.d.mts" + }, + "./intent-library": { + "import": "./dist/intent-library.mjs" + } + }, + "bin": { + "intent": "dist/cli.mjs", + "intent-library": "dist/intent-library.mjs" + }, + "files": [ + "dist", + "meta" + ], + "dependencies": { + "yaml": "^2.7.0" + }, + "devDependencies": { + "tsdown": "^0.19.0" + }, + "scripts": { + "prepack": "pnpm run build", + "build": "tsdown src/index.ts src/cli.ts src/setup.ts src/intent-library.ts src/library-scanner.ts --format esm --dts", + "test:lib": "vitest run", + "test:types": "tsc --noEmit" + } +} diff --git a/packages/intent/src/cli.ts b/packages/intent/src/cli.ts index 3a5fbe87..e95fa9e6 100644 --- a/packages/intent/src/cli.ts +++ b/packages/intent/src/cli.ts @@ -1,550 +1,550 @@ -#!/usr/bin/env node - -import { existsSync, readdirSync, readFileSync } from 'node:fs' -import { dirname, join, relative, sep } from 'node:path' -import { fileURLToPath } from 'node:url' -import { parse as parseYaml } from 'yaml' -import { computeSkillNameWidth, printSkillTree, printTable } from './display.js' -import { scanForIntents } from './scanner.js' -import type { ScanResult } from './types.js' -import { findSkillFiles, parseFrontmatter } from './utils.js' - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -function getMetaDir(): string { - const thisDir = dirname(fileURLToPath(import.meta.url)) - return join(thisDir, '..', 'meta') -} - -// --------------------------------------------------------------------------- -// Commands -// --------------------------------------------------------------------------- - -async function cmdList(args: string[]): Promise { - const jsonOutput = args.includes('--json') - - let result: ScanResult - try { - result = await scanForIntents() - } catch (err) { - console.error((err as Error).message) - process.exit(1) - } - - if (jsonOutput) { - console.log(JSON.stringify(result, null, 2)) - return - } - - if (result.packages.length === 0) { - console.log('No intent-enabled packages found.') - if (result.warnings.length > 0) { - console.log(`\nWarnings:`) - for (const w of result.warnings) console.log(` ⚠ ${w}`) - } - return - } - - const totalSkills = result.packages.reduce( - (sum, p) => sum + p.skills.length, - 0, - ) - console.log( - `\n${result.packages.length} intent-enabled packages, ${totalSkills} skills (${result.packageManager})\n`, - ) - - // Summary table - const rows = result.packages.map((pkg) => [ - pkg.name, - pkg.version, - String(pkg.skills.length), - pkg.intent.requires?.join(', ') || '–', - ]) - printTable(['PACKAGE', 'VERSION', 'SKILLS', 'REQUIRES'], rows) - - // Skills detail - const allSkills = result.packages.map((p) => p.skills) - const nameWidth = computeSkillNameWidth(allSkills) - const showTypes = result.packages.some((p) => p.skills.some((s) => s.type)) - - console.log(`\nSkills:\n`) - for (const pkg of result.packages) { - console.log(` ${pkg.name}`) - printSkillTree(pkg.skills, { nameWidth, showTypes }) - console.log() - } - - console.log(`Feedback:`) - console.log( - ` Submit feedback on skill usage to help maintainers improve the skills.`, - ) - console.log( - ` Load: node_modules/@tanstack/intent/meta/feedback-collection/SKILL.md`, - ) - console.log() - - if (result.warnings.length > 0) { - console.log(`Warnings:`) - for (const w of result.warnings) console.log(` ⚠ ${w}`) - } -} - -function cmdMeta(): void { - const metaDir = getMetaDir() - - if (!existsSync(metaDir)) { - console.error('Meta-skills directory not found.') - process.exit(1) - } - - const entries = readdirSync(metaDir, { withFileTypes: true }) - .filter((e) => e.isDirectory()) - .filter((e) => existsSync(join(metaDir, e.name, 'SKILL.md'))) - - if (entries.length === 0) { - console.log('No meta-skills found.') - return - } - - console.log('Meta-skills (for library maintainers):\n') - - for (const entry of entries) { - const skillFile = join(metaDir, entry.name, 'SKILL.md') - const fm = parseFrontmatter(skillFile) - let description = '' - if (typeof fm?.description === 'string') { - description = fm.description.replace(/\s+/g, ' ').trim() - } - - const shortDesc = - description.length > 60 ? description.slice(0, 57) + '...' : description - console.log(` ${entry.name.padEnd(28)} ${shortDesc}`) - } - - console.log(`\nUsage: load the SKILL.md into your AI agent conversation.`) - console.log(`Path: node_modules/@tanstack/intent/meta//SKILL.md`) -} - -function collectPackagingWarnings(root: string): string[] { - const pkgJsonPath = join(root, 'package.json') - if (!existsSync(pkgJsonPath)) return [] - - let pkgJson: Record - try { - pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8')) - } catch (err) { - const msg = err instanceof Error ? err.message : String(err) - return [`Could not parse package.json: ${msg}`] - } - - const warnings: string[] = [] - - const devDeps = pkgJson.devDependencies as Record | undefined - if (!devDeps?.['@tanstack/intent']) { - warnings.push('@tanstack/intent is not in devDependencies') - } - - const bin = pkgJson.bin as Record | undefined - if (!bin?.intent) { - warnings.push('Missing "bin": { "intent": ... } entry in package.json') - } - - const shimJs = join(root, 'bin', 'intent.js') - const shimMjs = join(root, 'bin', 'intent.mjs') - if (!existsSync(shimJs) && !existsSync(shimMjs)) { - warnings.push( - 'No bin/intent.js or bin/intent.mjs shim found (run: npx @tanstack/intent setup --shim)', - ) - } - - const files = pkgJson.files as string[] | undefined - if (Array.isArray(files)) { - if (!files.includes('skills')) { - warnings.push( - '"skills" is not in the "files" array — skills won\'t be published', - ) - } - if (!files.includes('bin')) { - warnings.push( - '"bin" is not in the "files" array — shim won\'t be published', - ) - } - if (!files.includes('!skills/_artifacts')) { - warnings.push( - '"!skills/_artifacts" is not in the "files" array — artifacts will be published unnecessarily', - ) - } - } - - return warnings -} - -function cmdValidate(args: string[]): void { - const targetDir = args[0] ?? 'skills' - const skillsDir = join(process.cwd(), targetDir) - - if (!existsSync(skillsDir)) { - console.error(`Skills directory not found: ${skillsDir}`) - process.exit(1) - } - - interface ValidationError { - file: string - message: string - } - - const errors: ValidationError[] = [] - const skillFiles = findSkillFiles(skillsDir) - - if (skillFiles.length === 0) { - console.error('No SKILL.md files found') - process.exit(1) - } - - for (const filePath of skillFiles) { - const rel = relative(process.cwd(), filePath) - const content = readFileSync(filePath, 'utf8') - const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)/) - - if (!match) { - errors.push({ file: rel, message: 'Missing or invalid frontmatter' }) - continue - } - - if (!match[1]) { - errors.push({ file: rel, message: 'Missing YAML frontmatter' }) - continue - } - - let fm: Record - try { - fm = parseYaml(match[1]) as Record - } catch { - errors.push({ file: rel, message: 'Invalid YAML frontmatter' }) - continue - } - - if (!fm.name) - errors.push({ file: rel, message: 'Missing required field: name' }) - if (!fm.description) - errors.push({ file: rel, message: 'Missing required field: description' }) - - // Validate name matches directory path - if (typeof fm.name === 'string') { - const expectedPath = relative(skillsDir, filePath) - .replace(/[/\\]SKILL\.md$/, '') - .split(sep) - .join('/') - if (fm.name !== expectedPath) { - errors.push({ - file: rel, - message: `name "${fm.name}" does not match directory path "${expectedPath}"`, - }) - } - } - - // Description character limit - if (typeof fm.description === 'string' && fm.description.length > 1024) { - errors.push({ - file: rel, - message: `Description exceeds 1024 character limit (${fm.description.length} chars)`, - }) - } - - // Framework skills must have requires - if (fm.type === 'framework' && !Array.isArray(fm.requires)) { - errors.push({ - file: rel, - message: 'Framework skills must have a "requires" field', - }) - } - - // Line count - const lineCount = content.split(/\r?\n/).length - if (lineCount > 500) { - errors.push({ - file: rel, - message: `Exceeds 500 line limit (${lineCount} lines). Rewrite for conciseness: move API tables to references/, trim verbose examples, and remove content an agent already knows. Do not simply raise the limit.`, - }) - } - } - - const artifactsDir = join(skillsDir, '_artifacts') - if (existsSync(artifactsDir)) { - const requiredArtifacts = [ - 'domain_map.yaml', - 'skill_spec.md', - 'skill_tree.yaml', - ] - - for (const fileName of requiredArtifacts) { - const artifactPath = join(artifactsDir, fileName) - if (!existsSync(artifactPath)) { - errors.push({ - file: relative(process.cwd(), artifactPath), - message: 'Missing required artifact', - }) - continue - } - - const content = readFileSync(artifactPath, 'utf8') - if (content.trim().length === 0) { - errors.push({ - file: relative(process.cwd(), artifactPath), - message: 'Artifact file is empty', - }) - continue - } - - if (fileName.endsWith('.yaml')) { - try { - parseYaml(content) - } catch { - errors.push({ - file: relative(process.cwd(), artifactPath), - message: 'Invalid YAML in artifact file', - }) - } - } - } - } - - const warnings = collectPackagingWarnings(process.cwd()) - - const printWarnings = (log: (...args: unknown[]) => void): void => { - if (warnings.length === 0) return - log(`\n⚠ Packaging warnings:`) - for (const w of warnings) log(` ${w}`) - } - - if (errors.length > 0) { - console.error(`\n❌ Validation failed with ${errors.length} error(s):\n`) - for (const { file, message } of errors) { - console.error(` ${file}: ${message}`) - } - printWarnings(console.error) - process.exit(1) - } - - console.log(`✅ Validated ${skillFiles.length} skill files — all passed`) - printWarnings(console.log) -} - -function cmdScaffold(): void { - const metaDir = getMetaDir() - const metaSkillPath = (name: string) => join(metaDir, name, 'SKILL.md') - - const prompt = `You are helping a library maintainer scaffold Intent skills. - -Run the three meta skills below **one at a time, in order**. For each step: -1. Load the SKILL.md file specified -2. Follow its instructions completely -3. Present outputs to the maintainer for review -4. Do NOT proceed to the next step until the maintainer confirms - -## Before you start - -Gather this context yourself (do not ask the maintainer — agents should never -ask for information they can discover): -1. Read package.json for library name, repository URL, and homepage/docs URL -2. Detect if this is a monorepo (look for workspaces field, packages/ directory, lerna.json) -3. Use skills/ as the default skills root -4. For monorepos: - - Domain map artifacts go at the REPO ROOT: _artifacts/ - - Skills go INSIDE EACH PACKAGE: packages//skills/ - - Identify which packages are client-facing (usually client SDKs and primary framework adapters) - ---- - -## Step 1 — Domain Discovery - -Load and follow: ${metaSkillPath('domain-discovery')} - -This produces: domain_map.yaml and skill_spec.md in the artifacts directory. -Domain discovery covers the WHOLE library (one domain map even for monorepos). - -**STOP. Review outputs with the maintainer before continuing.** - ---- - -## Step 2 — Tree Generator - -Load and follow: ${metaSkillPath('tree-generator')} - -This produces: skill_tree.yaml in the artifacts directory. -For monorepos, each skill entry should include a \`package\` field. - -**STOP. Review outputs with the maintainer before continuing.** - ---- - -## Step 3 — Generate Skills - -Load and follow: ${metaSkillPath('generate-skill')} - -This produces: individual SKILL.md files. -- Single-repo: skills///SKILL.md -- Monorepo: packages//skills///SKILL.md - ---- - -## After all skills are generated - -1. Run \`npx @tanstack/intent validate\` in each package directory -2. Commit skills/ and artifacts -3. For each publishable package, run: \`npx @tanstack/intent setup --shim\` -4. Ensure each package has \`@tanstack/intent\` as a devDependency -5. Add \`"skills"\`, \`"bin"\` to the \`"files"\` array in each package.json -6. Add \`"!skills/_artifacts"\` to exclude artifacts from publishing -7. Create a \`feedback:\` label on the GitHub repo for each skill (use \`gh label create\`) -8. Add a README note: "If you use an AI agent, run \`npx @tanstack/intent install\`" -` - - console.log(prompt) -} - -// --------------------------------------------------------------------------- -// Main -// --------------------------------------------------------------------------- - -const USAGE = `TanStack Intent CLI - -Usage: - intent list [--json] Discover intent-enabled packages - intent meta List meta-skills for maintainers - intent validate [] Validate skill files (default: skills/) - intent install Print a skill that guides your coding agent to set up skill-to-task mappings - intent scaffold Print maintainer scaffold prompt - intent setup [--workflows] [--shim] [--all] Copy CI templates and generate shim - intent stale Check skills for staleness` - -const command = process.argv[2] -const commandArgs = process.argv.slice(3) - -switch (command) { - case 'list': - await cmdList(commandArgs) - break - case 'meta': - cmdMeta() - break - case 'validate': - cmdValidate(commandArgs) - break - case 'install': { - const prompt = `You are an AI assistant helping a developer set up skill-to-task mappings for their project. - -Follow these steps in order: - -1. CHECK FOR EXISTING MAPPINGS - Search the project's agent config files (CLAUDE.md, AGENTS.md, .cursorrules, - .github/copilot-instructions.md) for a block delimited by: - - - - If found: show the user the current mappings and ask "What would you like to update?" - Then skip to step 4 with their requested changes. - - If not found: continue to step 2. - -2. DISCOVER AVAILABLE SKILLS - Run: intent list - This outputs each skill's name, description, and full path — grouped by package. - -3. SCAN THE REPOSITORY - Build a picture of the project's structure and patterns: - - Read package.json for library dependencies - - Survey the directory layout (src/, app/, routes/, components/, api/, etc.) - - Note recurring patterns (routing, data fetching, auth, UI components, etc.) - - Based on this, propose 3–5 skill-to-task mappings. For each one explain: - - The task or code area (in plain language the user would recognise) - - Which skill applies and why - - Then ask: "What other tasks do you commonly use AI coding agents for? - I'll create mappings for those too." - -4. WRITE THE MAPPINGS BLOCK - Once you have the full set of mappings, write or update the agent config file - (prefer CLAUDE.md; create it if none exists) with this exact block: - - -# Skill mappings — when working in these areas, load the linked skill file into context. -skills: - - task: "describe the task or code area here" - load: "node_modules/package-name/skills/skill-name/SKILL.md" - - - Rules: - - Use the user's own words for task descriptions - - Include the exact path from \`intent list\` output so agents can load it directly - - Keep entries concise — this block is read on every agent task - - Preserve all content outside the block tags unchanged` - - console.log(prompt) - break - } - case 'scaffold': { - cmdScaffold() - break - } - case 'stale': { - const { checkStaleness } = await import('./staleness.js') - const { scanForIntents: scanStale } = await import('./scanner.js') - let staleResult - try { - staleResult = await scanStale() - } catch (err) { - console.error((err as Error).message) - process.exit(1) - } - - if (staleResult.packages.length === 0) { - console.log('No intent-enabled packages found.') - break - } - - const jsonStale = commandArgs.includes('--json') - const reports = await Promise.all( - staleResult.packages.map((pkg) => { - const pkgDir = join(process.cwd(), 'node_modules', pkg.name) - return checkStaleness(pkgDir, pkg.name) - }), - ) - - if (jsonStale) { - console.log(JSON.stringify(reports, null, 2)) - break - } - - for (const report of reports) { - const driftLabel = report.versionDrift - ? ` [${report.versionDrift} drift]` - : '' - const vLabel = - report.skillVersion && report.currentVersion - ? ` (${report.skillVersion} → ${report.currentVersion})` - : '' - console.log(`${report.library}${vLabel}${driftLabel}`) - - const stale = report.skills.filter((s) => s.needsReview) - if (stale.length === 0) { - console.log(' All skills up-to-date') - } else { - for (const skill of stale) { - console.log(` ⚠ ${skill.name}: ${skill.reasons.join(', ')}`) - } - } - console.log() - } - break - } - case 'setup': { - const { runSetup } = await import('./setup.js') - runSetup(process.cwd(), getMetaDir(), commandArgs) - break - } - default: - console.log(USAGE) - process.exit(command ? 1 : 0) -} +#!/usr/bin/env node + +import { existsSync, readdirSync, readFileSync } from 'node:fs' +import { dirname, join, relative, sep } from 'node:path' +import { fileURLToPath } from 'node:url' +import { parse as parseYaml } from 'yaml' +import { computeSkillNameWidth, printSkillTree, printTable } from './display.js' +import { scanForIntents } from './scanner.js' +import type { ScanResult } from './types.js' +import { findSkillFiles, parseFrontmatter } from './utils.js' + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +function getMetaDir(): string { + const thisDir = dirname(fileURLToPath(import.meta.url)) + return join(thisDir, '..', 'meta') +} + +// --------------------------------------------------------------------------- +// Commands +// --------------------------------------------------------------------------- + +async function cmdList(args: string[]): Promise { + const jsonOutput = args.includes('--json') + + let result: ScanResult + try { + result = await scanForIntents() + } catch (err) { + console.error((err as Error).message) + process.exit(1) + } + + if (jsonOutput) { + console.log(JSON.stringify(result, null, 2)) + return + } + + if (result.packages.length === 0) { + console.log('No intent-enabled packages found.') + if (result.warnings.length > 0) { + console.log(`\nWarnings:`) + for (const w of result.warnings) console.log(` ⚠ ${w}`) + } + return + } + + const totalSkills = result.packages.reduce( + (sum, p) => sum + p.skills.length, + 0, + ) + console.log( + `\n${result.packages.length} intent-enabled packages, ${totalSkills} skills (${result.packageManager})\n`, + ) + + // Summary table + const rows = result.packages.map((pkg) => [ + pkg.name, + pkg.version, + String(pkg.skills.length), + pkg.intent.requires?.join(', ') || '–', + ]) + printTable(['PACKAGE', 'VERSION', 'SKILLS', 'REQUIRES'], rows) + + // Skills detail + const allSkills = result.packages.map((p) => p.skills) + const nameWidth = computeSkillNameWidth(allSkills) + const showTypes = result.packages.some((p) => p.skills.some((s) => s.type)) + + console.log(`\nSkills:\n`) + for (const pkg of result.packages) { + console.log(` ${pkg.name}`) + printSkillTree(pkg.skills, { nameWidth, showTypes }) + console.log() + } + + console.log(`Feedback:`) + console.log( + ` Submit feedback on skill usage to help maintainers improve the skills.`, + ) + console.log( + ` Load: node_modules/@tanstack/intent/meta/feedback-collection/SKILL.md`, + ) + console.log() + + if (result.warnings.length > 0) { + console.log(`Warnings:`) + for (const w of result.warnings) console.log(` ⚠ ${w}`) + } +} + +function cmdMeta(): void { + const metaDir = getMetaDir() + + if (!existsSync(metaDir)) { + console.error('Meta-skills directory not found.') + process.exit(1) + } + + const entries = readdirSync(metaDir, { withFileTypes: true }) + .filter((e) => e.isDirectory()) + .filter((e) => existsSync(join(metaDir, e.name, 'SKILL.md'))) + + if (entries.length === 0) { + console.log('No meta-skills found.') + return + } + + console.log('Meta-skills (for library maintainers):\n') + + for (const entry of entries) { + const skillFile = join(metaDir, entry.name, 'SKILL.md') + const fm = parseFrontmatter(skillFile) + let description = '' + if (typeof fm?.description === 'string') { + description = fm.description.replace(/\s+/g, ' ').trim() + } + + const shortDesc = + description.length > 60 ? description.slice(0, 57) + '...' : description + console.log(` ${entry.name.padEnd(28)} ${shortDesc}`) + } + + console.log(`\nUsage: load the SKILL.md into your AI agent conversation.`) + console.log(`Path: node_modules/@tanstack/intent/meta//SKILL.md`) +} + +function collectPackagingWarnings(root: string): string[] { + const pkgJsonPath = join(root, 'package.json') + if (!existsSync(pkgJsonPath)) return [] + + let pkgJson: Record + try { + pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8')) + } catch (err) { + const msg = err instanceof Error ? err.message : String(err) + return [`Could not parse package.json: ${msg}`] + } + + const warnings: string[] = [] + + const devDeps = pkgJson.devDependencies as Record | undefined + if (!devDeps?.['@tanstack/intent']) { + warnings.push('@tanstack/intent is not in devDependencies') + } + + const bin = pkgJson.bin as Record | undefined + if (!bin?.intent) { + warnings.push('Missing "bin": { "intent": ... } entry in package.json') + } + + const shimJs = join(root, 'bin', 'intent.js') + const shimMjs = join(root, 'bin', 'intent.mjs') + if (!existsSync(shimJs) && !existsSync(shimMjs)) { + warnings.push( + 'No bin/intent.js or bin/intent.mjs shim found (run: npx @tanstack/intent setup --shim)', + ) + } + + const files = pkgJson.files as string[] | undefined + if (Array.isArray(files)) { + if (!files.includes('skills')) { + warnings.push( + '"skills" is not in the "files" array — skills won\'t be published', + ) + } + if (!files.includes('bin')) { + warnings.push( + '"bin" is not in the "files" array — shim won\'t be published', + ) + } + if (!files.includes('!skills/_artifacts')) { + warnings.push( + '"!skills/_artifacts" is not in the "files" array — artifacts will be published unnecessarily', + ) + } + } + + return warnings +} + +function cmdValidate(args: string[]): void { + const targetDir = args[0] ?? 'skills' + const skillsDir = join(process.cwd(), targetDir) + + if (!existsSync(skillsDir)) { + console.error(`Skills directory not found: ${skillsDir}`) + process.exit(1) + } + + interface ValidationError { + file: string + message: string + } + + const errors: ValidationError[] = [] + const skillFiles = findSkillFiles(skillsDir) + + if (skillFiles.length === 0) { + console.error('No SKILL.md files found') + process.exit(1) + } + + for (const filePath of skillFiles) { + const rel = relative(process.cwd(), filePath) + const content = readFileSync(filePath, 'utf8') + const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)/) + + if (!match) { + errors.push({ file: rel, message: 'Missing or invalid frontmatter' }) + continue + } + + if (!match[1]) { + errors.push({ file: rel, message: 'Missing YAML frontmatter' }) + continue + } + + let fm: Record + try { + fm = parseYaml(match[1]) as Record + } catch { + errors.push({ file: rel, message: 'Invalid YAML frontmatter' }) + continue + } + + if (!fm.name) + errors.push({ file: rel, message: 'Missing required field: name' }) + if (!fm.description) + errors.push({ file: rel, message: 'Missing required field: description' }) + + // Validate name matches directory path + if (typeof fm.name === 'string') { + const expectedPath = relative(skillsDir, filePath) + .replace(/[/\\]SKILL\.md$/, '') + .split(sep) + .join('/') + if (fm.name !== expectedPath) { + errors.push({ + file: rel, + message: `name "${fm.name}" does not match directory path "${expectedPath}"`, + }) + } + } + + // Description character limit + if (typeof fm.description === 'string' && fm.description.length > 1024) { + errors.push({ + file: rel, + message: `Description exceeds 1024 character limit (${fm.description.length} chars)`, + }) + } + + // Framework skills must have requires + if (fm.type === 'framework' && !Array.isArray(fm.requires)) { + errors.push({ + file: rel, + message: 'Framework skills must have a "requires" field', + }) + } + + // Line count + const lineCount = content.split(/\r?\n/).length + if (lineCount > 500) { + errors.push({ + file: rel, + message: `Exceeds 500 line limit (${lineCount} lines). Rewrite for conciseness: move API tables to references/, trim verbose examples, and remove content an agent already knows. Do not simply raise the limit.`, + }) + } + } + + const artifactsDir = join(skillsDir, '_artifacts') + if (existsSync(artifactsDir)) { + const requiredArtifacts = [ + 'domain_map.yaml', + 'skill_spec.md', + 'skill_tree.yaml', + ] + + for (const fileName of requiredArtifacts) { + const artifactPath = join(artifactsDir, fileName) + if (!existsSync(artifactPath)) { + errors.push({ + file: relative(process.cwd(), artifactPath), + message: 'Missing required artifact', + }) + continue + } + + const content = readFileSync(artifactPath, 'utf8') + if (content.trim().length === 0) { + errors.push({ + file: relative(process.cwd(), artifactPath), + message: 'Artifact file is empty', + }) + continue + } + + if (fileName.endsWith('.yaml')) { + try { + parseYaml(content) + } catch { + errors.push({ + file: relative(process.cwd(), artifactPath), + message: 'Invalid YAML in artifact file', + }) + } + } + } + } + + const warnings = collectPackagingWarnings(process.cwd()) + + const printWarnings = (log: (...args: unknown[]) => void): void => { + if (warnings.length === 0) return + log(`\n⚠ Packaging warnings:`) + for (const w of warnings) log(` ${w}`) + } + + if (errors.length > 0) { + console.error(`\n❌ Validation failed with ${errors.length} error(s):\n`) + for (const { file, message } of errors) { + console.error(` ${file}: ${message}`) + } + printWarnings(console.error) + process.exit(1) + } + + console.log(`✅ Validated ${skillFiles.length} skill files — all passed`) + printWarnings(console.log) +} + +function cmdScaffold(): void { + const metaDir = getMetaDir() + const metaSkillPath = (name: string) => join(metaDir, name, 'SKILL.md') + + const prompt = `You are helping a library maintainer scaffold Intent skills. + +Run the three meta skills below **one at a time, in order**. For each step: +1. Load the SKILL.md file specified +2. Follow its instructions completely +3. Present outputs to the maintainer for review +4. Do NOT proceed to the next step until the maintainer confirms + +## Before you start + +Gather this context yourself (do not ask the maintainer — agents should never +ask for information they can discover): +1. Read package.json for library name, repository URL, and homepage/docs URL +2. Detect if this is a monorepo (look for workspaces field, packages/ directory, lerna.json) +3. Use skills/ as the default skills root +4. For monorepos: + - Domain map artifacts go at the REPO ROOT: _artifacts/ + - Skills go INSIDE EACH PACKAGE: packages//skills/ + - Identify which packages are client-facing (usually client SDKs and primary framework adapters) + +--- + +## Step 1 — Domain Discovery + +Load and follow: ${metaSkillPath('domain-discovery')} + +This produces: domain_map.yaml and skill_spec.md in the artifacts directory. +Domain discovery covers the WHOLE library (one domain map even for monorepos). + +**STOP. Review outputs with the maintainer before continuing.** + +--- + +## Step 2 — Tree Generator + +Load and follow: ${metaSkillPath('tree-generator')} + +This produces: skill_tree.yaml in the artifacts directory. +For monorepos, each skill entry should include a \`package\` field. + +**STOP. Review outputs with the maintainer before continuing.** + +--- + +## Step 3 — Generate Skills + +Load and follow: ${metaSkillPath('generate-skill')} + +This produces: individual SKILL.md files. +- Single-repo: skills///SKILL.md +- Monorepo: packages//skills///SKILL.md + +--- + +## After all skills are generated + +1. Run \`npx @tanstack/intent validate\` in each package directory +2. Commit skills/ and artifacts +3. For each publishable package, run: \`npx @tanstack/intent setup --shim\` +4. Ensure each package has \`@tanstack/intent\` as a devDependency +5. Add \`"skills"\`, \`"bin"\` to the \`"files"\` array in each package.json +6. Add \`"!skills/_artifacts"\` to exclude artifacts from publishing +7. Create a \`feedback:\` label on the GitHub repo for each skill (use \`gh label create\`) +8. Add a README note: "If you use an AI agent, run \`npx @tanstack/intent install\`" +` + + console.log(prompt) +} + +// --------------------------------------------------------------------------- +// Main +// --------------------------------------------------------------------------- + +const USAGE = `TanStack Intent CLI + +Usage: + intent list [--json] Discover intent-enabled packages + intent meta List meta-skills for maintainers + intent validate [] Validate skill files (default: skills/) + intent install Print a skill that guides your coding agent to set up skill-to-task mappings + intent scaffold Print maintainer scaffold prompt + intent setup [--workflows] [--shim] [--all] Copy CI templates and generate shim + intent stale Check skills for staleness` + +const command = process.argv[2] +const commandArgs = process.argv.slice(3) + +switch (command) { + case 'list': + await cmdList(commandArgs) + break + case 'meta': + cmdMeta() + break + case 'validate': + cmdValidate(commandArgs) + break + case 'install': { + const prompt = `You are an AI assistant helping a developer set up skill-to-task mappings for their project. + +Follow these steps in order: + +1. CHECK FOR EXISTING MAPPINGS + Search the project's agent config files (CLAUDE.md, AGENTS.md, .cursorrules, + .github/copilot-instructions.md) for a block delimited by: + + + - If found: show the user the current mappings and ask "What would you like to update?" + Then skip to step 4 with their requested changes. + - If not found: continue to step 2. + +2. DISCOVER AVAILABLE SKILLS + Run: intent list + This outputs each skill's name, description, and full path — grouped by package. + +3. SCAN THE REPOSITORY + Build a picture of the project's structure and patterns: + - Read package.json for library dependencies + - Survey the directory layout (src/, app/, routes/, components/, api/, etc.) + - Note recurring patterns (routing, data fetching, auth, UI components, etc.) + + Based on this, propose 3–5 skill-to-task mappings. For each one explain: + - The task or code area (in plain language the user would recognise) + - Which skill applies and why + + Then ask: "What other tasks do you commonly use AI coding agents for? + I'll create mappings for those too." + +4. WRITE THE MAPPINGS BLOCK + Once you have the full set of mappings, write or update the agent config file + (prefer CLAUDE.md; create it if none exists) with this exact block: + + +# Skill mappings — when working in these areas, load the linked skill file into context. +skills: + - task: "describe the task or code area here" + load: "node_modules/package-name/skills/skill-name/SKILL.md" + + + Rules: + - Use the user's own words for task descriptions + - Include the exact path from \`intent list\` output so agents can load it directly + - Keep entries concise — this block is read on every agent task + - Preserve all content outside the block tags unchanged` + + console.log(prompt) + break + } + case 'scaffold': { + cmdScaffold() + break + } + case 'stale': { + const { checkStaleness } = await import('./staleness.js') + const { scanForIntents: scanStale } = await import('./scanner.js') + let staleResult + try { + staleResult = await scanStale() + } catch (err) { + console.error((err as Error).message) + process.exit(1) + } + + if (staleResult.packages.length === 0) { + console.log('No intent-enabled packages found.') + break + } + + const jsonStale = commandArgs.includes('--json') + const reports = await Promise.all( + staleResult.packages.map((pkg) => { + const pkgDir = join(process.cwd(), 'node_modules', pkg.name) + return checkStaleness(pkgDir, pkg.name) + }), + ) + + if (jsonStale) { + console.log(JSON.stringify(reports, null, 2)) + break + } + + for (const report of reports) { + const driftLabel = report.versionDrift + ? ` [${report.versionDrift} drift]` + : '' + const vLabel = + report.skillVersion && report.currentVersion + ? ` (${report.skillVersion} → ${report.currentVersion})` + : '' + console.log(`${report.library}${vLabel}${driftLabel}`) + + const stale = report.skills.filter((s) => s.needsReview) + if (stale.length === 0) { + console.log(' All skills up-to-date') + } else { + for (const skill of stale) { + console.log(` ⚠ ${skill.name}: ${skill.reasons.join(', ')}`) + } + } + console.log() + } + break + } + case 'setup': { + const { runSetup } = await import('./setup.js') + runSetup(process.cwd(), getMetaDir(), commandArgs) + break + } + default: + console.log(USAGE) + process.exit(command ? 1 : 0) +} diff --git a/packages/intent/src/display.ts b/packages/intent/src/display.ts index 1ace4191..85f2f87b 100644 --- a/packages/intent/src/display.ts +++ b/packages/intent/src/display.ts @@ -1,98 +1,98 @@ -// --------------------------------------------------------------------------- -// Shared display helpers for CLI output -// --------------------------------------------------------------------------- - -export interface SkillDisplay { - name: string - description: string - type?: string - path?: string -} - -function padColumn(text: string, width: number): string { - return text.length >= width ? text + ' ' : text.padEnd(width) -} - -export function printTable(headers: string[], rows: string[][]): void { - const widths = headers.map( - (h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? '').length)) + 2, - ) - - const headerLine = headers.map((h, i) => padColumn(h, widths[i]!)).join('') - const separator = widths.map((w) => '─'.repeat(w)).join('') - - console.log(headerLine) - console.log(separator) - for (const row of rows) { - console.log(row.map((cell, i) => padColumn(cell, widths[i]!)).join('')) - } -} - -function printSkillLine( - displayName: string, - skill: SkillDisplay, - indent: number, - opts: { nameWidth: number; showTypes: boolean }, -): void { - const nameStr = ' '.repeat(indent) + displayName - const padding = ' '.repeat(Math.max(2, opts.nameWidth - nameStr.length)) - const typeCol = opts.showTypes - ? (skill.type ? `[${skill.type}]` : '').padEnd(14) - : '' - console.log(`${nameStr}${padding}${typeCol}${skill.description}`) - if (skill.path) { - console.log(`${' '.repeat(indent + 2)}${skill.path}`) - } -} - -export function printSkillTree( - skills: SkillDisplay[], - opts: { nameWidth: number; showTypes: boolean }, -): void { - const roots: string[] = [] - const children = new Map() - - for (const skill of skills) { - const slashIdx = skill.name.indexOf('/') - if (slashIdx === -1) { - roots.push(skill.name) - } else { - const parent = skill.name.slice(0, slashIdx) - if (!children.has(parent)) children.set(parent, []) - children.get(parent)!.push(skill) - } - } - - if (roots.length === 0) { - for (const skill of skills) { - if (!roots.includes(skill.name)) roots.push(skill.name) - } - } - - for (const rootName of roots) { - const rootSkill = skills.find((s) => s.name === rootName) - if (!rootSkill) continue - - printSkillLine(rootName, rootSkill, 4, opts) - - for (const sub of children.get(rootName) ?? []) { - const childName = sub.name.slice(sub.name.indexOf('/') + 1) - printSkillLine(childName, sub, 6, opts) - } - } -} - -export function computeSkillNameWidth( - allPackageSkills: SkillDisplay[][], -): number { - let max = 0 - for (const skills of allPackageSkills) { - for (const s of skills) { - const slashIdx = s.name.indexOf('/') - const displayName = slashIdx === -1 ? s.name : s.name.slice(slashIdx + 1) - const indent = slashIdx === -1 ? 4 : 6 - max = Math.max(max, indent + displayName.length) - } - } - return max + 2 -} +// --------------------------------------------------------------------------- +// Shared display helpers for CLI output +// --------------------------------------------------------------------------- + +export interface SkillDisplay { + name: string + description: string + type?: string + path?: string +} + +function padColumn(text: string, width: number): string { + return text.length >= width ? text + ' ' : text.padEnd(width) +} + +export function printTable(headers: string[], rows: string[][]): void { + const widths = headers.map( + (h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? '').length)) + 2, + ) + + const headerLine = headers.map((h, i) => padColumn(h, widths[i]!)).join('') + const separator = widths.map((w) => '─'.repeat(w)).join('') + + console.log(headerLine) + console.log(separator) + for (const row of rows) { + console.log(row.map((cell, i) => padColumn(cell, widths[i]!)).join('')) + } +} + +function printSkillLine( + displayName: string, + skill: SkillDisplay, + indent: number, + opts: { nameWidth: number; showTypes: boolean }, +): void { + const nameStr = ' '.repeat(indent) + displayName + const padding = ' '.repeat(Math.max(2, opts.nameWidth - nameStr.length)) + const typeCol = opts.showTypes + ? (skill.type ? `[${skill.type}]` : '').padEnd(14) + : '' + console.log(`${nameStr}${padding}${typeCol}${skill.description}`) + if (skill.path) { + console.log(`${' '.repeat(indent + 2)}${skill.path}`) + } +} + +export function printSkillTree( + skills: SkillDisplay[], + opts: { nameWidth: number; showTypes: boolean }, +): void { + const roots: string[] = [] + const children = new Map() + + for (const skill of skills) { + const slashIdx = skill.name.indexOf('/') + if (slashIdx === -1) { + roots.push(skill.name) + } else { + const parent = skill.name.slice(0, slashIdx) + if (!children.has(parent)) children.set(parent, []) + children.get(parent)!.push(skill) + } + } + + if (roots.length === 0) { + for (const skill of skills) { + if (!roots.includes(skill.name)) roots.push(skill.name) + } + } + + for (const rootName of roots) { + const rootSkill = skills.find((s) => s.name === rootName) + if (!rootSkill) continue + + printSkillLine(rootName, rootSkill, 4, opts) + + for (const sub of children.get(rootName) ?? []) { + const childName = sub.name.slice(sub.name.indexOf('/') + 1) + printSkillLine(childName, sub, 6, opts) + } + } +} + +export function computeSkillNameWidth( + allPackageSkills: SkillDisplay[][], +): number { + let max = 0 + for (const skills of allPackageSkills) { + for (const s of skills) { + const slashIdx = s.name.indexOf('/') + const displayName = slashIdx === -1 ? s.name : s.name.slice(slashIdx + 1) + const indent = slashIdx === -1 ? 4 : 6 + max = Math.max(max, indent + displayName.length) + } + } + return max + 2 +} diff --git a/packages/intent/src/feedback.ts b/packages/intent/src/feedback.ts index a0c9d85c..a0d43e58 100644 --- a/packages/intent/src/feedback.ts +++ b/packages/intent/src/feedback.ts @@ -1,374 +1,374 @@ -import { execFileSync, execSync } from 'node:child_process' -import { readFileSync, writeFileSync } from 'node:fs' -import { join } from 'node:path' -import type { - FeedbackPayload, - IntentProjectConfig, - MetaFeedbackPayload, -} from './types.js' - -const META_FEEDBACK_REPO = 'TanStack/intent' - -// --------------------------------------------------------------------------- -// Secret detection -// --------------------------------------------------------------------------- - -const SECRET_PATTERNS = [ - /(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36,}/, // GitHub tokens - /(?:sk|pk)[-_](?:live|test)[-_][A-Za-z0-9]{24,}/, // Stripe keys - /AKIA[0-9A-Z]{16}/, // AWS access keys - /-----BEGIN (?:RSA |EC )?PRIVATE KEY-----/, // PEM private keys - /eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/, // JWT-like tokens - /(?:Bearer|token)\s+[A-Za-z0-9_\-.~+/]{20,}/i, // Bearer tokens - /[A-Za-z0-9]{32,}(?=.*(?:key|secret|token|password))/i, // Generic secrets near keywords -] - -export function containsSecrets(text: string): boolean { - return SECRET_PATTERNS.some((pattern) => pattern.test(text)) -} - -// --------------------------------------------------------------------------- -// `gh` CLI detection -// --------------------------------------------------------------------------- - -export function hasGhCli(): boolean { - try { - execSync('gh --version', { stdio: 'ignore' }) - return true - } catch { - return false - } -} - -// --------------------------------------------------------------------------- -// Config resolution -// --------------------------------------------------------------------------- - -function getHomeConfigDir(): string { - return ( - process.env.XDG_CONFIG_HOME ?? - join(process.env.HOME ?? process.env.USERPROFILE ?? '', '.config') - ) -} - -export function resolveFrequency(root: string): string { - // 1. User override (~/.config/intent/config.json) - const userConfigPath = join(getHomeConfigDir(), 'intent', 'config.json') - try { - const userCfg = JSON.parse( - readFileSync(userConfigPath, 'utf8'), - ) as Partial - if (userCfg.feedback?.frequency) return userCfg.feedback.frequency - } catch { - /* fallback */ - } - - // 2. Project config - const projectConfigPath = join(root, 'intent.config.json') - try { - const projCfg = JSON.parse( - readFileSync(projectConfigPath, 'utf8'), - ) as Partial - if (projCfg.feedback?.frequency) return projCfg.feedback.frequency - } catch { - /* fallback */ - } - - // 3. Default - return 'every-5' -} - -// --------------------------------------------------------------------------- -// Feedback payload validation -// --------------------------------------------------------------------------- - -const REQUIRED_FIELDS: (keyof FeedbackPayload)[] = [ - 'skill', - 'package', - 'skillVersion', - 'task', - 'whatWorked', - 'whatFailed', - 'missing', - 'selfCorrections', - 'userRating', -] - -export function validatePayload(payload: unknown): { - valid: boolean - errors: string[] -} { - const errors: string[] = [] - if (!payload || typeof payload !== 'object') { - return { valid: false, errors: ['Payload must be a JSON object'] } - } - const obj = payload as Record - - for (const field of REQUIRED_FIELDS) { - if ( - typeof obj[field] !== 'string' || - (obj[field] as string).trim() === '' - ) { - errors.push(`Missing or empty required field: ${field}`) - } - } - - if ( - obj.userRating && - !['good', 'mixed', 'bad'].includes(obj.userRating as string) - ) { - errors.push('userRating must be one of: good, mixed, bad') - } - - // Secret scan across all string values - const allText = Object.values(obj) - .filter((v) => typeof v === 'string') - .join('\n') - - if (containsSecrets(allText)) { - errors.push( - 'Payload appears to contain secrets or tokens — submission rejected', - ) - } - - return { valid: errors.length === 0, errors } -} - -// --------------------------------------------------------------------------- -// Meta-feedback payload validation -// --------------------------------------------------------------------------- - -const META_REQUIRED_FIELDS: (keyof MetaFeedbackPayload)[] = [ - 'metaSkill', - 'library', - 'agentUsed', - 'artifactQuality', - 'whatWorked', - 'whatFailed', - 'suggestions', - 'userRating', -] - -const VALID_META_SKILLS = [ - 'domain-discovery', - 'tree-generator', - 'generate-skill', - 'skill-staleness-check', -] - -const VALID_AGENTS = ['claude-code', 'cursor', 'copilot', 'codex', 'other'] - -const VALID_QUALITY_RATINGS = ['good', 'mixed', 'bad'] - -export function validateMetaPayload(payload: unknown): { - valid: boolean - errors: string[] -} { - const errors: string[] = [] - if (!payload || typeof payload !== 'object') { - return { valid: false, errors: ['Payload must be a JSON object'] } - } - const obj = payload as Record - - for (const field of META_REQUIRED_FIELDS) { - if ( - typeof obj[field] !== 'string' || - (obj[field] as string).trim() === '' - ) { - errors.push(`Missing or empty required field: ${field}`) - } - } - - if (obj.metaSkill && !VALID_META_SKILLS.includes(obj.metaSkill as string)) { - errors.push(`metaSkill must be one of: ${VALID_META_SKILLS.join(', ')}`) - } - - if (obj.agentUsed && !VALID_AGENTS.includes(obj.agentUsed as string)) { - errors.push(`agentUsed must be one of: ${VALID_AGENTS.join(', ')}`) - } - - if ( - obj.artifactQuality && - !VALID_QUALITY_RATINGS.includes(obj.artifactQuality as string) - ) { - errors.push('artifactQuality must be one of: good, mixed, bad') - } - - if ( - obj.userRating && - !VALID_QUALITY_RATINGS.includes(obj.userRating as string) - ) { - errors.push('userRating must be one of: good, mixed, bad') - } - - // Secret scan - const allText = Object.values(obj) - .filter((v) => typeof v === 'string') - .join('\n') - - if (containsSecrets(allText)) { - errors.push( - 'Payload appears to contain secrets or tokens — submission rejected', - ) - } - - return { valid: errors.length === 0, errors } -} - -// --------------------------------------------------------------------------- -// Markdown conversion -// --------------------------------------------------------------------------- - -export function metaToMarkdown(payload: MetaFeedbackPayload): string { - const lines = [ - `# Meta-Skill Feedback: ${payload.metaSkill}`, - '', - `**Library:** ${payload.library}`, - `**Agent:** ${payload.agentUsed}`, - `**Artifact quality:** ${payload.artifactQuality}`, - `**Rating:** ${payload.userRating}`, - ] - - if (payload.interviewQuality) { - lines.push(`**Interview quality:** ${payload.interviewQuality}`) - } - if (payload.failureModeQuality) { - lines.push(`**Failure mode quality:** ${payload.failureModeQuality}`) - } - - lines.push( - '', - '## What Worked', - payload.whatWorked, - '', - '## What Failed', - payload.whatFailed, - '', - '## Suggestions', - payload.suggestions, - ) - - return lines.join('\n') + '\n' -} - -export function toMarkdown(payload: FeedbackPayload): string { - const lines = [ - `# Skill Feedback: ${payload.skill}`, - '', - `**Package:** ${payload.package}`, - `**Skill version:** ${payload.skillVersion}`, - `**Rating:** ${payload.userRating}`, - '', - '## Task', - payload.task, - '', - '## What Worked', - payload.whatWorked, - '', - '## What Failed', - payload.whatFailed, - '', - '## Missing', - payload.missing, - '', - '## Self-Corrections', - payload.selfCorrections, - ] - - if (payload.userComments) { - lines.push('', '## User Comments', payload.userComments) - } - - return lines.join('\n') + '\n' -} - -// --------------------------------------------------------------------------- -// Submission -// --------------------------------------------------------------------------- - -export interface SubmitResult { - method: 'gh' | 'file' | 'stdout' - detail: string -} - -export function submitFeedback( - payload: FeedbackPayload, - repo: string, - opts: { ghAvailable: boolean; outputPath?: string }, -): SubmitResult { - const md = toMarkdown(payload) - - // Try gh - if (opts.ghAvailable) { - try { - const title = `Skill Feedback: ${payload.skill} (${payload.userRating})` - execFileSync( - 'gh', - ['issue', 'create', '--repo', repo, '--title', title, '--body', '-'], - { input: md, stdio: ['pipe', 'pipe', 'pipe'] }, - ) - return { method: 'gh', detail: `Submitted issue to ${repo}` } - } catch (err) { - const msg = err instanceof Error ? err.message : String(err) - console.error(`GitHub submission failed: ${msg}`) - console.error('Falling back to file output.') - } - } - - // File fallback - if (opts.outputPath) { - writeFileSync(opts.outputPath, md, 'utf8') - return { method: 'file', detail: `Saved to ${opts.outputPath}` } - } - - // Stdout fallback - return { method: 'stdout', detail: md } -} - -// --------------------------------------------------------------------------- -// Meta-feedback submission -// --------------------------------------------------------------------------- - -export function submitMetaFeedback( - payload: MetaFeedbackPayload, - opts: { ghAvailable: boolean; outputPath?: string }, -): SubmitResult { - const md = metaToMarkdown(payload) - - if (opts.ghAvailable) { - try { - const title = `Meta-Skill Feedback: ${payload.metaSkill} (${payload.userRating})` - execFileSync( - 'gh', - [ - 'issue', - 'create', - '--repo', - META_FEEDBACK_REPO, - '--title', - title, - '--label', - `feedback:${payload.metaSkill}`, - '--body', - '-', - ], - { input: md, stdio: ['pipe', 'pipe', 'pipe'] }, - ) - return { - method: 'gh', - detail: `Submitted issue to ${META_FEEDBACK_REPO}`, - } - } catch (err) { - const msg = err instanceof Error ? err.message : String(err) - console.error(`GitHub submission failed: ${msg}`) - console.error('Falling back to file output.') - } - } - - if (opts.outputPath) { - writeFileSync(opts.outputPath, md, 'utf8') - return { method: 'file', detail: `Saved to ${opts.outputPath}` } - } - - return { method: 'stdout', detail: md } -} +import { execFileSync, execSync } from 'node:child_process' +import { readFileSync, writeFileSync } from 'node:fs' +import { join } from 'node:path' +import type { + FeedbackPayload, + IntentProjectConfig, + MetaFeedbackPayload, +} from './types.js' + +const META_FEEDBACK_REPO = 'TanStack/intent' + +// --------------------------------------------------------------------------- +// Secret detection +// --------------------------------------------------------------------------- + +const SECRET_PATTERNS = [ + /(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36,}/, // GitHub tokens + /(?:sk|pk)[-_](?:live|test)[-_][A-Za-z0-9]{24,}/, // Stripe keys + /AKIA[0-9A-Z]{16}/, // AWS access keys + /-----BEGIN (?:RSA |EC )?PRIVATE KEY-----/, // PEM private keys + /eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/, // JWT-like tokens + /(?:Bearer|token)\s+[A-Za-z0-9_\-.~+/]{20,}/i, // Bearer tokens + /[A-Za-z0-9]{32,}(?=.*(?:key|secret|token|password))/i, // Generic secrets near keywords +] + +export function containsSecrets(text: string): boolean { + return SECRET_PATTERNS.some((pattern) => pattern.test(text)) +} + +// --------------------------------------------------------------------------- +// `gh` CLI detection +// --------------------------------------------------------------------------- + +export function hasGhCli(): boolean { + try { + execSync('gh --version', { stdio: 'ignore' }) + return true + } catch { + return false + } +} + +// --------------------------------------------------------------------------- +// Config resolution +// --------------------------------------------------------------------------- + +function getHomeConfigDir(): string { + return ( + process.env.XDG_CONFIG_HOME ?? + join(process.env.HOME ?? process.env.USERPROFILE ?? '', '.config') + ) +} + +export function resolveFrequency(root: string): string { + // 1. User override (~/.config/intent/config.json) + const userConfigPath = join(getHomeConfigDir(), 'intent', 'config.json') + try { + const userCfg = JSON.parse( + readFileSync(userConfigPath, 'utf8'), + ) as Partial + if (userCfg.feedback?.frequency) return userCfg.feedback.frequency + } catch { + /* fallback */ + } + + // 2. Project config + const projectConfigPath = join(root, 'intent.config.json') + try { + const projCfg = JSON.parse( + readFileSync(projectConfigPath, 'utf8'), + ) as Partial + if (projCfg.feedback?.frequency) return projCfg.feedback.frequency + } catch { + /* fallback */ + } + + // 3. Default + return 'every-5' +} + +// --------------------------------------------------------------------------- +// Feedback payload validation +// --------------------------------------------------------------------------- + +const REQUIRED_FIELDS: (keyof FeedbackPayload)[] = [ + 'skill', + 'package', + 'skillVersion', + 'task', + 'whatWorked', + 'whatFailed', + 'missing', + 'selfCorrections', + 'userRating', +] + +export function validatePayload(payload: unknown): { + valid: boolean + errors: string[] +} { + const errors: string[] = [] + if (!payload || typeof payload !== 'object') { + return { valid: false, errors: ['Payload must be a JSON object'] } + } + const obj = payload as Record + + for (const field of REQUIRED_FIELDS) { + if ( + typeof obj[field] !== 'string' || + (obj[field] as string).trim() === '' + ) { + errors.push(`Missing or empty required field: ${field}`) + } + } + + if ( + obj.userRating && + !['good', 'mixed', 'bad'].includes(obj.userRating as string) + ) { + errors.push('userRating must be one of: good, mixed, bad') + } + + // Secret scan across all string values + const allText = Object.values(obj) + .filter((v) => typeof v === 'string') + .join('\n') + + if (containsSecrets(allText)) { + errors.push( + 'Payload appears to contain secrets or tokens — submission rejected', + ) + } + + return { valid: errors.length === 0, errors } +} + +// --------------------------------------------------------------------------- +// Meta-feedback payload validation +// --------------------------------------------------------------------------- + +const META_REQUIRED_FIELDS: (keyof MetaFeedbackPayload)[] = [ + 'metaSkill', + 'library', + 'agentUsed', + 'artifactQuality', + 'whatWorked', + 'whatFailed', + 'suggestions', + 'userRating', +] + +const VALID_META_SKILLS = [ + 'domain-discovery', + 'tree-generator', + 'generate-skill', + 'skill-staleness-check', +] + +const VALID_AGENTS = ['claude-code', 'cursor', 'copilot', 'codex', 'other'] + +const VALID_QUALITY_RATINGS = ['good', 'mixed', 'bad'] + +export function validateMetaPayload(payload: unknown): { + valid: boolean + errors: string[] +} { + const errors: string[] = [] + if (!payload || typeof payload !== 'object') { + return { valid: false, errors: ['Payload must be a JSON object'] } + } + const obj = payload as Record + + for (const field of META_REQUIRED_FIELDS) { + if ( + typeof obj[field] !== 'string' || + (obj[field] as string).trim() === '' + ) { + errors.push(`Missing or empty required field: ${field}`) + } + } + + if (obj.metaSkill && !VALID_META_SKILLS.includes(obj.metaSkill as string)) { + errors.push(`metaSkill must be one of: ${VALID_META_SKILLS.join(', ')}`) + } + + if (obj.agentUsed && !VALID_AGENTS.includes(obj.agentUsed as string)) { + errors.push(`agentUsed must be one of: ${VALID_AGENTS.join(', ')}`) + } + + if ( + obj.artifactQuality && + !VALID_QUALITY_RATINGS.includes(obj.artifactQuality as string) + ) { + errors.push('artifactQuality must be one of: good, mixed, bad') + } + + if ( + obj.userRating && + !VALID_QUALITY_RATINGS.includes(obj.userRating as string) + ) { + errors.push('userRating must be one of: good, mixed, bad') + } + + // Secret scan + const allText = Object.values(obj) + .filter((v) => typeof v === 'string') + .join('\n') + + if (containsSecrets(allText)) { + errors.push( + 'Payload appears to contain secrets or tokens — submission rejected', + ) + } + + return { valid: errors.length === 0, errors } +} + +// --------------------------------------------------------------------------- +// Markdown conversion +// --------------------------------------------------------------------------- + +export function metaToMarkdown(payload: MetaFeedbackPayload): string { + const lines = [ + `# Meta-Skill Feedback: ${payload.metaSkill}`, + '', + `**Library:** ${payload.library}`, + `**Agent:** ${payload.agentUsed}`, + `**Artifact quality:** ${payload.artifactQuality}`, + `**Rating:** ${payload.userRating}`, + ] + + if (payload.interviewQuality) { + lines.push(`**Interview quality:** ${payload.interviewQuality}`) + } + if (payload.failureModeQuality) { + lines.push(`**Failure mode quality:** ${payload.failureModeQuality}`) + } + + lines.push( + '', + '## What Worked', + payload.whatWorked, + '', + '## What Failed', + payload.whatFailed, + '', + '## Suggestions', + payload.suggestions, + ) + + return lines.join('\n') + '\n' +} + +export function toMarkdown(payload: FeedbackPayload): string { + const lines = [ + `# Skill Feedback: ${payload.skill}`, + '', + `**Package:** ${payload.package}`, + `**Skill version:** ${payload.skillVersion}`, + `**Rating:** ${payload.userRating}`, + '', + '## Task', + payload.task, + '', + '## What Worked', + payload.whatWorked, + '', + '## What Failed', + payload.whatFailed, + '', + '## Missing', + payload.missing, + '', + '## Self-Corrections', + payload.selfCorrections, + ] + + if (payload.userComments) { + lines.push('', '## User Comments', payload.userComments) + } + + return lines.join('\n') + '\n' +} + +// --------------------------------------------------------------------------- +// Submission +// --------------------------------------------------------------------------- + +export interface SubmitResult { + method: 'gh' | 'file' | 'stdout' + detail: string +} + +export function submitFeedback( + payload: FeedbackPayload, + repo: string, + opts: { ghAvailable: boolean; outputPath?: string }, +): SubmitResult { + const md = toMarkdown(payload) + + // Try gh + if (opts.ghAvailable) { + try { + const title = `Skill Feedback: ${payload.skill} (${payload.userRating})` + execFileSync( + 'gh', + ['issue', 'create', '--repo', repo, '--title', title, '--body', '-'], + { input: md, stdio: ['pipe', 'pipe', 'pipe'] }, + ) + return { method: 'gh', detail: `Submitted issue to ${repo}` } + } catch (err) { + const msg = err instanceof Error ? err.message : String(err) + console.error(`GitHub submission failed: ${msg}`) + console.error('Falling back to file output.') + } + } + + // File fallback + if (opts.outputPath) { + writeFileSync(opts.outputPath, md, 'utf8') + return { method: 'file', detail: `Saved to ${opts.outputPath}` } + } + + // Stdout fallback + return { method: 'stdout', detail: md } +} + +// --------------------------------------------------------------------------- +// Meta-feedback submission +// --------------------------------------------------------------------------- + +export function submitMetaFeedback( + payload: MetaFeedbackPayload, + opts: { ghAvailable: boolean; outputPath?: string }, +): SubmitResult { + const md = metaToMarkdown(payload) + + if (opts.ghAvailable) { + try { + const title = `Meta-Skill Feedback: ${payload.metaSkill} (${payload.userRating})` + execFileSync( + 'gh', + [ + 'issue', + 'create', + '--repo', + META_FEEDBACK_REPO, + '--title', + title, + '--label', + `feedback:${payload.metaSkill}`, + '--body', + '-', + ], + { input: md, stdio: ['pipe', 'pipe', 'pipe'] }, + ) + return { + method: 'gh', + detail: `Submitted issue to ${META_FEEDBACK_REPO}`, + } + } catch (err) { + const msg = err instanceof Error ? err.message : String(err) + console.error(`GitHub submission failed: ${msg}`) + console.error('Falling back to file output.') + } + } + + if (opts.outputPath) { + writeFileSync(opts.outputPath, md, 'utf8') + return { method: 'file', detail: `Saved to ${opts.outputPath}` } + } + + return { method: 'stdout', detail: md } +} diff --git a/packages/intent/src/index.ts b/packages/intent/src/index.ts index 3d22fde8..0436cbf9 100644 --- a/packages/intent/src/index.ts +++ b/packages/intent/src/index.ts @@ -1,28 +1,28 @@ -export { scanForIntents } from './scanner.js' -export { checkStaleness } from './staleness.js' -export { - containsSecrets, - hasGhCli, - metaToMarkdown, - resolveFrequency, - submitFeedback, - submitMetaFeedback, - toMarkdown, - validateMetaPayload, - validatePayload, -} from './feedback.js' -export { findSkillFiles, parseFrontmatter } from './utils.js' -export { runSetup } from './setup.js' -export type { - AgentName, - FeedbackPayload, - IntentConfig, - IntentPackage, - IntentProjectConfig, - MetaFeedbackPayload, - MetaSkillName, - ScanResult, - SkillEntry, - StalenessReport, - SkillStaleness, -} from './types.js' +export { scanForIntents } from './scanner.js' +export { checkStaleness } from './staleness.js' +export { + containsSecrets, + hasGhCli, + metaToMarkdown, + resolveFrequency, + submitFeedback, + submitMetaFeedback, + toMarkdown, + validateMetaPayload, + validatePayload, +} from './feedback.js' +export { findSkillFiles, parseFrontmatter } from './utils.js' +export { runSetup } from './setup.js' +export type { + AgentName, + FeedbackPayload, + IntentConfig, + IntentPackage, + IntentProjectConfig, + MetaFeedbackPayload, + MetaSkillName, + ScanResult, + SkillEntry, + StalenessReport, + SkillStaleness, +} from './types.js' diff --git a/packages/intent/src/intent-library.ts b/packages/intent/src/intent-library.ts index 8f930435..916f3bd6 100644 --- a/packages/intent/src/intent-library.ts +++ b/packages/intent/src/intent-library.ts @@ -1,147 +1,147 @@ -#!/usr/bin/env node - -import { computeSkillNameWidth, printSkillTree, printTable } from './display.js' -import type { LibraryScanResult } from './library-scanner.js' -import { scanLibrary } from './library-scanner.js' - -// --------------------------------------------------------------------------- -// Commands -// --------------------------------------------------------------------------- - -async function cmdList(): Promise { - let result: LibraryScanResult - try { - result = await scanLibrary(process.argv[1]!) - } catch (err) { - console.error((err as Error).message) - process.exit(1) - } - - if (result.packages.length === 0) { - console.log('No intent-enabled packages found.') - if (result.warnings.length > 0) { - console.log('\nWarnings:') - for (const w of result.warnings) console.log(` ⚠ ${w}`) - } - return - } - - const totalSkills = result.packages.reduce( - (sum, p) => sum + p.skills.length, - 0, - ) - console.log( - `\n${result.packages.length} intent-enabled packages, ${totalSkills} skills\n`, - ) - - // Summary table - const rows = result.packages.map((pkg) => [ - pkg.name, - pkg.version, - String(pkg.skills.length), - ]) - printTable(['PACKAGE', 'VERSION', 'SKILLS'], rows) - - // Skills detail - const allSkills = result.packages.map((p) => p.skills) - const nameWidth = computeSkillNameWidth(allSkills) - const showTypes = result.packages.some((p) => p.skills.some((s) => s.type)) - - console.log(`\nSkills:\n`) - for (const pkg of result.packages) { - console.log(` ${pkg.name}`) - printSkillTree(pkg.skills, { nameWidth, showTypes }) - console.log() - } - - console.log(`Feedback:`) - console.log( - ` Submit feedback on skill usage to help maintainers improve the skills.`, - ) - console.log( - ` Load: node_modules/@tanstack/intent/meta/feedback-collection/SKILL.md`, - ) - console.log() - - if (result.warnings.length > 0) { - console.log(`Warnings:`) - for (const w of result.warnings) console.log(` ⚠ ${w}`) - } -} - -function cmdInstall(): void { - const prompt = `You are an AI assistant helping a developer set up skill-to-task mappings for their project. - -Follow these steps in order: - -1. CHECK FOR EXISTING MAPPINGS - Search the project's agent config files (CLAUDE.md, AGENTS.md, .cursorrules, - .github/copilot-instructions.md) for a block delimited by: - - - - If found: show the user the current mappings and ask "What would you like to update?" - Then skip to step 4 with their requested changes. - - If not found: continue to step 2. - -2. DISCOVER AVAILABLE SKILLS - Run: intent list - This outputs each skill's name, description, and full path — grouped by package. - -3. SCAN THE REPOSITORY - Build a picture of the project's structure and patterns: - - Read package.json for library dependencies - - Survey the directory layout (src/, app/, routes/, components/, api/, etc.) - - Note recurring patterns (routing, data fetching, auth, UI components, etc.) - - Based on this, propose 3–5 skill-to-task mappings. For each one explain: - - The task or code area (in plain language the user would recognise) - - Which skill applies and why - - Then ask: "What other tasks do you commonly use AI coding agents for? - I'll create mappings for those too." - -4. WRITE THE MAPPINGS BLOCK - Once you have the full set of mappings, write or update the agent config file - (prefer CLAUDE.md; create it if none exists) with this exact block: - - -# Skill mappings — when working in these areas, load the linked skill file into context. -skills: - - task: "describe the task or code area here" - load: "node_modules/package-name/skills/skill-name/SKILL.md" - - - Rules: - - Use the user's own words for task descriptions - - Include the exact path from \`intent list\` output so agents can load it directly - - Keep entries concise — this block is read on every agent task - - Preserve all content outside the block tags unchanged` - - console.log(prompt) -} - -// --------------------------------------------------------------------------- -// Main -// --------------------------------------------------------------------------- - -const USAGE = `TanStack Intent - -Usage: - intent list List all available skills from this library and its dependencies - intent install Print a skill that guides your coding agent to scan the project - and set up skill-to-task mappings in your agent config` - -const command = process.argv[2] - -switch (command) { - case 'list': - case undefined: - await cmdList() - break - case 'install': - cmdInstall() - break - default: - console.log(USAGE) - process.exit(command ? 1 : 0) -} +#!/usr/bin/env node + +import { computeSkillNameWidth, printSkillTree, printTable } from './display.js' +import type { LibraryScanResult } from './library-scanner.js' +import { scanLibrary } from './library-scanner.js' + +// --------------------------------------------------------------------------- +// Commands +// --------------------------------------------------------------------------- + +async function cmdList(): Promise { + let result: LibraryScanResult + try { + result = await scanLibrary(process.argv[1]!) + } catch (err) { + console.error((err as Error).message) + process.exit(1) + } + + if (result.packages.length === 0) { + console.log('No intent-enabled packages found.') + if (result.warnings.length > 0) { + console.log('\nWarnings:') + for (const w of result.warnings) console.log(` ⚠ ${w}`) + } + return + } + + const totalSkills = result.packages.reduce( + (sum, p) => sum + p.skills.length, + 0, + ) + console.log( + `\n${result.packages.length} intent-enabled packages, ${totalSkills} skills\n`, + ) + + // Summary table + const rows = result.packages.map((pkg) => [ + pkg.name, + pkg.version, + String(pkg.skills.length), + ]) + printTable(['PACKAGE', 'VERSION', 'SKILLS'], rows) + + // Skills detail + const allSkills = result.packages.map((p) => p.skills) + const nameWidth = computeSkillNameWidth(allSkills) + const showTypes = result.packages.some((p) => p.skills.some((s) => s.type)) + + console.log(`\nSkills:\n`) + for (const pkg of result.packages) { + console.log(` ${pkg.name}`) + printSkillTree(pkg.skills, { nameWidth, showTypes }) + console.log() + } + + console.log(`Feedback:`) + console.log( + ` Submit feedback on skill usage to help maintainers improve the skills.`, + ) + console.log( + ` Load: node_modules/@tanstack/intent/meta/feedback-collection/SKILL.md`, + ) + console.log() + + if (result.warnings.length > 0) { + console.log(`Warnings:`) + for (const w of result.warnings) console.log(` ⚠ ${w}`) + } +} + +function cmdInstall(): void { + const prompt = `You are an AI assistant helping a developer set up skill-to-task mappings for their project. + +Follow these steps in order: + +1. CHECK FOR EXISTING MAPPINGS + Search the project's agent config files (CLAUDE.md, AGENTS.md, .cursorrules, + .github/copilot-instructions.md) for a block delimited by: + + + - If found: show the user the current mappings and ask "What would you like to update?" + Then skip to step 4 with their requested changes. + - If not found: continue to step 2. + +2. DISCOVER AVAILABLE SKILLS + Run: intent list + This outputs each skill's name, description, and full path — grouped by package. + +3. SCAN THE REPOSITORY + Build a picture of the project's structure and patterns: + - Read package.json for library dependencies + - Survey the directory layout (src/, app/, routes/, components/, api/, etc.) + - Note recurring patterns (routing, data fetching, auth, UI components, etc.) + + Based on this, propose 3–5 skill-to-task mappings. For each one explain: + - The task or code area (in plain language the user would recognise) + - Which skill applies and why + + Then ask: "What other tasks do you commonly use AI coding agents for? + I'll create mappings for those too." + +4. WRITE THE MAPPINGS BLOCK + Once you have the full set of mappings, write or update the agent config file + (prefer CLAUDE.md; create it if none exists) with this exact block: + + +# Skill mappings — when working in these areas, load the linked skill file into context. +skills: + - task: "describe the task or code area here" + load: "node_modules/package-name/skills/skill-name/SKILL.md" + + + Rules: + - Use the user's own words for task descriptions + - Include the exact path from \`intent list\` output so agents can load it directly + - Keep entries concise — this block is read on every agent task + - Preserve all content outside the block tags unchanged` + + console.log(prompt) +} + +// --------------------------------------------------------------------------- +// Main +// --------------------------------------------------------------------------- + +const USAGE = `TanStack Intent + +Usage: + intent list List all available skills from this library and its dependencies + intent install Print a skill that guides your coding agent to scan the project + and set up skill-to-task mappings in your agent config` + +const command = process.argv[2] + +switch (command) { + case 'list': + case undefined: + await cmdList() + break + case 'install': + cmdInstall() + break + default: + console.log(USAGE) + process.exit(command ? 1 : 0) +} diff --git a/packages/intent/src/library-scanner.ts b/packages/intent/src/library-scanner.ts index 4ca7beea..0ff96507 100644 --- a/packages/intent/src/library-scanner.ts +++ b/packages/intent/src/library-scanner.ts @@ -1,159 +1,159 @@ -import type { Dirent } from 'node:fs' -import { existsSync, readdirSync, readFileSync } from 'node:fs' -import { dirname, join, relative, sep } from 'node:path' -import type { SkillEntry } from './types.js' -import { parseFrontmatter } from './utils.js' - -// --------------------------------------------------------------------------- -// Types -// --------------------------------------------------------------------------- - -export interface LibraryPackage { - name: string - version: string - description: string - skills: SkillEntry[] -} - -export interface LibraryScanResult { - packages: LibraryPackage[] - warnings: string[] -} - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -function readPkgJson(dir: string): Record | null { - try { - return JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) - } catch { - return null - } -} - -function findHomeDir(scriptPath: string): string | null { - let dir = dirname(scriptPath) - while (true) { - if (existsSync(join(dir, 'package.json'))) return dir - const parent = dirname(dir) - if (parent === dir) return null - dir = parent - } -} - -function hasIntentBin(pkg: Record): boolean { - const bin = pkg.bin - if (!bin || typeof bin !== 'object') return false - return 'intent' in (bin as Record) -} - -function getDeps(pkg: Record): string[] { - const seen = new Set() - for (const field of ['dependencies', 'peerDependencies']) { - const d = pkg[field] - if (d && typeof d === 'object') { - for (const name of Object.keys(d as Record)) { - seen.add(name) - } - } - } - return [...seen] -} - -function discoverSkills(skillsDir: string): SkillEntry[] { - const skills: SkillEntry[] = [] - - function walk(dir: string): void { - let entries: Dirent[] - try { - entries = readdirSync(dir, { withFileTypes: true, encoding: 'utf8' }) - } catch { - return - } - for (const entry of entries) { - if (!entry.isDirectory()) continue - const childDir = join(dir, entry.name) - const skillFile = join(childDir, 'SKILL.md') - if (existsSync(skillFile)) { - const fm = parseFrontmatter(skillFile) - const relName = relative(skillsDir, childDir).split(sep).join('/') - skills.push({ - name: typeof fm?.name === 'string' ? fm.name : relName, - path: skillFile, - description: - typeof fm?.description === 'string' - ? fm.description.replace(/\s+/g, ' ').trim() - : '', - type: typeof fm?.type === 'string' ? fm.type : undefined, - framework: - typeof fm?.framework === 'string' ? fm.framework : undefined, - }) - walk(childDir) - } - } - } - - walk(skillsDir) - return skills -} - -// --------------------------------------------------------------------------- -// Main scanner -// --------------------------------------------------------------------------- - -export async function scanLibrary( - scriptPath: string, - projectRoot?: string, -): Promise { - const nodeModulesDir = join(projectRoot ?? process.cwd(), 'node_modules') - const packages: LibraryPackage[] = [] - const warnings: string[] = [] - const visited = new Set() - - const homeDir = findHomeDir(scriptPath) - if (!homeDir) { - return { - packages, - warnings: ['Could not determine home package directory'], - } - } - - const homePkg = readPkgJson(homeDir) - if (!homePkg) { - return { packages, warnings: ['Could not read home package.json'] } - } - - const homeName = typeof homePkg.name === 'string' ? homePkg.name : '' - - function processPackage(name: string, dir: string): void { - if (visited.has(name)) return - visited.add(name) - - const pkg = readPkgJson(dir) - if (!pkg) { - warnings.push(`Could not read package.json for ${name}`) - return - } - - const skillsDir = join(dir, 'skills') - packages.push({ - name, - version: typeof pkg.version === 'string' ? pkg.version : '0.0.0', - description: typeof pkg.description === 'string' ? pkg.description : '', - skills: existsSync(skillsDir) ? discoverSkills(skillsDir) : [], - }) - - for (const depName of getDeps(pkg)) { - const depDir = join(nodeModulesDir, depName) - if (!existsSync(depDir)) continue - const depPkg = readPkgJson(depDir) - if (depPkg && hasIntentBin(depPkg)) { - processPackage(depName, depDir) - } - } - } - - processPackage(homeName, homeDir) - return { packages, warnings } -} +import type { Dirent } from 'node:fs' +import { existsSync, readdirSync, readFileSync } from 'node:fs' +import { dirname, join, relative, sep } from 'node:path' +import type { SkillEntry } from './types.js' +import { parseFrontmatter } from './utils.js' + +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + +export interface LibraryPackage { + name: string + version: string + description: string + skills: SkillEntry[] +} + +export interface LibraryScanResult { + packages: LibraryPackage[] + warnings: string[] +} + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +function readPkgJson(dir: string): Record | null { + try { + return JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) + } catch { + return null + } +} + +function findHomeDir(scriptPath: string): string | null { + let dir = dirname(scriptPath) + while (true) { + if (existsSync(join(dir, 'package.json'))) return dir + const parent = dirname(dir) + if (parent === dir) return null + dir = parent + } +} + +function hasIntentBin(pkg: Record): boolean { + const bin = pkg.bin + if (!bin || typeof bin !== 'object') return false + return 'intent' in (bin as Record) +} + +function getDeps(pkg: Record): string[] { + const seen = new Set() + for (const field of ['dependencies', 'peerDependencies']) { + const d = pkg[field] + if (d && typeof d === 'object') { + for (const name of Object.keys(d as Record)) { + seen.add(name) + } + } + } + return [...seen] +} + +function discoverSkills(skillsDir: string): SkillEntry[] { + const skills: SkillEntry[] = [] + + function walk(dir: string): void { + let entries: Dirent[] + try { + entries = readdirSync(dir, { withFileTypes: true, encoding: 'utf8' }) + } catch { + return + } + for (const entry of entries) { + if (!entry.isDirectory()) continue + const childDir = join(dir, entry.name) + const skillFile = join(childDir, 'SKILL.md') + if (existsSync(skillFile)) { + const fm = parseFrontmatter(skillFile) + const relName = relative(skillsDir, childDir).split(sep).join('/') + skills.push({ + name: typeof fm?.name === 'string' ? fm.name : relName, + path: skillFile, + description: + typeof fm?.description === 'string' + ? fm.description.replace(/\s+/g, ' ').trim() + : '', + type: typeof fm?.type === 'string' ? fm.type : undefined, + framework: + typeof fm?.framework === 'string' ? fm.framework : undefined, + }) + walk(childDir) + } + } + } + + walk(skillsDir) + return skills +} + +// --------------------------------------------------------------------------- +// Main scanner +// --------------------------------------------------------------------------- + +export async function scanLibrary( + scriptPath: string, + projectRoot?: string, +): Promise { + const nodeModulesDir = join(projectRoot ?? process.cwd(), 'node_modules') + const packages: LibraryPackage[] = [] + const warnings: string[] = [] + const visited = new Set() + + const homeDir = findHomeDir(scriptPath) + if (!homeDir) { + return { + packages, + warnings: ['Could not determine home package directory'], + } + } + + const homePkg = readPkgJson(homeDir) + if (!homePkg) { + return { packages, warnings: ['Could not read home package.json'] } + } + + const homeName = typeof homePkg.name === 'string' ? homePkg.name : '' + + function processPackage(name: string, dir: string): void { + if (visited.has(name)) return + visited.add(name) + + const pkg = readPkgJson(dir) + if (!pkg) { + warnings.push(`Could not read package.json for ${name}`) + return + } + + const skillsDir = join(dir, 'skills') + packages.push({ + name, + version: typeof pkg.version === 'string' ? pkg.version : '0.0.0', + description: typeof pkg.description === 'string' ? pkg.description : '', + skills: existsSync(skillsDir) ? discoverSkills(skillsDir) : [], + }) + + for (const depName of getDeps(pkg)) { + const depDir = join(nodeModulesDir, depName) + if (!existsSync(depDir)) continue + const depPkg = readPkgJson(depDir) + if (depPkg && hasIntentBin(depPkg)) { + processPackage(depName, depDir) + } + } + } + + processPackage(homeName, homeDir) + return { packages, warnings } +} diff --git a/packages/intent/src/scanner.ts b/packages/intent/src/scanner.ts index 7985fcaf..a5ec4520 100644 --- a/packages/intent/src/scanner.ts +++ b/packages/intent/src/scanner.ts @@ -1,285 +1,285 @@ -import type { Dirent } from 'node:fs' -import { existsSync, readdirSync, readFileSync } from 'node:fs' -import { join, relative, sep } from 'node:path' -import type { - IntentConfig, - IntentPackage, - ScanResult, - SkillEntry, -} from './types.js' -import { parseFrontmatter } from './utils.js' - -// --------------------------------------------------------------------------- -// Package manager detection -// --------------------------------------------------------------------------- - -type PackageManager = ScanResult['packageManager'] - -function detectPackageManager(root: string): PackageManager { - // Check for unsupported environments first - if (existsSync(join(root, '.pnp.cjs')) || existsSync(join(root, '.pnp.js'))) { - throw new Error( - 'Yarn PnP is not yet supported. Add `nodeLinker: node-modules` to your .yarnrc.yml to use intent.', - ) - } - if ( - existsSync(join(root, 'deno.json')) && - !existsSync(join(root, 'node_modules')) - ) { - throw new Error( - 'Deno without node_modules is not yet supported. Add `"nodeModulesDir": "auto"` to your deno.json to use intent.', - ) - } - - if (existsSync(join(root, 'pnpm-lock.yaml'))) return 'pnpm' - if (existsSync(join(root, 'bun.lockb')) || existsSync(join(root, 'bun.lock'))) - return 'bun' - if (existsSync(join(root, 'yarn.lock'))) return 'yarn' - if (existsSync(join(root, 'package-lock.json'))) return 'npm' - return 'unknown' -} - -// --------------------------------------------------------------------------- -// Intent field validation -// --------------------------------------------------------------------------- - -function validateIntentField( - _pkgName: string, - intent: unknown, -): IntentConfig | null { - if (!intent || typeof intent !== 'object') return null - const pb = intent as Record - - if (pb.version !== 1) return null - if (typeof pb.repo !== 'string' || !pb.repo) return null - if (typeof pb.docs !== 'string' || !pb.docs) return null - - const requires = Array.isArray(pb.requires) - ? pb.requires.filter((r): r is string => typeof r === 'string') - : undefined - - return { - version: 1, - repo: pb.repo, - docs: pb.docs, - requires, - } -} - -/** - * Derive an IntentConfig from standard package.json fields when no explicit - * `intent` field is present. A package with a `skills/` directory signals - * intent support; `repo` and `docs` are derived from `repository` and - * `homepage`. - */ -function deriveIntentConfig( - pkgJson: Record, -): IntentConfig | null { - // Derive repo from repository field - let repo: string | null = null - if (typeof pkgJson.repository === 'string') { - repo = pkgJson.repository - } else if ( - pkgJson.repository && - typeof pkgJson.repository === 'object' && - typeof (pkgJson.repository as Record).url === 'string' - ) { - repo = (pkgJson.repository as Record).url as string - // Normalize git+https://github.com/foo/bar.git → foo/bar - repo = repo - .replace(/^git\+/, '') - .replace(/\.git$/, '') - .replace(/^https?:\/\/github\.com\//, '') - } - - // Derive docs from homepage field - const docs = - typeof pkgJson.homepage === 'string' ? pkgJson.homepage : undefined - - // Need at least a repo to be useful - if (!repo) return null - - // Derive requires from intent.requires if partially present - const intentPartial = pkgJson.intent as Record | undefined - const requires = - intentPartial && Array.isArray(intentPartial.requires) - ? intentPartial.requires.filter((r): r is string => typeof r === 'string') - : undefined - - return { - version: 1, - repo, - docs: docs ?? '', - requires, - } -} - -// --------------------------------------------------------------------------- -// Skill discovery within a package -// --------------------------------------------------------------------------- - -function discoverSkills(skillsDir: string, _baseName: string): SkillEntry[] { - const skills: SkillEntry[] = [] - - function walk(dir: string): void { - let entries: Dirent[] - try { - entries = readdirSync(dir, { withFileTypes: true, encoding: 'utf8' }) - } catch { - return - } - for (const entry of entries) { - if (!entry.isDirectory()) continue - const childDir = join(dir, entry.name) - const skillFile = join(childDir, 'SKILL.md') - if (existsSync(skillFile)) { - const fm = parseFrontmatter(skillFile) - const relName = relative(skillsDir, childDir).split(sep).join('/') - const desc = - typeof fm?.description === 'string' - ? fm.description.replace(/\s+/g, ' ').trim() - : '' - skills.push({ - name: typeof fm?.name === 'string' ? fm.name : relName, - path: skillFile, - description: desc, - type: typeof fm?.type === 'string' ? fm.type : undefined, - framework: - typeof fm?.framework === 'string' ? fm.framework : undefined, - }) - // Recurse for sub-skills - walk(childDir) - } - } - } - - walk(skillsDir) - return skills -} - -// --------------------------------------------------------------------------- -// Topological sort on requires -// --------------------------------------------------------------------------- - -function topoSort(packages: IntentPackage[]): IntentPackage[] { - const byName = new Map(packages.map((p) => [p.name, p])) - const visited = new Set() - const sorted: IntentPackage[] = [] - - function visit(name: string): void { - if (visited.has(name)) return - visited.add(name) - const pkg = byName.get(name) - if (!pkg) return - for (const dep of pkg.intent.requires ?? []) { - visit(dep) - } - sorted.push(pkg) - } - - for (const pkg of packages) { - visit(pkg.name) - } - return sorted -} - -// --------------------------------------------------------------------------- -// Main scanner -// --------------------------------------------------------------------------- - -export async function scanForIntents(root?: string): Promise { - const projectRoot = root ?? process.cwd() - const packageManager = detectPackageManager(projectRoot) - const nodeModulesDir = join(projectRoot, 'node_modules') - - const packages: IntentPackage[] = [] - const warnings: string[] = [] - - if (!existsSync(nodeModulesDir)) { - return { packageManager, packages, warnings } - } - - // Collect all package directories to check - const packageDirs: Array<{ dirPath: string }> = [] - - let topEntries: Dirent[] - try { - topEntries = readdirSync(nodeModulesDir, { - withFileTypes: true, - encoding: 'utf8', - }) - } catch { - return { packageManager, packages, warnings } - } - - for (const entry of topEntries) { - if (!entry.isDirectory()) continue - const dirPath = join(nodeModulesDir, entry.name) - - if (entry.name.startsWith('@')) { - // Scoped package — check children - let scopedEntries: Dirent[] - try { - scopedEntries = readdirSync(dirPath, { - withFileTypes: true, - encoding: 'utf8', - }) - } catch { - continue - } - for (const scoped of scopedEntries) { - if (!scoped.isDirectory()) continue - packageDirs.push({ dirPath: join(dirPath, scoped.name) }) - } - } else if (!entry.name.startsWith('.')) { - packageDirs.push({ dirPath }) - } - } - - // Check each package for skills/ - for (const { dirPath } of packageDirs) { - const skillsDir = join(dirPath, 'skills') - if (!existsSync(skillsDir)) continue - - // Has skills/ — read package.json - const pkgJsonPath = join(dirPath, 'package.json') - let pkgJson: Record - try { - pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8')) - } catch { - warnings.push(`Could not read package.json for ${dirPath}`) - continue - } - - const pkgName = typeof pkgJson.name === 'string' ? pkgJson.name : 'unknown' - const pkgVersion = - typeof pkgJson.version === 'string' ? pkgJson.version : '0.0.0' - - // Validate intent field — explicit config takes priority, then derive from - // standard package.json fields (repository, homepage) - const intent = - validateIntentField(pkgName, pkgJson.intent) ?? - deriveIntentConfig(pkgJson) - if (!intent) { - warnings.push( - `${pkgName} has a skills/ directory but could not determine repo/docs from package.json (add a "repository" field or explicit "intent" config)`, - ) - continue - } - - // Discover skills - const skills = discoverSkills(skillsDir, pkgName) - - packages.push({ - name: pkgName, - version: pkgVersion, - intent, - skills, - }) - } - - // Sort by dependency order - const sorted = topoSort(packages) - - return { packageManager, packages: sorted, warnings } -} +import type { Dirent } from 'node:fs' +import { existsSync, readdirSync, readFileSync } from 'node:fs' +import { join, relative, sep } from 'node:path' +import type { + IntentConfig, + IntentPackage, + ScanResult, + SkillEntry, +} from './types.js' +import { parseFrontmatter } from './utils.js' + +// --------------------------------------------------------------------------- +// Package manager detection +// --------------------------------------------------------------------------- + +type PackageManager = ScanResult['packageManager'] + +function detectPackageManager(root: string): PackageManager { + // Check for unsupported environments first + if (existsSync(join(root, '.pnp.cjs')) || existsSync(join(root, '.pnp.js'))) { + throw new Error( + 'Yarn PnP is not yet supported. Add `nodeLinker: node-modules` to your .yarnrc.yml to use intent.', + ) + } + if ( + existsSync(join(root, 'deno.json')) && + !existsSync(join(root, 'node_modules')) + ) { + throw new Error( + 'Deno without node_modules is not yet supported. Add `"nodeModulesDir": "auto"` to your deno.json to use intent.', + ) + } + + if (existsSync(join(root, 'pnpm-lock.yaml'))) return 'pnpm' + if (existsSync(join(root, 'bun.lockb')) || existsSync(join(root, 'bun.lock'))) + return 'bun' + if (existsSync(join(root, 'yarn.lock'))) return 'yarn' + if (existsSync(join(root, 'package-lock.json'))) return 'npm' + return 'unknown' +} + +// --------------------------------------------------------------------------- +// Intent field validation +// --------------------------------------------------------------------------- + +function validateIntentField( + _pkgName: string, + intent: unknown, +): IntentConfig | null { + if (!intent || typeof intent !== 'object') return null + const pb = intent as Record + + if (pb.version !== 1) return null + if (typeof pb.repo !== 'string' || !pb.repo) return null + if (typeof pb.docs !== 'string' || !pb.docs) return null + + const requires = Array.isArray(pb.requires) + ? pb.requires.filter((r): r is string => typeof r === 'string') + : undefined + + return { + version: 1, + repo: pb.repo, + docs: pb.docs, + requires, + } +} + +/** + * Derive an IntentConfig from standard package.json fields when no explicit + * `intent` field is present. A package with a `skills/` directory signals + * intent support; `repo` and `docs` are derived from `repository` and + * `homepage`. + */ +function deriveIntentConfig( + pkgJson: Record, +): IntentConfig | null { + // Derive repo from repository field + let repo: string | null = null + if (typeof pkgJson.repository === 'string') { + repo = pkgJson.repository + } else if ( + pkgJson.repository && + typeof pkgJson.repository === 'object' && + typeof (pkgJson.repository as Record).url === 'string' + ) { + repo = (pkgJson.repository as Record).url as string + // Normalize git+https://github.com/foo/bar.git → foo/bar + repo = repo + .replace(/^git\+/, '') + .replace(/\.git$/, '') + .replace(/^https?:\/\/github\.com\//, '') + } + + // Derive docs from homepage field + const docs = + typeof pkgJson.homepage === 'string' ? pkgJson.homepage : undefined + + // Need at least a repo to be useful + if (!repo) return null + + // Derive requires from intent.requires if partially present + const intentPartial = pkgJson.intent as Record | undefined + const requires = + intentPartial && Array.isArray(intentPartial.requires) + ? intentPartial.requires.filter((r): r is string => typeof r === 'string') + : undefined + + return { + version: 1, + repo, + docs: docs ?? '', + requires, + } +} + +// --------------------------------------------------------------------------- +// Skill discovery within a package +// --------------------------------------------------------------------------- + +function discoverSkills(skillsDir: string, _baseName: string): SkillEntry[] { + const skills: SkillEntry[] = [] + + function walk(dir: string): void { + let entries: Dirent[] + try { + entries = readdirSync(dir, { withFileTypes: true, encoding: 'utf8' }) + } catch { + return + } + for (const entry of entries) { + if (!entry.isDirectory()) continue + const childDir = join(dir, entry.name) + const skillFile = join(childDir, 'SKILL.md') + if (existsSync(skillFile)) { + const fm = parseFrontmatter(skillFile) + const relName = relative(skillsDir, childDir).split(sep).join('/') + const desc = + typeof fm?.description === 'string' + ? fm.description.replace(/\s+/g, ' ').trim() + : '' + skills.push({ + name: typeof fm?.name === 'string' ? fm.name : relName, + path: skillFile, + description: desc, + type: typeof fm?.type === 'string' ? fm.type : undefined, + framework: + typeof fm?.framework === 'string' ? fm.framework : undefined, + }) + // Recurse for sub-skills + walk(childDir) + } + } + } + + walk(skillsDir) + return skills +} + +// --------------------------------------------------------------------------- +// Topological sort on requires +// --------------------------------------------------------------------------- + +function topoSort(packages: IntentPackage[]): IntentPackage[] { + const byName = new Map(packages.map((p) => [p.name, p])) + const visited = new Set() + const sorted: IntentPackage[] = [] + + function visit(name: string): void { + if (visited.has(name)) return + visited.add(name) + const pkg = byName.get(name) + if (!pkg) return + for (const dep of pkg.intent.requires ?? []) { + visit(dep) + } + sorted.push(pkg) + } + + for (const pkg of packages) { + visit(pkg.name) + } + return sorted +} + +// --------------------------------------------------------------------------- +// Main scanner +// --------------------------------------------------------------------------- + +export async function scanForIntents(root?: string): Promise { + const projectRoot = root ?? process.cwd() + const packageManager = detectPackageManager(projectRoot) + const nodeModulesDir = join(projectRoot, 'node_modules') + + const packages: IntentPackage[] = [] + const warnings: string[] = [] + + if (!existsSync(nodeModulesDir)) { + return { packageManager, packages, warnings } + } + + // Collect all package directories to check + const packageDirs: Array<{ dirPath: string }> = [] + + let topEntries: Dirent[] + try { + topEntries = readdirSync(nodeModulesDir, { + withFileTypes: true, + encoding: 'utf8', + }) + } catch { + return { packageManager, packages, warnings } + } + + for (const entry of topEntries) { + if (!entry.isDirectory()) continue + const dirPath = join(nodeModulesDir, entry.name) + + if (entry.name.startsWith('@')) { + // Scoped package — check children + let scopedEntries: Dirent[] + try { + scopedEntries = readdirSync(dirPath, { + withFileTypes: true, + encoding: 'utf8', + }) + } catch { + continue + } + for (const scoped of scopedEntries) { + if (!scoped.isDirectory()) continue + packageDirs.push({ dirPath: join(dirPath, scoped.name) }) + } + } else if (!entry.name.startsWith('.')) { + packageDirs.push({ dirPath }) + } + } + + // Check each package for skills/ + for (const { dirPath } of packageDirs) { + const skillsDir = join(dirPath, 'skills') + if (!existsSync(skillsDir)) continue + + // Has skills/ — read package.json + const pkgJsonPath = join(dirPath, 'package.json') + let pkgJson: Record + try { + pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8')) + } catch { + warnings.push(`Could not read package.json for ${dirPath}`) + continue + } + + const pkgName = typeof pkgJson.name === 'string' ? pkgJson.name : 'unknown' + const pkgVersion = + typeof pkgJson.version === 'string' ? pkgJson.version : '0.0.0' + + // Validate intent field — explicit config takes priority, then derive from + // standard package.json fields (repository, homepage) + const intent = + validateIntentField(pkgName, pkgJson.intent) ?? + deriveIntentConfig(pkgJson) + if (!intent) { + warnings.push( + `${pkgName} has a skills/ directory but could not determine repo/docs from package.json (add a "repository" field or explicit "intent" config)`, + ) + continue + } + + // Discover skills + const skills = discoverSkills(skillsDir, pkgName) + + packages.push({ + name: pkgName, + version: pkgVersion, + intent, + skills, + }) + } + + // Sort by dependency order + const sorted = topoSort(packages) + + return { packageManager, packages: sorted, warnings } +} diff --git a/packages/intent/src/setup.ts b/packages/intent/src/setup.ts index f1a50e83..b6b64f5c 100644 --- a/packages/intent/src/setup.ts +++ b/packages/intent/src/setup.ts @@ -1,225 +1,225 @@ -import { - existsSync, - mkdirSync, - readFileSync, - readdirSync, - writeFileSync, -} from 'node:fs' -import { join } from 'node:path' - -// --------------------------------------------------------------------------- -// Types -// --------------------------------------------------------------------------- - -export interface SetupResult { - workflows: string[] - skipped: string[] - shim: string | null -} - -interface TemplateVars { - PACKAGE_NAME: string - REPO: string - DOCS_PATH: string - SRC_PATH: string -} - -// --------------------------------------------------------------------------- -// Variable detection from package.json -// --------------------------------------------------------------------------- - -function detectVars(root: string): TemplateVars { - const pkgPath = join(root, 'package.json') - let pkgJson: Record = {} - try { - pkgJson = JSON.parse(readFileSync(pkgPath, 'utf8')) - } catch { - /* fallback to defaults */ - } - - const name = typeof pkgJson.name === 'string' ? pkgJson.name : 'unknown' - const intent = pkgJson.intent as Record | undefined - - const repo = - typeof intent?.repo === 'string' - ? intent.repo - : name.replace(/^@/, '').replace(/\//, '/') - - const docs = typeof intent?.docs === 'string' ? intent.docs : 'docs/' - - // Best-guess src path from common monorepo patterns - const shortName = name.replace(/^@[^/]+\//, '') - let srcPath = `packages/${shortName}/src/**` - if (existsSync(join(root, 'src'))) { - srcPath = 'src/**' - } - - return { - PACKAGE_NAME: name, - REPO: repo, - DOCS_PATH: docs.endsWith('**') ? docs : docs.replace(/\/$/, '') + '/**', - SRC_PATH: srcPath, - } -} - -// --------------------------------------------------------------------------- -// Template variable substitution -// --------------------------------------------------------------------------- - -function applyVars(content: string, vars: TemplateVars): string { - return content - .replace(/\{\{PACKAGE_NAME\}\}/g, vars.PACKAGE_NAME) - .replace(/\{\{REPO\}\}/g, vars.REPO) - .replace(/\{\{DOCS_PATH\}\}/g, vars.DOCS_PATH) - .replace(/\{\{SRC_PATH\}\}/g, vars.SRC_PATH) -} - -// --------------------------------------------------------------------------- -// Copy helpers -// --------------------------------------------------------------------------- - -function copyTemplates( - srcDir: string, - destDir: string, - vars: TemplateVars, -): { copied: string[]; skipped: string[] } { - const copied: string[] = [] - const skipped: string[] = [] - - if (!existsSync(srcDir)) return { copied, skipped } - - mkdirSync(destDir, { recursive: true }) - - for (const entry of readdirSync(srcDir)) { - const srcPath = join(srcDir, entry) - const destPath = join(destDir, entry) - - if (existsSync(destPath)) { - skipped.push(destPath) - continue - } - - const content = readFileSync(srcPath, 'utf8') - const substituted = applyVars(content, vars) - writeFileSync(destPath, substituted) - copied.push(destPath) - } - - return { copied, skipped } -} - -// --------------------------------------------------------------------------- -// Shim generation -// --------------------------------------------------------------------------- - -function getShimContent(ext: string): string { - return `#!/usr/bin/env node -// Auto-generated by @tanstack/intent setup -// Exposes the intent end-user CLI for consumers of this library. -// Commit this file, then add to your package.json: -// "bin": { "intent": "./bin/intent.${ext}" } -await import('@tanstack/intent/intent-library') -` -} - -function detectShimExtension(root: string): string { - try { - const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')) - if (pkg.type === 'module') return 'js' - } catch { - // default to .mjs when package.json is unreadable - } - return 'mjs' -} - -function findExistingShim(root: string): string | null { - const shimJs = join(root, 'bin', 'intent.js') - if (existsSync(shimJs)) return shimJs - - const shimMjs = join(root, 'bin', 'intent.mjs') - if (existsSync(shimMjs)) return shimMjs - - return null -} - -function generateShim(root: string, result: SetupResult): void { - const existingShim = findExistingShim(root) - - if (existingShim) { - result.skipped.push(existingShim) - return - } - - const ext = detectShimExtension(root) - const shimPath = join(root, 'bin', `intent.${ext}`) - mkdirSync(join(root, 'bin'), { recursive: true }) - writeFileSync(shimPath, getShimContent(ext)) - result.shim = shimPath -} - -// --------------------------------------------------------------------------- -// Main -// --------------------------------------------------------------------------- - -export function runSetup( - root: string, - metaDir: string, - args: string[], -): SetupResult { - const doAll = args.includes('--all') - const doWorkflows = doAll || args.includes('--workflows') - const doShim = doAll || args.includes('--shim') - - const noFlagsGiven = !doWorkflows && !doShim - const installWorkflows = doWorkflows || noFlagsGiven - const installShim = doShim || noFlagsGiven - - const vars = detectVars(root) - const result: SetupResult = { - workflows: [], - skipped: [], - shim: null, - } - - const templatesDir = join(metaDir, 'templates') - - if (installWorkflows) { - const srcDir = join(templatesDir, 'workflows') - const destDir = join(root, '.github', 'workflows') - const { copied, skipped } = copyTemplates(srcDir, destDir, vars) - result.workflows = copied - result.skipped.push(...skipped) - } - - if (installShim) { - generateShim(root, result) - } - - // Print results - for (const f of result.workflows) console.log(`✓ Copied workflow: ${f}`) - for (const f of result.skipped) console.log(` Already exists: ${f}`) - - if (result.shim) { - const shimRelative = result.shim.replace(root + '/', './') - console.log(`✓ Generated intent shim: ${result.shim}`) - console.log(`\n Add to your package.json:`) - console.log(` "bin": { "intent": "${shimRelative}" }`) - console.log(`\n Add "bin" to your package.json "files" array.`) - } - - if ( - result.workflows.length === 0 && - result.shim === null && - result.skipped.length === 0 - ) { - console.log('No templates directory found. Is @tanstack/intent installed?') - } else if (result.workflows.length > 0) { - console.log(`\nTemplate variables applied:`) - console.log(` Package: ${vars.PACKAGE_NAME}`) - console.log(` Repo: ${vars.REPO}`) - console.log(` Docs: ${vars.DOCS_PATH}`) - console.log(` Src: ${vars.SRC_PATH}`) - } - - return result -} +import { + existsSync, + mkdirSync, + readFileSync, + readdirSync, + writeFileSync, +} from 'node:fs' +import { join } from 'node:path' + +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + +export interface SetupResult { + workflows: string[] + skipped: string[] + shim: string | null +} + +interface TemplateVars { + PACKAGE_NAME: string + REPO: string + DOCS_PATH: string + SRC_PATH: string +} + +// --------------------------------------------------------------------------- +// Variable detection from package.json +// --------------------------------------------------------------------------- + +function detectVars(root: string): TemplateVars { + const pkgPath = join(root, 'package.json') + let pkgJson: Record = {} + try { + pkgJson = JSON.parse(readFileSync(pkgPath, 'utf8')) + } catch { + /* fallback to defaults */ + } + + const name = typeof pkgJson.name === 'string' ? pkgJson.name : 'unknown' + const intent = pkgJson.intent as Record | undefined + + const repo = + typeof intent?.repo === 'string' + ? intent.repo + : name.replace(/^@/, '').replace(/\//, '/') + + const docs = typeof intent?.docs === 'string' ? intent.docs : 'docs/' + + // Best-guess src path from common monorepo patterns + const shortName = name.replace(/^@[^/]+\//, '') + let srcPath = `packages/${shortName}/src/**` + if (existsSync(join(root, 'src'))) { + srcPath = 'src/**' + } + + return { + PACKAGE_NAME: name, + REPO: repo, + DOCS_PATH: docs.endsWith('**') ? docs : docs.replace(/\/$/, '') + '/**', + SRC_PATH: srcPath, + } +} + +// --------------------------------------------------------------------------- +// Template variable substitution +// --------------------------------------------------------------------------- + +function applyVars(content: string, vars: TemplateVars): string { + return content + .replace(/\{\{PACKAGE_NAME\}\}/g, vars.PACKAGE_NAME) + .replace(/\{\{REPO\}\}/g, vars.REPO) + .replace(/\{\{DOCS_PATH\}\}/g, vars.DOCS_PATH) + .replace(/\{\{SRC_PATH\}\}/g, vars.SRC_PATH) +} + +// --------------------------------------------------------------------------- +// Copy helpers +// --------------------------------------------------------------------------- + +function copyTemplates( + srcDir: string, + destDir: string, + vars: TemplateVars, +): { copied: string[]; skipped: string[] } { + const copied: string[] = [] + const skipped: string[] = [] + + if (!existsSync(srcDir)) return { copied, skipped } + + mkdirSync(destDir, { recursive: true }) + + for (const entry of readdirSync(srcDir)) { + const srcPath = join(srcDir, entry) + const destPath = join(destDir, entry) + + if (existsSync(destPath)) { + skipped.push(destPath) + continue + } + + const content = readFileSync(srcPath, 'utf8') + const substituted = applyVars(content, vars) + writeFileSync(destPath, substituted) + copied.push(destPath) + } + + return { copied, skipped } +} + +// --------------------------------------------------------------------------- +// Shim generation +// --------------------------------------------------------------------------- + +function getShimContent(ext: string): string { + return `#!/usr/bin/env node +// Auto-generated by @tanstack/intent setup +// Exposes the intent end-user CLI for consumers of this library. +// Commit this file, then add to your package.json: +// "bin": { "intent": "./bin/intent.${ext}" } +await import('@tanstack/intent/intent-library') +` +} + +function detectShimExtension(root: string): string { + try { + const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')) + if (pkg.type === 'module') return 'js' + } catch { + // default to .mjs when package.json is unreadable + } + return 'mjs' +} + +function findExistingShim(root: string): string | null { + const shimJs = join(root, 'bin', 'intent.js') + if (existsSync(shimJs)) return shimJs + + const shimMjs = join(root, 'bin', 'intent.mjs') + if (existsSync(shimMjs)) return shimMjs + + return null +} + +function generateShim(root: string, result: SetupResult): void { + const existingShim = findExistingShim(root) + + if (existingShim) { + result.skipped.push(existingShim) + return + } + + const ext = detectShimExtension(root) + const shimPath = join(root, 'bin', `intent.${ext}`) + mkdirSync(join(root, 'bin'), { recursive: true }) + writeFileSync(shimPath, getShimContent(ext)) + result.shim = shimPath +} + +// --------------------------------------------------------------------------- +// Main +// --------------------------------------------------------------------------- + +export function runSetup( + root: string, + metaDir: string, + args: string[], +): SetupResult { + const doAll = args.includes('--all') + const doWorkflows = doAll || args.includes('--workflows') + const doShim = doAll || args.includes('--shim') + + const noFlagsGiven = !doWorkflows && !doShim + const installWorkflows = doWorkflows || noFlagsGiven + const installShim = doShim || noFlagsGiven + + const vars = detectVars(root) + const result: SetupResult = { + workflows: [], + skipped: [], + shim: null, + } + + const templatesDir = join(metaDir, 'templates') + + if (installWorkflows) { + const srcDir = join(templatesDir, 'workflows') + const destDir = join(root, '.github', 'workflows') + const { copied, skipped } = copyTemplates(srcDir, destDir, vars) + result.workflows = copied + result.skipped.push(...skipped) + } + + if (installShim) { + generateShim(root, result) + } + + // Print results + for (const f of result.workflows) console.log(`✓ Copied workflow: ${f}`) + for (const f of result.skipped) console.log(` Already exists: ${f}`) + + if (result.shim) { + const shimRelative = result.shim.replace(root + '/', './') + console.log(`✓ Generated intent shim: ${result.shim}`) + console.log(`\n Add to your package.json:`) + console.log(` "bin": { "intent": "${shimRelative}" }`) + console.log(`\n Add "bin" to your package.json "files" array.`) + } + + if ( + result.workflows.length === 0 && + result.shim === null && + result.skipped.length === 0 + ) { + console.log('No templates directory found. Is @tanstack/intent installed?') + } else if (result.workflows.length > 0) { + console.log(`\nTemplate variables applied:`) + console.log(` Package: ${vars.PACKAGE_NAME}`) + console.log(` Repo: ${vars.REPO}`) + console.log(` Docs: ${vars.DOCS_PATH}`) + console.log(` Src: ${vars.SRC_PATH}`) + } + + return result +} diff --git a/packages/intent/src/staleness.ts b/packages/intent/src/staleness.ts index f2c25120..2b04668d 100644 --- a/packages/intent/src/staleness.ts +++ b/packages/intent/src/staleness.ts @@ -1,158 +1,158 @@ -import { readFileSync } from 'node:fs' -import { join, relative, sep } from 'node:path' -import type { StalenessReport, SkillStaleness } from './types.js' -import { findSkillFiles, parseFrontmatter } from './utils.js' - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -interface SkillMeta { - name: string - filePath: string - libraryVersion?: string - sources?: string[] -} - -function classifyVersionDrift( - oldVer: string, - newVer: string, -): 'major' | 'minor' | 'patch' | null { - if (oldVer === newVer) return null - const oldParts = oldVer - .replace(/[^0-9.]/g, '') - .split('.') - .map(Number) - const newParts = newVer - .replace(/[^0-9.]/g, '') - .split('.') - .map(Number) - if ((newParts[0] ?? 0) > (oldParts[0] ?? 0)) return 'major' - if ((newParts[1] ?? 0) > (oldParts[1] ?? 0)) return 'minor' - if ((newParts[2] ?? 0) > (oldParts[2] ?? 0)) return 'patch' - return null -} - -// --------------------------------------------------------------------------- -// npm version fetching -// --------------------------------------------------------------------------- - -async function fetchNpmVersion(packageName: string): Promise { - try { - const res = await fetch( - `https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`, - ) - if (!res.ok) return null - const data = (await res.json()) as Record - return typeof data.version === 'string' ? data.version : null - } catch { - return null - } -} - -// --------------------------------------------------------------------------- -// Sync state -// --------------------------------------------------------------------------- - -interface SyncState { - library_version?: string - skills?: Record }> -} - -function readSyncState(packageDir: string): SyncState | null { - const statePath = join(packageDir, 'skills', 'sync-state.json') - try { - return JSON.parse(readFileSync(statePath, 'utf8')) as SyncState - } catch { - return null - } -} - -// --------------------------------------------------------------------------- -// Main -// --------------------------------------------------------------------------- - -export async function checkStaleness( - packageDir: string, - packageName?: string, -): Promise { - const skillsDir = join(packageDir, 'skills') - const library = packageName ?? 'unknown' - - // Find all skills - const skillFiles = findSkillFiles(skillsDir) - const skillMetas: SkillMeta[] = skillFiles.map((filePath) => { - const fm = parseFrontmatter(filePath) - const relName = relative(skillsDir, filePath) - .replace(/[/\\]SKILL\.md$/, '') - .split(sep) - .join('/') - return { - name: (fm?.name as string) ?? relName, - filePath, - libraryVersion: fm?.library_version as string | undefined, - sources: Array.isArray(fm?.sources) - ? (fm.sources as string[]) - : undefined, - } - }) - - // Get the version from frontmatter (use first skill that has it) - const skillVersion = - skillMetas.find((s) => s.libraryVersion)?.libraryVersion ?? null - - // Fetch current npm version - const currentVersion = await fetchNpmVersion(library) - - // Classify drift - const versionDrift = - skillVersion && currentVersion - ? classifyVersionDrift(skillVersion, currentVersion) - : null - - // Read sync state - const syncState = readSyncState(packageDir) - - // Build per-skill staleness - const skills: SkillStaleness[] = skillMetas.map((skill) => { - const reasons: string[] = [] - - // Version drift - if ( - currentVersion && - skill.libraryVersion && - skill.libraryVersion !== currentVersion - ) { - reasons.push( - `version drift (${skill.libraryVersion} → ${currentVersion})`, - ) - } - - // Source SHA changes (from sync-state) - const storedShas = syncState?.skills?.[skill.name]?.sources_sha ?? {} - // We only flag if there are stored SHAs but we can't check remote - // (actual remote checking requires GitHub API — deferred to agent) - if (skill.sources && Object.keys(storedShas).length > 0) { - // Mark sources as needing review — agent will do the actual comparison - for (const source of skill.sources) { - if (!storedShas[source]) { - reasons.push(`new source (${source})`) - } - } - } - - return { - name: skill.name, - reasons, - needsReview: reasons.length > 0, - } - }) - - return { - library, - currentVersion, - skillVersion, - versionDrift, - skills, - } -} +import { readFileSync } from 'node:fs' +import { join, relative, sep } from 'node:path' +import type { StalenessReport, SkillStaleness } from './types.js' +import { findSkillFiles, parseFrontmatter } from './utils.js' + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +interface SkillMeta { + name: string + filePath: string + libraryVersion?: string + sources?: string[] +} + +function classifyVersionDrift( + oldVer: string, + newVer: string, +): 'major' | 'minor' | 'patch' | null { + if (oldVer === newVer) return null + const oldParts = oldVer + .replace(/[^0-9.]/g, '') + .split('.') + .map(Number) + const newParts = newVer + .replace(/[^0-9.]/g, '') + .split('.') + .map(Number) + if ((newParts[0] ?? 0) > (oldParts[0] ?? 0)) return 'major' + if ((newParts[1] ?? 0) > (oldParts[1] ?? 0)) return 'minor' + if ((newParts[2] ?? 0) > (oldParts[2] ?? 0)) return 'patch' + return null +} + +// --------------------------------------------------------------------------- +// npm version fetching +// --------------------------------------------------------------------------- + +async function fetchNpmVersion(packageName: string): Promise { + try { + const res = await fetch( + `https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`, + ) + if (!res.ok) return null + const data = (await res.json()) as Record + return typeof data.version === 'string' ? data.version : null + } catch { + return null + } +} + +// --------------------------------------------------------------------------- +// Sync state +// --------------------------------------------------------------------------- + +interface SyncState { + library_version?: string + skills?: Record }> +} + +function readSyncState(packageDir: string): SyncState | null { + const statePath = join(packageDir, 'skills', 'sync-state.json') + try { + return JSON.parse(readFileSync(statePath, 'utf8')) as SyncState + } catch { + return null + } +} + +// --------------------------------------------------------------------------- +// Main +// --------------------------------------------------------------------------- + +export async function checkStaleness( + packageDir: string, + packageName?: string, +): Promise { + const skillsDir = join(packageDir, 'skills') + const library = packageName ?? 'unknown' + + // Find all skills + const skillFiles = findSkillFiles(skillsDir) + const skillMetas: SkillMeta[] = skillFiles.map((filePath) => { + const fm = parseFrontmatter(filePath) + const relName = relative(skillsDir, filePath) + .replace(/[/\\]SKILL\.md$/, '') + .split(sep) + .join('/') + return { + name: (fm?.name as string) ?? relName, + filePath, + libraryVersion: fm?.library_version as string | undefined, + sources: Array.isArray(fm?.sources) + ? (fm.sources as string[]) + : undefined, + } + }) + + // Get the version from frontmatter (use first skill that has it) + const skillVersion = + skillMetas.find((s) => s.libraryVersion)?.libraryVersion ?? null + + // Fetch current npm version + const currentVersion = await fetchNpmVersion(library) + + // Classify drift + const versionDrift = + skillVersion && currentVersion + ? classifyVersionDrift(skillVersion, currentVersion) + : null + + // Read sync state + const syncState = readSyncState(packageDir) + + // Build per-skill staleness + const skills: SkillStaleness[] = skillMetas.map((skill) => { + const reasons: string[] = [] + + // Version drift + if ( + currentVersion && + skill.libraryVersion && + skill.libraryVersion !== currentVersion + ) { + reasons.push( + `version drift (${skill.libraryVersion} → ${currentVersion})`, + ) + } + + // Source SHA changes (from sync-state) + const storedShas = syncState?.skills?.[skill.name]?.sources_sha ?? {} + // We only flag if there are stored SHAs but we can't check remote + // (actual remote checking requires GitHub API — deferred to agent) + if (skill.sources && Object.keys(storedShas).length > 0) { + // Mark sources as needing review — agent will do the actual comparison + for (const source of skill.sources) { + if (!storedShas[source]) { + reasons.push(`new source (${source})`) + } + } + } + + return { + name: skill.name, + reasons, + needsReview: reasons.length > 0, + } + }) + + return { + library, + currentVersion, + skillVersion, + versionDrift, + skills, + } +} diff --git a/packages/intent/src/types.ts b/packages/intent/src/types.ts index eda3ab9f..e268225b 100644 --- a/packages/intent/src/types.ts +++ b/packages/intent/src/types.ts @@ -1,105 +1,105 @@ -// --------------------------------------------------------------------------- -// Intent config (lives in library package.json under "intent" key) -// --------------------------------------------------------------------------- - -export interface IntentConfig { - version: number - repo: string - docs: string - requires?: string[] -} - -// --------------------------------------------------------------------------- -// Scanner types -// --------------------------------------------------------------------------- - -export interface ScanResult { - packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun' | 'unknown' - packages: IntentPackage[] - warnings: string[] -} - -export interface IntentPackage { - name: string - version: string - intent: IntentConfig - skills: SkillEntry[] -} - -export interface SkillEntry { - name: string - path: string - description: string - type?: string - framework?: string -} - -// --------------------------------------------------------------------------- -// Staleness types -// --------------------------------------------------------------------------- - -export interface StalenessReport { - library: string - currentVersion: string | null - skillVersion: string | null - versionDrift: 'major' | 'minor' | 'patch' | null - skills: SkillStaleness[] -} - -export interface SkillStaleness { - name: string - reasons: string[] - needsReview: boolean -} - -// --------------------------------------------------------------------------- -// Feedback types -// --------------------------------------------------------------------------- - -export interface FeedbackPayload { - skill: string - package: string - skillVersion: string - task: string - whatWorked: string - whatFailed: string - missing: string - selfCorrections: string - userRating: 'good' | 'mixed' | 'bad' - userComments?: string -} - -// --------------------------------------------------------------------------- -// Meta-skill feedback types -// --------------------------------------------------------------------------- - -export type MetaSkillName = - | 'domain-discovery' - | 'tree-generator' - | 'generate-skill' - | 'skill-staleness-check' - -export type AgentName = 'claude-code' | 'cursor' | 'copilot' | 'codex' | 'other' - -export interface MetaFeedbackPayload { - metaSkill: MetaSkillName - library: string - agentUsed: AgentName - artifactQuality: 'good' | 'mixed' | 'bad' - interviewQuality?: 'good' | 'mixed' | 'bad' | 'skipped' - failureModeQuality?: 'good' | 'mixed' | 'bad' | 'not-applicable' - whatWorked: string - whatFailed: string - suggestions: string - userRating: 'good' | 'mixed' | 'bad' -} - -// --------------------------------------------------------------------------- -// Config types -// --------------------------------------------------------------------------- - -export interface IntentProjectConfig { - feedback: { - frequency: string // "always" | "every-N" | "never" - } -} +// --------------------------------------------------------------------------- +// Intent config (lives in library package.json under "intent" key) +// --------------------------------------------------------------------------- + +export interface IntentConfig { + version: number + repo: string + docs: string + requires?: string[] +} + +// --------------------------------------------------------------------------- +// Scanner types +// --------------------------------------------------------------------------- + +export interface ScanResult { + packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun' | 'unknown' + packages: IntentPackage[] + warnings: string[] +} + +export interface IntentPackage { + name: string + version: string + intent: IntentConfig + skills: SkillEntry[] +} + +export interface SkillEntry { + name: string + path: string + description: string + type?: string + framework?: string +} + +// --------------------------------------------------------------------------- +// Staleness types +// --------------------------------------------------------------------------- + +export interface StalenessReport { + library: string + currentVersion: string | null + skillVersion: string | null + versionDrift: 'major' | 'minor' | 'patch' | null + skills: SkillStaleness[] +} + +export interface SkillStaleness { + name: string + reasons: string[] + needsReview: boolean +} + +// --------------------------------------------------------------------------- +// Feedback types +// --------------------------------------------------------------------------- + +export interface FeedbackPayload { + skill: string + package: string + skillVersion: string + task: string + whatWorked: string + whatFailed: string + missing: string + selfCorrections: string + userRating: 'good' | 'mixed' | 'bad' + userComments?: string +} + +// --------------------------------------------------------------------------- +// Meta-skill feedback types +// --------------------------------------------------------------------------- + +export type MetaSkillName = + | 'domain-discovery' + | 'tree-generator' + | 'generate-skill' + | 'skill-staleness-check' + +export type AgentName = 'claude-code' | 'cursor' | 'copilot' | 'codex' | 'other' + +export interface MetaFeedbackPayload { + metaSkill: MetaSkillName + library: string + agentUsed: AgentName + artifactQuality: 'good' | 'mixed' | 'bad' + interviewQuality?: 'good' | 'mixed' | 'bad' | 'skipped' + failureModeQuality?: 'good' | 'mixed' | 'bad' | 'not-applicable' + whatWorked: string + whatFailed: string + suggestions: string + userRating: 'good' | 'mixed' | 'bad' +} + +// --------------------------------------------------------------------------- +// Config types +// --------------------------------------------------------------------------- + +export interface IntentProjectConfig { + feedback: { + frequency: string // "always" | "every-N" | "never" + } +} diff --git a/packages/intent/src/utils.ts b/packages/intent/src/utils.ts index 4c2dadbd..ad1214f0 100644 --- a/packages/intent/src/utils.ts +++ b/packages/intent/src/utils.ts @@ -1,41 +1,41 @@ -import { existsSync, readdirSync, readFileSync } from 'node:fs' -import { join } from 'node:path' -import { parse as parseYaml } from 'yaml' - -/** - * Recursively find all SKILL.md files under a directory. - */ -export function findSkillFiles(dir: string): string[] { - const files: string[] = [] - if (!existsSync(dir)) return files - for (const entry of readdirSync(dir, { withFileTypes: true })) { - const fullPath = join(dir, entry.name) - if (entry.isDirectory()) { - files.push(...findSkillFiles(fullPath)) - } else if (entry.name === 'SKILL.md') { - files.push(fullPath) - } - } - return files -} - -/** - * Parse YAML frontmatter from a file. Returns null if no frontmatter or on error. - */ -export function parseFrontmatter( - filePath: string, -): Record | null { - let content: string - try { - content = readFileSync(filePath, 'utf8') - } catch { - return null - } - const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/) - if (!match?.[1]) return null - try { - return parseYaml(match[1]) as Record - } catch { - return null - } -} +import { existsSync, readdirSync, readFileSync } from 'node:fs' +import { join } from 'node:path' +import { parse as parseYaml } from 'yaml' + +/** + * Recursively find all SKILL.md files under a directory. + */ +export function findSkillFiles(dir: string): string[] { + const files: string[] = [] + if (!existsSync(dir)) return files + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const fullPath = join(dir, entry.name) + if (entry.isDirectory()) { + files.push(...findSkillFiles(fullPath)) + } else if (entry.name === 'SKILL.md') { + files.push(fullPath) + } + } + return files +} + +/** + * Parse YAML frontmatter from a file. Returns null if no frontmatter or on error. + */ +export function parseFrontmatter( + filePath: string, +): Record | null { + let content: string + try { + content = readFileSync(filePath, 'utf8') + } catch { + return null + } + const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/) + if (!match?.[1]) return null + try { + return parseYaml(match[1]) as Record + } catch { + return null + } +} diff --git a/packages/intent/tests/cli.test.ts b/packages/intent/tests/cli.test.ts index 8bd3a9f6..d2547199 100644 --- a/packages/intent/tests/cli.test.ts +++ b/packages/intent/tests/cli.test.ts @@ -1,94 +1,94 @@ -import { existsSync, readdirSync, readFileSync } from 'node:fs' -import { join, dirname } from 'node:path' -import { fileURLToPath } from 'node:url' -import { describe, expect, it } from 'vitest' -import { parse as parseYaml } from 'yaml' - -// ── Meta-skills tests (intent meta) ── - -const thisDir = dirname(fileURLToPath(import.meta.url)) -const metaDir = join(thisDir, '..', 'meta') - -describe('intent meta', () => { - it('meta directory exists', () => { - expect(existsSync(metaDir)).toBe(true) - }) - - it('contains expected meta-skills', () => { - const entries = readdirSync(metaDir, { withFileTypes: true }) - .filter((e) => e.isDirectory()) - .filter((e) => existsSync(join(metaDir, e.name, 'SKILL.md'))) - .map((e) => e.name) - - expect(entries).toContain('domain-discovery') - expect(entries).toContain('tree-generator') - expect(entries).toContain('generate-skill') - expect(entries).toContain('skill-staleness-check') - }) - - it('each meta-skill has a description in frontmatter', () => { - const entries = readdirSync(metaDir, { withFileTypes: true }) - .filter((e) => e.isDirectory()) - .filter((e) => existsSync(join(metaDir, e.name, 'SKILL.md'))) - - for (const entry of entries) { - const content = readFileSync( - join(metaDir, entry.name, 'SKILL.md'), - 'utf8', - ) - const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/) - expect(match, `${entry.name} should have frontmatter`).not.toBeNull() - - const fm = parseYaml(match![1]) as Record - expect( - fm.description, - `${entry.name} should have a description`, - ).toBeTruthy() - } - }) -}) - -// ── Validate command logic ── - -describe('intent validate', () => { - it('finds SKILL.md files in meta directory', () => { - function findSkillFiles(dir: string): string[] { - const files: string[] = [] - for (const entry of readdirSync(dir, { withFileTypes: true })) { - const fullPath = join(dir, entry.name) - if (entry.isDirectory()) { - files.push(...findSkillFiles(fullPath)) - } else if (entry.name === 'SKILL.md') { - files.push(fullPath) - } - } - return files - } - - const files = findSkillFiles(metaDir) - expect(files.length).toBeGreaterThan(0) - }) -}) - -// ── Scanner JSON output shape ── - -describe('intent list --json shape', () => { - it('scanForIntents returns correct shape', async () => { - const { scanForIntents } = await import('../src/scanner.js') - // Run against a dir with no node_modules — should return valid shape - const { mkdtempSync } = await import('node:fs') - const { tmpdir } = await import('node:os') - const root = mkdtempSync(join(tmpdir(), 'cli-test-')) - - const result = await scanForIntents(root) - expect(result).toHaveProperty('packageManager') - expect(result).toHaveProperty('packages') - expect(result).toHaveProperty('warnings') - expect(Array.isArray(result.packages)).toBe(true) - expect(Array.isArray(result.warnings)).toBe(true) - - // Cleanup - const { rmSync } = await import('node:fs') - rmSync(root, { recursive: true, force: true }) - }) -}) +import { existsSync, readdirSync, readFileSync } from 'node:fs' +import { join, dirname } from 'node:path' +import { fileURLToPath } from 'node:url' +import { describe, expect, it } from 'vitest' +import { parse as parseYaml } from 'yaml' + +// ── Meta-skills tests (intent meta) ── + +const thisDir = dirname(fileURLToPath(import.meta.url)) +const metaDir = join(thisDir, '..', 'meta') + +describe('intent meta', () => { + it('meta directory exists', () => { + expect(existsSync(metaDir)).toBe(true) + }) + + it('contains expected meta-skills', () => { + const entries = readdirSync(metaDir, { withFileTypes: true }) + .filter((e) => e.isDirectory()) + .filter((e) => existsSync(join(metaDir, e.name, 'SKILL.md'))) + .map((e) => e.name) + + expect(entries).toContain('domain-discovery') + expect(entries).toContain('tree-generator') + expect(entries).toContain('generate-skill') + expect(entries).toContain('skill-staleness-check') + }) + + it('each meta-skill has a description in frontmatter', () => { + const entries = readdirSync(metaDir, { withFileTypes: true }) + .filter((e) => e.isDirectory()) + .filter((e) => existsSync(join(metaDir, e.name, 'SKILL.md'))) + + for (const entry of entries) { + const content = readFileSync( + join(metaDir, entry.name, 'SKILL.md'), + 'utf8', + ) + const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/) + expect(match, `${entry.name} should have frontmatter`).not.toBeNull() + + const fm = parseYaml(match![1]) as Record + expect( + fm.description, + `${entry.name} should have a description`, + ).toBeTruthy() + } + }) +}) + +// ── Validate command logic ── + +describe('intent validate', () => { + it('finds SKILL.md files in meta directory', () => { + function findSkillFiles(dir: string): string[] { + const files: string[] = [] + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const fullPath = join(dir, entry.name) + if (entry.isDirectory()) { + files.push(...findSkillFiles(fullPath)) + } else if (entry.name === 'SKILL.md') { + files.push(fullPath) + } + } + return files + } + + const files = findSkillFiles(metaDir) + expect(files.length).toBeGreaterThan(0) + }) +}) + +// ── Scanner JSON output shape ── + +describe('intent list --json shape', () => { + it('scanForIntents returns correct shape', async () => { + const { scanForIntents } = await import('../src/scanner.js') + // Run against a dir with no node_modules — should return valid shape + const { mkdtempSync } = await import('node:fs') + const { tmpdir } = await import('node:os') + const root = mkdtempSync(join(tmpdir(), 'cli-test-')) + + const result = await scanForIntents(root) + expect(result).toHaveProperty('packageManager') + expect(result).toHaveProperty('packages') + expect(result).toHaveProperty('warnings') + expect(Array.isArray(result.packages)).toBe(true) + expect(Array.isArray(result.warnings)).toBe(true) + + // Cleanup + const { rmSync } = await import('node:fs') + rmSync(root, { recursive: true, force: true }) + }) +}) diff --git a/packages/intent/tests/feedback.test.ts b/packages/intent/tests/feedback.test.ts index d2ea1581..35cd4e45 100644 --- a/packages/intent/tests/feedback.test.ts +++ b/packages/intent/tests/feedback.test.ts @@ -1,275 +1,275 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { - existsSync, - mkdirSync, - readFileSync, - rmSync, - writeFileSync, -} from 'node:fs' -import { join } from 'node:path' -import { tmpdir } from 'node:os' -import { - containsSecrets, - resolveFrequency, - submitFeedback, - toMarkdown, - validatePayload, -} from '../src/feedback.js' -import type { FeedbackPayload } from '../src/types.js' - -// --------------------------------------------------------------------------- -// Fixture helpers -// --------------------------------------------------------------------------- - -let tmpDir: string - -function setupDir(): string { - const dir = join( - tmpdir(), - `intent-fb-test-${Date.now()}-${Math.random().toString(36).slice(2)}`, - ) - mkdirSync(dir, { recursive: true }) - return dir -} - -function validPayload( - overrides: Partial = {}, -): FeedbackPayload { - return { - skill: 'db-core/live-queries', - package: '@tanstack/db', - skillVersion: '0.5.0', - task: 'Set up a live query subscription', - whatWorked: 'Query builder syntax was great', - whatFailed: 'Collection creation missed an import', - missing: 'No examples for nested joins', - selfCorrections: 'Had to add missing import manually', - userRating: 'good', - ...overrides, - } -} - -beforeEach(() => { - tmpDir = setupDir() -}) - -afterEach(() => { - if (existsSync(tmpDir)) { - rmSync(tmpDir, { recursive: true, force: true }) - } -}) - -// --------------------------------------------------------------------------- -// containsSecrets -// --------------------------------------------------------------------------- - -describe('containsSecrets', () => { - it('detects GitHub tokens', () => { - expect(containsSecrets('token: ghp_' + 'A'.repeat(36))).toBe(true) - }) - - it('detects AWS access keys', () => { - expect(containsSecrets('key: AKIA' + '0'.repeat(16))).toBe(true) - }) - - it('detects PEM private keys', () => { - expect(containsSecrets('-----BEGIN RSA PRIVATE KEY-----')).toBe(true) - }) - - it('detects Stripe keys', () => { - expect(containsSecrets('sk-live-' + 'a'.repeat(24))).toBe(true) - }) - - it('detects Bearer tokens', () => { - expect(containsSecrets('Bearer ' + 'a'.repeat(30))).toBe(true) - }) - - it('does not flag normal text', () => { - expect( - containsSecrets( - 'This is a perfectly normal feedback message about queries.', - ), - ).toBe(false) - }) - - it('does not flag short strings', () => { - expect(containsSecrets('key=abc123')).toBe(false) - }) -}) - -// --------------------------------------------------------------------------- -// validatePayload -// --------------------------------------------------------------------------- - -describe('validatePayload', () => { - it('accepts a valid payload', () => { - const result = validatePayload(validPayload()) - expect(result.valid).toBe(true) - expect(result.errors).toHaveLength(0) - }) - - it('rejects non-object input', () => { - const result = validatePayload('not an object') - expect(result.valid).toBe(false) - expect(result.errors[0]).toContain('JSON object') - }) - - it('rejects null', () => { - const result = validatePayload(null) - expect(result.valid).toBe(false) - }) - - it('reports missing required fields', () => { - const result = validatePayload({ skill: 'test' }) - expect(result.valid).toBe(false) - expect(result.errors.length).toBeGreaterThan(1) - expect(result.errors.some((e) => e.includes('package'))).toBe(true) - }) - - it('rejects empty string fields', () => { - const result = validatePayload(validPayload({ task: '' })) - expect(result.valid).toBe(false) - expect(result.errors.some((e) => e.includes('task'))).toBe(true) - }) - - it('rejects invalid userRating', () => { - const result = validatePayload( - validPayload({ userRating: 'excellent' as 'good' }), - ) - expect(result.valid).toBe(false) - expect(result.errors.some((e) => e.includes('userRating'))).toBe(true) - }) - - it('rejects payloads containing secrets', () => { - const result = validatePayload( - validPayload({ - whatFailed: 'Used token ghp_' + 'A'.repeat(36) + ' and it failed', - }), - ) - expect(result.valid).toBe(false) - expect(result.errors.some((e) => e.includes('secrets'))).toBe(true) - }) -}) - -// --------------------------------------------------------------------------- -// toMarkdown -// --------------------------------------------------------------------------- - -describe('toMarkdown', () => { - it('converts payload to markdown', () => { - const md = toMarkdown(validPayload()) - expect(md).toContain('# Skill Feedback: db-core/live-queries') - expect(md).toContain('**Package:** @tanstack/db') - expect(md).toContain('**Rating:** good') - expect(md).toContain('## Task') - expect(md).toContain('## What Worked') - expect(md).toContain('## What Failed') - expect(md).toContain('## Missing') - expect(md).toContain('## Self-Corrections') - }) - - it('includes user comments when present', () => { - const md = toMarkdown(validPayload({ userComments: 'Great overall!' })) - expect(md).toContain('## User Comments') - expect(md).toContain('Great overall!') - }) - - it('omits user comments section when not present', () => { - const md = toMarkdown(validPayload()) - expect(md).not.toContain('## User Comments') - }) -}) - -// --------------------------------------------------------------------------- -// submitFeedback -// --------------------------------------------------------------------------- - -describe('submitFeedback', () => { - it('saves to file when gh not available and outputPath given', () => { - const outPath = join(tmpDir, 'feedback.md') - const result = submitFeedback(validPayload(), 'tanstack/db', { - ghAvailable: false, - outputPath: outPath, - }) - expect(result.method).toBe('file') - expect(result.detail).toContain(outPath) - expect(existsSync(outPath)).toBe(true) - const content = readFileSync(outPath, 'utf8') - expect(content).toContain('# Skill Feedback') - }) - - it('returns stdout when no gh and no outputPath', () => { - const result = submitFeedback(validPayload(), 'tanstack/db', { - ghAvailable: false, - }) - expect(result.method).toBe('stdout') - expect(result.detail).toContain('# Skill Feedback') - }) -}) - -// --------------------------------------------------------------------------- -// resolveFrequency -// --------------------------------------------------------------------------- - -describe('resolveFrequency', () => { - it('returns project config frequency when set', () => { - writeFileSync( - join(tmpDir, 'intent.config.json'), - JSON.stringify({ feedback: { frequency: 'always' } }), - ) - expect(resolveFrequency(tmpDir)).toBe('always') - }) - - it('returns default when no config exists', () => { - expect(resolveFrequency(tmpDir)).toBe('every-5') - }) - - it('reads user override via XDG_CONFIG_HOME', () => { - const configDir = join(tmpDir, 'xdg') - mkdirSync(join(configDir, 'intent'), { recursive: true }) - writeFileSync( - join(configDir, 'intent', 'config.json'), - JSON.stringify({ feedback: { frequency: 'never' } }), - ) - - const originalXdg = process.env.XDG_CONFIG_HOME - process.env.XDG_CONFIG_HOME = configDir - try { - expect(resolveFrequency(tmpDir)).toBe('never') - } finally { - if (originalXdg !== undefined) { - process.env.XDG_CONFIG_HOME = originalXdg - } else { - delete process.env.XDG_CONFIG_HOME - } - } - }) - - it('user override takes precedence over project config', () => { - // Project says "always" - writeFileSync( - join(tmpDir, 'intent.config.json'), - JSON.stringify({ feedback: { frequency: 'always' } }), - ) - - // User override says "never" - const configDir = join(tmpDir, 'xdg2') - mkdirSync(join(configDir, 'intent'), { recursive: true }) - writeFileSync( - join(configDir, 'intent', 'config.json'), - JSON.stringify({ feedback: { frequency: 'never' } }), - ) - - const originalXdg = process.env.XDG_CONFIG_HOME - process.env.XDG_CONFIG_HOME = configDir - try { - expect(resolveFrequency(tmpDir)).toBe('never') - } finally { - if (originalXdg !== undefined) { - process.env.XDG_CONFIG_HOME = originalXdg - } else { - delete process.env.XDG_CONFIG_HOME - } - } - }) -}) +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { + existsSync, + mkdirSync, + readFileSync, + rmSync, + writeFileSync, +} from 'node:fs' +import { join } from 'node:path' +import { tmpdir } from 'node:os' +import { + containsSecrets, + resolveFrequency, + submitFeedback, + toMarkdown, + validatePayload, +} from '../src/feedback.js' +import type { FeedbackPayload } from '../src/types.js' + +// --------------------------------------------------------------------------- +// Fixture helpers +// --------------------------------------------------------------------------- + +let tmpDir: string + +function setupDir(): string { + const dir = join( + tmpdir(), + `intent-fb-test-${Date.now()}-${Math.random().toString(36).slice(2)}`, + ) + mkdirSync(dir, { recursive: true }) + return dir +} + +function validPayload( + overrides: Partial = {}, +): FeedbackPayload { + return { + skill: 'db-core/live-queries', + package: '@tanstack/db', + skillVersion: '0.5.0', + task: 'Set up a live query subscription', + whatWorked: 'Query builder syntax was great', + whatFailed: 'Collection creation missed an import', + missing: 'No examples for nested joins', + selfCorrections: 'Had to add missing import manually', + userRating: 'good', + ...overrides, + } +} + +beforeEach(() => { + tmpDir = setupDir() +}) + +afterEach(() => { + if (existsSync(tmpDir)) { + rmSync(tmpDir, { recursive: true, force: true }) + } +}) + +// --------------------------------------------------------------------------- +// containsSecrets +// --------------------------------------------------------------------------- + +describe('containsSecrets', () => { + it('detects GitHub tokens', () => { + expect(containsSecrets('token: ghp_' + 'A'.repeat(36))).toBe(true) + }) + + it('detects AWS access keys', () => { + expect(containsSecrets('key: AKIA' + '0'.repeat(16))).toBe(true) + }) + + it('detects PEM private keys', () => { + expect(containsSecrets('-----BEGIN RSA PRIVATE KEY-----')).toBe(true) + }) + + it('detects Stripe keys', () => { + expect(containsSecrets('sk-live-' + 'a'.repeat(24))).toBe(true) + }) + + it('detects Bearer tokens', () => { + expect(containsSecrets('Bearer ' + 'a'.repeat(30))).toBe(true) + }) + + it('does not flag normal text', () => { + expect( + containsSecrets( + 'This is a perfectly normal feedback message about queries.', + ), + ).toBe(false) + }) + + it('does not flag short strings', () => { + expect(containsSecrets('key=abc123')).toBe(false) + }) +}) + +// --------------------------------------------------------------------------- +// validatePayload +// --------------------------------------------------------------------------- + +describe('validatePayload', () => { + it('accepts a valid payload', () => { + const result = validatePayload(validPayload()) + expect(result.valid).toBe(true) + expect(result.errors).toHaveLength(0) + }) + + it('rejects non-object input', () => { + const result = validatePayload('not an object') + expect(result.valid).toBe(false) + expect(result.errors[0]).toContain('JSON object') + }) + + it('rejects null', () => { + const result = validatePayload(null) + expect(result.valid).toBe(false) + }) + + it('reports missing required fields', () => { + const result = validatePayload({ skill: 'test' }) + expect(result.valid).toBe(false) + expect(result.errors.length).toBeGreaterThan(1) + expect(result.errors.some((e) => e.includes('package'))).toBe(true) + }) + + it('rejects empty string fields', () => { + const result = validatePayload(validPayload({ task: '' })) + expect(result.valid).toBe(false) + expect(result.errors.some((e) => e.includes('task'))).toBe(true) + }) + + it('rejects invalid userRating', () => { + const result = validatePayload( + validPayload({ userRating: 'excellent' as 'good' }), + ) + expect(result.valid).toBe(false) + expect(result.errors.some((e) => e.includes('userRating'))).toBe(true) + }) + + it('rejects payloads containing secrets', () => { + const result = validatePayload( + validPayload({ + whatFailed: 'Used token ghp_' + 'A'.repeat(36) + ' and it failed', + }), + ) + expect(result.valid).toBe(false) + expect(result.errors.some((e) => e.includes('secrets'))).toBe(true) + }) +}) + +// --------------------------------------------------------------------------- +// toMarkdown +// --------------------------------------------------------------------------- + +describe('toMarkdown', () => { + it('converts payload to markdown', () => { + const md = toMarkdown(validPayload()) + expect(md).toContain('# Skill Feedback: db-core/live-queries') + expect(md).toContain('**Package:** @tanstack/db') + expect(md).toContain('**Rating:** good') + expect(md).toContain('## Task') + expect(md).toContain('## What Worked') + expect(md).toContain('## What Failed') + expect(md).toContain('## Missing') + expect(md).toContain('## Self-Corrections') + }) + + it('includes user comments when present', () => { + const md = toMarkdown(validPayload({ userComments: 'Great overall!' })) + expect(md).toContain('## User Comments') + expect(md).toContain('Great overall!') + }) + + it('omits user comments section when not present', () => { + const md = toMarkdown(validPayload()) + expect(md).not.toContain('## User Comments') + }) +}) + +// --------------------------------------------------------------------------- +// submitFeedback +// --------------------------------------------------------------------------- + +describe('submitFeedback', () => { + it('saves to file when gh not available and outputPath given', () => { + const outPath = join(tmpDir, 'feedback.md') + const result = submitFeedback(validPayload(), 'tanstack/db', { + ghAvailable: false, + outputPath: outPath, + }) + expect(result.method).toBe('file') + expect(result.detail).toContain(outPath) + expect(existsSync(outPath)).toBe(true) + const content = readFileSync(outPath, 'utf8') + expect(content).toContain('# Skill Feedback') + }) + + it('returns stdout when no gh and no outputPath', () => { + const result = submitFeedback(validPayload(), 'tanstack/db', { + ghAvailable: false, + }) + expect(result.method).toBe('stdout') + expect(result.detail).toContain('# Skill Feedback') + }) +}) + +// --------------------------------------------------------------------------- +// resolveFrequency +// --------------------------------------------------------------------------- + +describe('resolveFrequency', () => { + it('returns project config frequency when set', () => { + writeFileSync( + join(tmpDir, 'intent.config.json'), + JSON.stringify({ feedback: { frequency: 'always' } }), + ) + expect(resolveFrequency(tmpDir)).toBe('always') + }) + + it('returns default when no config exists', () => { + expect(resolveFrequency(tmpDir)).toBe('every-5') + }) + + it('reads user override via XDG_CONFIG_HOME', () => { + const configDir = join(tmpDir, 'xdg') + mkdirSync(join(configDir, 'intent'), { recursive: true }) + writeFileSync( + join(configDir, 'intent', 'config.json'), + JSON.stringify({ feedback: { frequency: 'never' } }), + ) + + const originalXdg = process.env.XDG_CONFIG_HOME + process.env.XDG_CONFIG_HOME = configDir + try { + expect(resolveFrequency(tmpDir)).toBe('never') + } finally { + if (originalXdg !== undefined) { + process.env.XDG_CONFIG_HOME = originalXdg + } else { + delete process.env.XDG_CONFIG_HOME + } + } + }) + + it('user override takes precedence over project config', () => { + // Project says "always" + writeFileSync( + join(tmpDir, 'intent.config.json'), + JSON.stringify({ feedback: { frequency: 'always' } }), + ) + + // User override says "never" + const configDir = join(tmpDir, 'xdg2') + mkdirSync(join(configDir, 'intent'), { recursive: true }) + writeFileSync( + join(configDir, 'intent', 'config.json'), + JSON.stringify({ feedback: { frequency: 'never' } }), + ) + + const originalXdg = process.env.XDG_CONFIG_HOME + process.env.XDG_CONFIG_HOME = configDir + try { + expect(resolveFrequency(tmpDir)).toBe('never') + } finally { + if (originalXdg !== undefined) { + process.env.XDG_CONFIG_HOME = originalXdg + } else { + delete process.env.XDG_CONFIG_HOME + } + } + }) +}) diff --git a/packages/intent/tests/library-scanner.test.ts b/packages/intent/tests/library-scanner.test.ts index 19ac7faf..38904e15 100644 --- a/packages/intent/tests/library-scanner.test.ts +++ b/packages/intent/tests/library-scanner.test.ts @@ -1,269 +1,269 @@ -import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' -import { join } from 'node:path' -import { tmpdir } from 'node:os' -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { scanLibrary } from '../src/library-scanner.js' - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -function createDir(...segments: string[]): string { - const dir = join(...segments) - mkdirSync(dir, { recursive: true }) - return dir -} - -function writeJson(filePath: string, data: unknown): void { - writeFileSync(filePath, JSON.stringify(data, null, 2)) -} - -function writeSkillMd(dir: string, frontmatter: Record): void { - const yamlLines = Object.entries(frontmatter) - .map(([k, v]) => `${k}: ${typeof v === 'string' ? `"${v}"` : v}`) - .join('\n') - writeFileSync( - join(dir, 'SKILL.md'), - `---\n${yamlLines}\n---\n\nSkill content here.\n`, - ) -} - -// Simulate the script path as it would appear in a library's bin/intent.js shim. -// findHomeDir walks up from dirname(scriptPath) to find the nearest package.json. -function shimPath(pkgDir: string): string { - return join(pkgDir, 'bin', 'intent.js') -} - -// --------------------------------------------------------------------------- -// Setup / Teardown -// --------------------------------------------------------------------------- - -let root: string - -beforeEach(() => { - root = mkdtempSync(join(tmpdir(), 'library-scanner-test-')) -}) - -afterEach(() => { - rmSync(root, { recursive: true, force: true }) -}) - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -describe('scanLibrary', () => { - it('returns the home package with its skills', async () => { - const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') - writeJson(join(pkgDir, 'package.json'), { - name: '@tanstack/router', - version: '1.2.0', - description: 'Type-safe router for React', - bin: { intent: './bin/intent.js' }, - }) - const skillDir = createDir(pkgDir, 'skills', 'routing') - writeSkillMd(skillDir, { - name: 'routing', - description: 'File-based route definitions', - }) - - const result = await scanLibrary(shimPath(pkgDir), root) - - expect(result.warnings).toEqual([]) - expect(result.packages).toHaveLength(1) - expect(result.packages[0]!.name).toBe('@tanstack/router') - expect(result.packages[0]!.version).toBe('1.2.0') - expect(result.packages[0]!.description).toBe('Type-safe router for React') - expect(result.packages[0]!.skills).toHaveLength(1) - expect(result.packages[0]!.skills[0]!.name).toBe('routing') - expect(result.packages[0]!.skills[0]!.description).toBe( - 'File-based route definitions', - ) - }) - - it('includes the full path to each SKILL.md', async () => { - const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') - writeJson(join(pkgDir, 'package.json'), { - name: '@tanstack/router', - version: '1.0.0', - bin: { intent: './bin/intent.js' }, - }) - const skillDir = createDir(pkgDir, 'skills', 'routing') - writeSkillMd(skillDir, { name: 'routing', description: 'Routing patterns' }) - - const result = await scanLibrary(shimPath(pkgDir), root) - - const skill = result.packages[0]!.skills[0]! - expect(skill.path).toBe(join(pkgDir, 'skills', 'routing', 'SKILL.md')) - }) - - it('recursively discovers deps with bin.intent', async () => { - // Home package: @tanstack/router, depends on @tanstack/query - const routerDir = createDir(root, 'node_modules', '@tanstack', 'router') - writeJson(join(routerDir, 'package.json'), { - name: '@tanstack/router', - version: '1.0.0', - description: 'Router', - bin: { intent: './bin/intent.js' }, - dependencies: { '@tanstack/query': '^5.0.0' }, - }) - const routerSkill = createDir(routerDir, 'skills', 'routing') - writeSkillMd(routerSkill, { - name: 'routing', - description: 'Route definitions', - }) - - // Dep package: @tanstack/query - const queryDir = createDir(root, 'node_modules', '@tanstack', 'query') - writeJson(join(queryDir, 'package.json'), { - name: '@tanstack/query', - version: '5.0.0', - description: 'Async state management', - bin: { intent: './bin/intent.js' }, - }) - const querySkill = createDir(queryDir, 'skills', 'fetching') - writeSkillMd(querySkill, { - name: 'fetching', - description: 'Query and mutation patterns', - }) - - const result = await scanLibrary(shimPath(routerDir), root) - - expect(result.warnings).toEqual([]) - expect(result.packages).toHaveLength(2) - - const names = result.packages.map((p) => p.name) - expect(names).toContain('@tanstack/router') - expect(names).toContain('@tanstack/query') - - const query = result.packages.find((p) => p.name === '@tanstack/query')! - expect(query.skills[0]!.name).toBe('fetching') - expect(query.skills[0]!.description).toBe('Query and mutation patterns') - }) - - it('discovers deps via peerDependencies', async () => { - const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') - writeJson(join(pkgDir, 'package.json'), { - name: '@tanstack/router', - version: '1.0.0', - bin: { intent: './bin/intent.js' }, - peerDependencies: { '@tanstack/query': '^5.0.0' }, - }) - - const queryDir = createDir(root, 'node_modules', '@tanstack', 'query') - writeJson(join(queryDir, 'package.json'), { - name: '@tanstack/query', - version: '5.0.0', - bin: { intent: './bin/intent.js' }, - }) - const querySkill = createDir(queryDir, 'skills', 'fetching') - writeSkillMd(querySkill, { name: 'fetching', description: 'Fetching' }) - - const result = await scanLibrary(shimPath(pkgDir), root) - - const names = result.packages.map((p) => p.name) - expect(names).toContain('@tanstack/query') - }) - - it('skips deps without bin.intent', async () => { - const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') - writeJson(join(pkgDir, 'package.json'), { - name: '@tanstack/router', - version: '1.0.0', - bin: { intent: './bin/intent.js' }, - dependencies: { react: '^18.0.0' }, - }) - - const reactDir = createDir(root, 'node_modules', 'react') - writeJson(join(reactDir, 'package.json'), { - name: 'react', - version: '18.0.0', - // no bin.intent - }) - const reactSkill = createDir(reactDir, 'skills', 'hooks') - writeSkillMd(reactSkill, { name: 'hooks', description: 'React hooks' }) - - const result = await scanLibrary(shimPath(pkgDir), root) - - const names = result.packages.map((p) => p.name) - expect(names).not.toContain('react') - }) - - it('handles packages with no skills/ directory', async () => { - const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') - writeJson(join(pkgDir, 'package.json'), { - name: '@tanstack/router', - version: '1.0.0', - bin: { intent: './bin/intent.js' }, - }) - // No skills/ directory - - const result = await scanLibrary(shimPath(pkgDir), root) - - expect(result.packages).toHaveLength(1) - expect(result.packages[0]!.skills).toEqual([]) - }) - - it('does not visit the same package twice (cycle detection)', async () => { - // router -> query -> router (circular) - const routerDir = createDir(root, 'node_modules', '@tanstack', 'router') - writeJson(join(routerDir, 'package.json'), { - name: '@tanstack/router', - version: '1.0.0', - bin: { intent: './bin/intent.js' }, - dependencies: { '@tanstack/query': '^5.0.0' }, - }) - - const queryDir = createDir(root, 'node_modules', '@tanstack', 'query') - writeJson(join(queryDir, 'package.json'), { - name: '@tanstack/query', - version: '5.0.0', - bin: { intent: './bin/intent.js' }, - dependencies: { '@tanstack/router': '^1.0.0' }, // circular back - }) - - const result = await scanLibrary(shimPath(routerDir), root) - - // Each package appears exactly once - const names = result.packages.map((p) => p.name) - expect(names).toHaveLength(2) - expect(new Set(names).size).toBe(2) - }) - - it('discovers sub-skills within a package', async () => { - const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') - writeJson(join(pkgDir, 'package.json'), { - name: '@tanstack/router', - version: '1.0.0', - bin: { intent: './bin/intent.js' }, - }) - const routingDir = createDir(pkgDir, 'skills', 'routing') - writeSkillMd(routingDir, { - name: 'routing', - description: 'Routing overview', - }) - const nestedDir = createDir(routingDir, 'nested-routes') - writeSkillMd(nestedDir, { - name: 'routing/nested-routes', - description: 'Nested route patterns', - }) - - const result = await scanLibrary(shimPath(pkgDir), root) - - const skills = result.packages[0]!.skills - expect(skills).toHaveLength(2) - const names = skills.map((s) => s.name) - expect(names).toContain('routing') - expect(names).toContain('routing/nested-routes') - }) - - it('returns a warning when home package.json cannot be found', async () => { - const fakeScript = join(root, 'nowhere', 'bin', 'intent.js') - - const result = await scanLibrary(fakeScript, root) - - expect(result.packages).toEqual([]) - expect(result.warnings).toHaveLength(1) - expect(result.warnings[0]).toMatch(/home package/i) - }) -}) +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' +import { join } from 'node:path' +import { tmpdir } from 'node:os' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { scanLibrary } from '../src/library-scanner.js' + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +function createDir(...segments: string[]): string { + const dir = join(...segments) + mkdirSync(dir, { recursive: true }) + return dir +} + +function writeJson(filePath: string, data: unknown): void { + writeFileSync(filePath, JSON.stringify(data, null, 2)) +} + +function writeSkillMd(dir: string, frontmatter: Record): void { + const yamlLines = Object.entries(frontmatter) + .map(([k, v]) => `${k}: ${typeof v === 'string' ? `"${v}"` : v}`) + .join('\n') + writeFileSync( + join(dir, 'SKILL.md'), + `---\n${yamlLines}\n---\n\nSkill content here.\n`, + ) +} + +// Simulate the script path as it would appear in a library's bin/intent.js shim. +// findHomeDir walks up from dirname(scriptPath) to find the nearest package.json. +function shimPath(pkgDir: string): string { + return join(pkgDir, 'bin', 'intent.js') +} + +// --------------------------------------------------------------------------- +// Setup / Teardown +// --------------------------------------------------------------------------- + +let root: string + +beforeEach(() => { + root = mkdtempSync(join(tmpdir(), 'library-scanner-test-')) +}) + +afterEach(() => { + rmSync(root, { recursive: true, force: true }) +}) + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +describe('scanLibrary', () => { + it('returns the home package with its skills', async () => { + const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') + writeJson(join(pkgDir, 'package.json'), { + name: '@tanstack/router', + version: '1.2.0', + description: 'Type-safe router for React', + bin: { intent: './bin/intent.js' }, + }) + const skillDir = createDir(pkgDir, 'skills', 'routing') + writeSkillMd(skillDir, { + name: 'routing', + description: 'File-based route definitions', + }) + + const result = await scanLibrary(shimPath(pkgDir), root) + + expect(result.warnings).toEqual([]) + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.name).toBe('@tanstack/router') + expect(result.packages[0]!.version).toBe('1.2.0') + expect(result.packages[0]!.description).toBe('Type-safe router for React') + expect(result.packages[0]!.skills).toHaveLength(1) + expect(result.packages[0]!.skills[0]!.name).toBe('routing') + expect(result.packages[0]!.skills[0]!.description).toBe( + 'File-based route definitions', + ) + }) + + it('includes the full path to each SKILL.md', async () => { + const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') + writeJson(join(pkgDir, 'package.json'), { + name: '@tanstack/router', + version: '1.0.0', + bin: { intent: './bin/intent.js' }, + }) + const skillDir = createDir(pkgDir, 'skills', 'routing') + writeSkillMd(skillDir, { name: 'routing', description: 'Routing patterns' }) + + const result = await scanLibrary(shimPath(pkgDir), root) + + const skill = result.packages[0]!.skills[0]! + expect(skill.path).toBe(join(pkgDir, 'skills', 'routing', 'SKILL.md')) + }) + + it('recursively discovers deps with bin.intent', async () => { + // Home package: @tanstack/router, depends on @tanstack/query + const routerDir = createDir(root, 'node_modules', '@tanstack', 'router') + writeJson(join(routerDir, 'package.json'), { + name: '@tanstack/router', + version: '1.0.0', + description: 'Router', + bin: { intent: './bin/intent.js' }, + dependencies: { '@tanstack/query': '^5.0.0' }, + }) + const routerSkill = createDir(routerDir, 'skills', 'routing') + writeSkillMd(routerSkill, { + name: 'routing', + description: 'Route definitions', + }) + + // Dep package: @tanstack/query + const queryDir = createDir(root, 'node_modules', '@tanstack', 'query') + writeJson(join(queryDir, 'package.json'), { + name: '@tanstack/query', + version: '5.0.0', + description: 'Async state management', + bin: { intent: './bin/intent.js' }, + }) + const querySkill = createDir(queryDir, 'skills', 'fetching') + writeSkillMd(querySkill, { + name: 'fetching', + description: 'Query and mutation patterns', + }) + + const result = await scanLibrary(shimPath(routerDir), root) + + expect(result.warnings).toEqual([]) + expect(result.packages).toHaveLength(2) + + const names = result.packages.map((p) => p.name) + expect(names).toContain('@tanstack/router') + expect(names).toContain('@tanstack/query') + + const query = result.packages.find((p) => p.name === '@tanstack/query')! + expect(query.skills[0]!.name).toBe('fetching') + expect(query.skills[0]!.description).toBe('Query and mutation patterns') + }) + + it('discovers deps via peerDependencies', async () => { + const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') + writeJson(join(pkgDir, 'package.json'), { + name: '@tanstack/router', + version: '1.0.0', + bin: { intent: './bin/intent.js' }, + peerDependencies: { '@tanstack/query': '^5.0.0' }, + }) + + const queryDir = createDir(root, 'node_modules', '@tanstack', 'query') + writeJson(join(queryDir, 'package.json'), { + name: '@tanstack/query', + version: '5.0.0', + bin: { intent: './bin/intent.js' }, + }) + const querySkill = createDir(queryDir, 'skills', 'fetching') + writeSkillMd(querySkill, { name: 'fetching', description: 'Fetching' }) + + const result = await scanLibrary(shimPath(pkgDir), root) + + const names = result.packages.map((p) => p.name) + expect(names).toContain('@tanstack/query') + }) + + it('skips deps without bin.intent', async () => { + const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') + writeJson(join(pkgDir, 'package.json'), { + name: '@tanstack/router', + version: '1.0.0', + bin: { intent: './bin/intent.js' }, + dependencies: { react: '^18.0.0' }, + }) + + const reactDir = createDir(root, 'node_modules', 'react') + writeJson(join(reactDir, 'package.json'), { + name: 'react', + version: '18.0.0', + // no bin.intent + }) + const reactSkill = createDir(reactDir, 'skills', 'hooks') + writeSkillMd(reactSkill, { name: 'hooks', description: 'React hooks' }) + + const result = await scanLibrary(shimPath(pkgDir), root) + + const names = result.packages.map((p) => p.name) + expect(names).not.toContain('react') + }) + + it('handles packages with no skills/ directory', async () => { + const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') + writeJson(join(pkgDir, 'package.json'), { + name: '@tanstack/router', + version: '1.0.0', + bin: { intent: './bin/intent.js' }, + }) + // No skills/ directory + + const result = await scanLibrary(shimPath(pkgDir), root) + + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.skills).toEqual([]) + }) + + it('does not visit the same package twice (cycle detection)', async () => { + // router -> query -> router (circular) + const routerDir = createDir(root, 'node_modules', '@tanstack', 'router') + writeJson(join(routerDir, 'package.json'), { + name: '@tanstack/router', + version: '1.0.0', + bin: { intent: './bin/intent.js' }, + dependencies: { '@tanstack/query': '^5.0.0' }, + }) + + const queryDir = createDir(root, 'node_modules', '@tanstack', 'query') + writeJson(join(queryDir, 'package.json'), { + name: '@tanstack/query', + version: '5.0.0', + bin: { intent: './bin/intent.js' }, + dependencies: { '@tanstack/router': '^1.0.0' }, // circular back + }) + + const result = await scanLibrary(shimPath(routerDir), root) + + // Each package appears exactly once + const names = result.packages.map((p) => p.name) + expect(names).toHaveLength(2) + expect(new Set(names).size).toBe(2) + }) + + it('discovers sub-skills within a package', async () => { + const pkgDir = createDir(root, 'node_modules', '@tanstack', 'router') + writeJson(join(pkgDir, 'package.json'), { + name: '@tanstack/router', + version: '1.0.0', + bin: { intent: './bin/intent.js' }, + }) + const routingDir = createDir(pkgDir, 'skills', 'routing') + writeSkillMd(routingDir, { + name: 'routing', + description: 'Routing overview', + }) + const nestedDir = createDir(routingDir, 'nested-routes') + writeSkillMd(nestedDir, { + name: 'routing/nested-routes', + description: 'Nested route patterns', + }) + + const result = await scanLibrary(shimPath(pkgDir), root) + + const skills = result.packages[0]!.skills + expect(skills).toHaveLength(2) + const names = skills.map((s) => s.name) + expect(names).toContain('routing') + expect(names).toContain('routing/nested-routes') + }) + + it('returns a warning when home package.json cannot be found', async () => { + const fakeScript = join(root, 'nowhere', 'bin', 'intent.js') + + const result = await scanLibrary(fakeScript, root) + + expect(result.packages).toEqual([]) + expect(result.warnings).toHaveLength(1) + expect(result.warnings[0]).toMatch(/home package/i) + }) +}) diff --git a/packages/intent/tests/meta-feedback.test.ts b/packages/intent/tests/meta-feedback.test.ts index 54227cc3..8be8c676 100644 --- a/packages/intent/tests/meta-feedback.test.ts +++ b/packages/intent/tests/meta-feedback.test.ts @@ -1,199 +1,199 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { - existsSync, - mkdirSync, - readFileSync, - rmSync, - writeFileSync, -} from 'node:fs' -import { join } from 'node:path' -import { tmpdir } from 'node:os' -import { - validateMetaPayload, - metaToMarkdown, - submitMetaFeedback, -} from '../src/feedback.js' -import type { MetaFeedbackPayload } from '../src/types.js' - -// --------------------------------------------------------------------------- -// Fixtures -// --------------------------------------------------------------------------- - -let tmpDir: string - -function setupDir(): string { - const dir = join( - tmpdir(), - `intent-meta-fb-test-${Date.now()}-${Math.random().toString(36).slice(2)}`, - ) - mkdirSync(dir, { recursive: true }) - return dir -} - -function validMetaPayload( - overrides: Partial = {}, -): MetaFeedbackPayload { - return { - metaSkill: 'domain-discovery', - library: '@tanstack/query', - agentUsed: 'claude-code', - artifactQuality: 'good', - whatWorked: 'Interview questions surfaced real failure modes', - whatFailed: 'Missed some SSR-specific gotchas', - suggestions: 'Add more framework-specific probing', - userRating: 'mixed', - ...overrides, - } -} - -beforeEach(() => { - tmpDir = setupDir() -}) - -afterEach(() => { - if (existsSync(tmpDir)) { - rmSync(tmpDir, { recursive: true, force: true }) - } -}) - -// --------------------------------------------------------------------------- -// validateMetaPayload -// --------------------------------------------------------------------------- - -describe('validateMetaPayload', () => { - it('accepts a valid payload', () => { - const result = validateMetaPayload(validMetaPayload()) - expect(result.valid).toBe(true) - expect(result.errors).toHaveLength(0) - }) - - it('rejects non-object input', () => { - const result = validateMetaPayload('not an object') - expect(result.valid).toBe(false) - expect(result.errors[0]).toContain('JSON object') - }) - - it('rejects null', () => { - const result = validateMetaPayload(null) - expect(result.valid).toBe(false) - }) - - it('reports missing required fields', () => { - const result = validateMetaPayload({ metaSkill: 'domain-discovery' }) - expect(result.valid).toBe(false) - expect(result.errors.length).toBeGreaterThan(1) - expect(result.errors.some((e) => e.includes('library'))).toBe(true) - }) - - it('rejects empty string fields', () => { - const result = validateMetaPayload(validMetaPayload({ whatWorked: '' })) - expect(result.valid).toBe(false) - expect(result.errors.some((e) => e.includes('whatWorked'))).toBe(true) - }) - - it('rejects invalid metaSkill', () => { - const result = validateMetaPayload( - validMetaPayload({ metaSkill: 'not-a-skill' as any }), - ) - expect(result.valid).toBe(false) - expect(result.errors.some((e) => e.includes('metaSkill'))).toBe(true) - }) - - it('rejects invalid agentUsed', () => { - const result = validateMetaPayload( - validMetaPayload({ agentUsed: 'chatgpt' as any }), - ) - expect(result.valid).toBe(false) - expect(result.errors.some((e) => e.includes('agentUsed'))).toBe(true) - }) - - it('rejects invalid userRating', () => { - const result = validateMetaPayload( - validMetaPayload({ userRating: 'excellent' as any }), - ) - expect(result.valid).toBe(false) - expect(result.errors.some((e) => e.includes('userRating'))).toBe(true) - }) - - it('rejects payloads containing secrets', () => { - const result = validateMetaPayload( - validMetaPayload({ - whatFailed: 'Used token ghp_' + 'A'.repeat(36) + ' and it failed', - }), - ) - expect(result.valid).toBe(false) - expect(result.errors.some((e) => e.includes('secrets'))).toBe(true) - }) - - it('accepts optional fields', () => { - const result = validateMetaPayload( - validMetaPayload({ - interviewQuality: 'good', - failureModeQuality: 'mixed', - }), - ) - expect(result.valid).toBe(true) - }) -}) - -// --------------------------------------------------------------------------- -// metaToMarkdown -// --------------------------------------------------------------------------- - -describe('metaToMarkdown', () => { - it('converts payload to markdown', () => { - const md = metaToMarkdown(validMetaPayload()) - expect(md).toContain('# Meta-Skill Feedback: domain-discovery') - expect(md).toContain('**Library:** @tanstack/query') - expect(md).toContain('**Agent:** claude-code') - expect(md).toContain('**Artifact quality:** good') - expect(md).toContain('**Rating:** mixed') - expect(md).toContain('## What Worked') - expect(md).toContain('## What Failed') - expect(md).toContain('## Suggestions') - }) - - it('includes optional quality fields when present', () => { - const md = metaToMarkdown( - validMetaPayload({ - interviewQuality: 'good', - failureModeQuality: 'bad', - }), - ) - expect(md).toContain('**Interview quality:** good') - expect(md).toContain('**Failure mode quality:** bad') - }) - - it('omits optional quality fields when not present', () => { - const md = metaToMarkdown(validMetaPayload()) - expect(md).not.toContain('Interview quality') - expect(md).not.toContain('Failure mode quality') - }) -}) - -// --------------------------------------------------------------------------- -// submitMetaFeedback -// --------------------------------------------------------------------------- - -describe('submitMetaFeedback', () => { - it('saves to file when gh not available and outputPath given', () => { - const outPath = join(tmpDir, 'meta-feedback.md') - const result = submitMetaFeedback(validMetaPayload(), { - ghAvailable: false, - outputPath: outPath, - }) - expect(result.method).toBe('file') - expect(result.detail).toContain(outPath) - expect(existsSync(outPath)).toBe(true) - const content = readFileSync(outPath, 'utf8') - expect(content).toContain('# Meta-Skill Feedback') - }) - - it('returns stdout when no gh and no outputPath', () => { - const result = submitMetaFeedback(validMetaPayload(), { - ghAvailable: false, - }) - expect(result.method).toBe('stdout') - expect(result.detail).toContain('# Meta-Skill Feedback') - }) -}) +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { + existsSync, + mkdirSync, + readFileSync, + rmSync, + writeFileSync, +} from 'node:fs' +import { join } from 'node:path' +import { tmpdir } from 'node:os' +import { + validateMetaPayload, + metaToMarkdown, + submitMetaFeedback, +} from '../src/feedback.js' +import type { MetaFeedbackPayload } from '../src/types.js' + +// --------------------------------------------------------------------------- +// Fixtures +// --------------------------------------------------------------------------- + +let tmpDir: string + +function setupDir(): string { + const dir = join( + tmpdir(), + `intent-meta-fb-test-${Date.now()}-${Math.random().toString(36).slice(2)}`, + ) + mkdirSync(dir, { recursive: true }) + return dir +} + +function validMetaPayload( + overrides: Partial = {}, +): MetaFeedbackPayload { + return { + metaSkill: 'domain-discovery', + library: '@tanstack/query', + agentUsed: 'claude-code', + artifactQuality: 'good', + whatWorked: 'Interview questions surfaced real failure modes', + whatFailed: 'Missed some SSR-specific gotchas', + suggestions: 'Add more framework-specific probing', + userRating: 'mixed', + ...overrides, + } +} + +beforeEach(() => { + tmpDir = setupDir() +}) + +afterEach(() => { + if (existsSync(tmpDir)) { + rmSync(tmpDir, { recursive: true, force: true }) + } +}) + +// --------------------------------------------------------------------------- +// validateMetaPayload +// --------------------------------------------------------------------------- + +describe('validateMetaPayload', () => { + it('accepts a valid payload', () => { + const result = validateMetaPayload(validMetaPayload()) + expect(result.valid).toBe(true) + expect(result.errors).toHaveLength(0) + }) + + it('rejects non-object input', () => { + const result = validateMetaPayload('not an object') + expect(result.valid).toBe(false) + expect(result.errors[0]).toContain('JSON object') + }) + + it('rejects null', () => { + const result = validateMetaPayload(null) + expect(result.valid).toBe(false) + }) + + it('reports missing required fields', () => { + const result = validateMetaPayload({ metaSkill: 'domain-discovery' }) + expect(result.valid).toBe(false) + expect(result.errors.length).toBeGreaterThan(1) + expect(result.errors.some((e) => e.includes('library'))).toBe(true) + }) + + it('rejects empty string fields', () => { + const result = validateMetaPayload(validMetaPayload({ whatWorked: '' })) + expect(result.valid).toBe(false) + expect(result.errors.some((e) => e.includes('whatWorked'))).toBe(true) + }) + + it('rejects invalid metaSkill', () => { + const result = validateMetaPayload( + validMetaPayload({ metaSkill: 'not-a-skill' as any }), + ) + expect(result.valid).toBe(false) + expect(result.errors.some((e) => e.includes('metaSkill'))).toBe(true) + }) + + it('rejects invalid agentUsed', () => { + const result = validateMetaPayload( + validMetaPayload({ agentUsed: 'chatgpt' as any }), + ) + expect(result.valid).toBe(false) + expect(result.errors.some((e) => e.includes('agentUsed'))).toBe(true) + }) + + it('rejects invalid userRating', () => { + const result = validateMetaPayload( + validMetaPayload({ userRating: 'excellent' as any }), + ) + expect(result.valid).toBe(false) + expect(result.errors.some((e) => e.includes('userRating'))).toBe(true) + }) + + it('rejects payloads containing secrets', () => { + const result = validateMetaPayload( + validMetaPayload({ + whatFailed: 'Used token ghp_' + 'A'.repeat(36) + ' and it failed', + }), + ) + expect(result.valid).toBe(false) + expect(result.errors.some((e) => e.includes('secrets'))).toBe(true) + }) + + it('accepts optional fields', () => { + const result = validateMetaPayload( + validMetaPayload({ + interviewQuality: 'good', + failureModeQuality: 'mixed', + }), + ) + expect(result.valid).toBe(true) + }) +}) + +// --------------------------------------------------------------------------- +// metaToMarkdown +// --------------------------------------------------------------------------- + +describe('metaToMarkdown', () => { + it('converts payload to markdown', () => { + const md = metaToMarkdown(validMetaPayload()) + expect(md).toContain('# Meta-Skill Feedback: domain-discovery') + expect(md).toContain('**Library:** @tanstack/query') + expect(md).toContain('**Agent:** claude-code') + expect(md).toContain('**Artifact quality:** good') + expect(md).toContain('**Rating:** mixed') + expect(md).toContain('## What Worked') + expect(md).toContain('## What Failed') + expect(md).toContain('## Suggestions') + }) + + it('includes optional quality fields when present', () => { + const md = metaToMarkdown( + validMetaPayload({ + interviewQuality: 'good', + failureModeQuality: 'bad', + }), + ) + expect(md).toContain('**Interview quality:** good') + expect(md).toContain('**Failure mode quality:** bad') + }) + + it('omits optional quality fields when not present', () => { + const md = metaToMarkdown(validMetaPayload()) + expect(md).not.toContain('Interview quality') + expect(md).not.toContain('Failure mode quality') + }) +}) + +// --------------------------------------------------------------------------- +// submitMetaFeedback +// --------------------------------------------------------------------------- + +describe('submitMetaFeedback', () => { + it('saves to file when gh not available and outputPath given', () => { + const outPath = join(tmpDir, 'meta-feedback.md') + const result = submitMetaFeedback(validMetaPayload(), { + ghAvailable: false, + outputPath: outPath, + }) + expect(result.method).toBe('file') + expect(result.detail).toContain(outPath) + expect(existsSync(outPath)).toBe(true) + const content = readFileSync(outPath, 'utf8') + expect(content).toContain('# Meta-Skill Feedback') + }) + + it('returns stdout when no gh and no outputPath', () => { + const result = submitMetaFeedback(validMetaPayload(), { + ghAvailable: false, + }) + expect(result.method).toBe('stdout') + expect(result.detail).toContain('# Meta-Skill Feedback') + }) +}) diff --git a/packages/intent/tests/scanner.test.ts b/packages/intent/tests/scanner.test.ts index 7942ee39..1378c180 100644 --- a/packages/intent/tests/scanner.test.ts +++ b/packages/intent/tests/scanner.test.ts @@ -1,238 +1,238 @@ -import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' -import { join } from 'node:path' -import { tmpdir } from 'node:os' -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { scanForIntents } from '../src/scanner.js' - -// ── Helpers ── - -function createDir(...segments: string[]): string { - const dir = join(...segments) - mkdirSync(dir, { recursive: true }) - return dir -} - -function writeJson(filePath: string, data: unknown): void { - writeFileSync(filePath, JSON.stringify(data, null, 2)) -} - -function writeSkillMd(dir: string, frontmatter: Record): void { - const yamlLines = Object.entries(frontmatter) - .map(([k, v]) => `${k}: ${typeof v === 'string' ? `"${v}"` : v}`) - .join('\n') - writeFileSync( - join(dir, 'SKILL.md'), - `---\n${yamlLines}\n---\n\nSkill content here.\n`, - ) -} - -// ── Setup / Teardown ── - -let root: string - -beforeEach(() => { - root = mkdtempSync(join(tmpdir(), 'intent-test-')) -}) - -afterEach(() => { - rmSync(root, { recursive: true, force: true }) -}) - -// ── Tests ── - -describe('scanForIntents', () => { - it('returns empty packages when no node_modules exists', async () => { - const result = await scanForIntents(root) - expect(result.packages).toEqual([]) - expect(result.warnings).toEqual([]) - }) - - it('returns empty packages when node_modules has no intent packages', async () => { - createDir(root, 'node_modules', 'some-lib') - writeJson(join(root, 'node_modules', 'some-lib', 'package.json'), { - name: 'some-lib', - version: '1.0.0', - }) - const result = await scanForIntents(root) - expect(result.packages).toEqual([]) - }) - - it('discovers an intent-enabled package with skills', async () => { - const pkgDir = createDir(root, 'node_modules', '@tanstack', 'db') - writeJson(join(pkgDir, 'package.json'), { - name: '@tanstack/db', - version: '0.5.2', - intent: { - version: 1, - repo: 'TanStack/db', - docs: 'docs/', - }, - }) - const skillDir = createDir(pkgDir, 'skills', 'db-core') - writeSkillMd(skillDir, { - name: 'db-core', - description: 'Core database concepts', - type: 'core', - }) - - const result = await scanForIntents(root) - expect(result.packages).toHaveLength(1) - expect(result.packages[0]!.name).toBe('@tanstack/db') - expect(result.packages[0]!.version).toBe('0.5.2') - expect(result.packages[0]!.skills).toHaveLength(1) - expect(result.packages[0]!.skills[0]!.name).toBe('db-core') - expect(result.packages[0]!.skills[0]!.description).toBe( - 'Core database concepts', - ) - }) - - it('discovers sub-skills', async () => { - const pkgDir = createDir(root, 'node_modules', '@tanstack', 'db') - writeJson(join(pkgDir, 'package.json'), { - name: '@tanstack/db', - version: '0.5.2', - intent: { version: 1, repo: 'TanStack/db', docs: 'docs/' }, - }) - const coreDir = createDir(pkgDir, 'skills', 'db-core') - writeSkillMd(coreDir, { name: 'db-core', description: 'Core' }) - const subDir = createDir(coreDir, 'live-queries') - writeSkillMd(subDir, { - name: 'db-core/live-queries', - description: 'Queries', - }) - - const result = await scanForIntents(root) - expect(result.packages[0]!.skills).toHaveLength(2) - const names = result.packages[0]!.skills.map((s) => s.name) - expect(names).toContain('db-core') - expect(names).toContain('db-core/live-queries') - }) - - it('warns on skills/ dir without valid intent field', async () => { - const pkgDir = createDir(root, 'node_modules', 'bad-pkg') - writeJson(join(pkgDir, 'package.json'), { - name: 'bad-pkg', - version: '1.0.0', - // no intent field - }) - createDir(pkgDir, 'skills', 'some-skill') - - const result = await scanForIntents(root) - expect(result.packages).toHaveLength(0) - expect(result.warnings).toHaveLength(1) - expect(result.warnings[0]).toContain('bad-pkg') - }) - - it('warns on invalid intent version', async () => { - const pkgDir = createDir(root, 'node_modules', 'wrong-ver') - writeJson(join(pkgDir, 'package.json'), { - name: 'wrong-ver', - version: '1.0.0', - intent: { version: 99, repo: 'foo/bar', docs: 'docs/' }, - }) - createDir(pkgDir, 'skills', 'some-skill') - - const result = await scanForIntents(root) - expect(result.packages).toHaveLength(0) - expect(result.warnings).toHaveLength(1) - }) - - it('sorts packages by dependency order (requires)', async () => { - // Create core package (no requires) - const coreDir = createDir(root, 'node_modules', '@tanstack', 'db') - writeJson(join(coreDir, 'package.json'), { - name: '@tanstack/db', - version: '0.5.0', - intent: { version: 1, repo: 'TanStack/db', docs: 'docs/' }, - }) - const coreSkill = createDir(coreDir, 'skills', 'db-core') - writeSkillMd(coreSkill, { name: 'db-core', description: 'Core' }) - - // Create framework package (requires core) - const reactDir = createDir(root, 'node_modules', '@tanstack', 'react-db') - writeJson(join(reactDir, 'package.json'), { - name: '@tanstack/react-db', - version: '0.5.0', - intent: { - version: 1, - repo: 'TanStack/db', - docs: 'docs/', - requires: ['@tanstack/db'], - }, - }) - const reactSkill = createDir(reactDir, 'skills', 'react-db') - writeSkillMd(reactSkill, { - name: 'react-db', - description: 'React bindings', - }) - - const result = await scanForIntents(root) - expect(result.packages).toHaveLength(2) - // Core should come first - expect(result.packages[0]!.name).toBe('@tanstack/db') - expect(result.packages[1]!.name).toBe('@tanstack/react-db') - }) - - it('skips packages without skills/ directory', async () => { - const pkgDir = createDir(root, 'node_modules', 'no-skills') - writeJson(join(pkgDir, 'package.json'), { - name: 'no-skills', - version: '1.0.0', - intent: { version: 1, repo: 'foo/bar', docs: 'docs/' }, - }) - // No skills/ directory - - const result = await scanForIntents(root) - expect(result.packages).toHaveLength(0) - expect(result.warnings).toHaveLength(0) - }) -}) - -describe('package manager detection', () => { - it('detects npm from package-lock.json', async () => { - writeFileSync(join(root, 'package-lock.json'), '{}') - createDir(root, 'node_modules') - const result = await scanForIntents(root) - expect(result.packageManager).toBe('npm') - }) - - it('detects pnpm from pnpm-lock.yaml', async () => { - writeFileSync(join(root, 'pnpm-lock.yaml'), '') - createDir(root, 'node_modules') - const result = await scanForIntents(root) - expect(result.packageManager).toBe('pnpm') - }) - - it('detects yarn from yarn.lock', async () => { - writeFileSync(join(root, 'yarn.lock'), '') - createDir(root, 'node_modules') - const result = await scanForIntents(root) - expect(result.packageManager).toBe('yarn') - }) - - it('detects bun from bun.lockb', async () => { - writeFileSync(join(root, 'bun.lockb'), '') - createDir(root, 'node_modules') - const result = await scanForIntents(root) - expect(result.packageManager).toBe('bun') - }) - - it('returns unknown when no lockfile found', async () => { - createDir(root, 'node_modules') - const result = await scanForIntents(root) - expect(result.packageManager).toBe('unknown') - }) - - it('throws for Yarn PnP', async () => { - writeFileSync(join(root, '.pnp.cjs'), '') - await expect(scanForIntents(root)).rejects.toThrow('Yarn PnP') - }) - - it('throws for Deno without node_modules', async () => { - writeFileSync(join(root, 'deno.json'), '{}') - // No node_modules dir - await expect(scanForIntents(root)).rejects.toThrow( - 'Deno without node_modules', - ) - }) -}) +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' +import { join } from 'node:path' +import { tmpdir } from 'node:os' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { scanForIntents } from '../src/scanner.js' + +// ── Helpers ── + +function createDir(...segments: string[]): string { + const dir = join(...segments) + mkdirSync(dir, { recursive: true }) + return dir +} + +function writeJson(filePath: string, data: unknown): void { + writeFileSync(filePath, JSON.stringify(data, null, 2)) +} + +function writeSkillMd(dir: string, frontmatter: Record): void { + const yamlLines = Object.entries(frontmatter) + .map(([k, v]) => `${k}: ${typeof v === 'string' ? `"${v}"` : v}`) + .join('\n') + writeFileSync( + join(dir, 'SKILL.md'), + `---\n${yamlLines}\n---\n\nSkill content here.\n`, + ) +} + +// ── Setup / Teardown ── + +let root: string + +beforeEach(() => { + root = mkdtempSync(join(tmpdir(), 'intent-test-')) +}) + +afterEach(() => { + rmSync(root, { recursive: true, force: true }) +}) + +// ── Tests ── + +describe('scanForIntents', () => { + it('returns empty packages when no node_modules exists', async () => { + const result = await scanForIntents(root) + expect(result.packages).toEqual([]) + expect(result.warnings).toEqual([]) + }) + + it('returns empty packages when node_modules has no intent packages', async () => { + createDir(root, 'node_modules', 'some-lib') + writeJson(join(root, 'node_modules', 'some-lib', 'package.json'), { + name: 'some-lib', + version: '1.0.0', + }) + const result = await scanForIntents(root) + expect(result.packages).toEqual([]) + }) + + it('discovers an intent-enabled package with skills', async () => { + const pkgDir = createDir(root, 'node_modules', '@tanstack', 'db') + writeJson(join(pkgDir, 'package.json'), { + name: '@tanstack/db', + version: '0.5.2', + intent: { + version: 1, + repo: 'TanStack/db', + docs: 'docs/', + }, + }) + const skillDir = createDir(pkgDir, 'skills', 'db-core') + writeSkillMd(skillDir, { + name: 'db-core', + description: 'Core database concepts', + type: 'core', + }) + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(1) + expect(result.packages[0]!.name).toBe('@tanstack/db') + expect(result.packages[0]!.version).toBe('0.5.2') + expect(result.packages[0]!.skills).toHaveLength(1) + expect(result.packages[0]!.skills[0]!.name).toBe('db-core') + expect(result.packages[0]!.skills[0]!.description).toBe( + 'Core database concepts', + ) + }) + + it('discovers sub-skills', async () => { + const pkgDir = createDir(root, 'node_modules', '@tanstack', 'db') + writeJson(join(pkgDir, 'package.json'), { + name: '@tanstack/db', + version: '0.5.2', + intent: { version: 1, repo: 'TanStack/db', docs: 'docs/' }, + }) + const coreDir = createDir(pkgDir, 'skills', 'db-core') + writeSkillMd(coreDir, { name: 'db-core', description: 'Core' }) + const subDir = createDir(coreDir, 'live-queries') + writeSkillMd(subDir, { + name: 'db-core/live-queries', + description: 'Queries', + }) + + const result = await scanForIntents(root) + expect(result.packages[0]!.skills).toHaveLength(2) + const names = result.packages[0]!.skills.map((s) => s.name) + expect(names).toContain('db-core') + expect(names).toContain('db-core/live-queries') + }) + + it('warns on skills/ dir without valid intent field', async () => { + const pkgDir = createDir(root, 'node_modules', 'bad-pkg') + writeJson(join(pkgDir, 'package.json'), { + name: 'bad-pkg', + version: '1.0.0', + // no intent field + }) + createDir(pkgDir, 'skills', 'some-skill') + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(0) + expect(result.warnings).toHaveLength(1) + expect(result.warnings[0]).toContain('bad-pkg') + }) + + it('warns on invalid intent version', async () => { + const pkgDir = createDir(root, 'node_modules', 'wrong-ver') + writeJson(join(pkgDir, 'package.json'), { + name: 'wrong-ver', + version: '1.0.0', + intent: { version: 99, repo: 'foo/bar', docs: 'docs/' }, + }) + createDir(pkgDir, 'skills', 'some-skill') + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(0) + expect(result.warnings).toHaveLength(1) + }) + + it('sorts packages by dependency order (requires)', async () => { + // Create core package (no requires) + const coreDir = createDir(root, 'node_modules', '@tanstack', 'db') + writeJson(join(coreDir, 'package.json'), { + name: '@tanstack/db', + version: '0.5.0', + intent: { version: 1, repo: 'TanStack/db', docs: 'docs/' }, + }) + const coreSkill = createDir(coreDir, 'skills', 'db-core') + writeSkillMd(coreSkill, { name: 'db-core', description: 'Core' }) + + // Create framework package (requires core) + const reactDir = createDir(root, 'node_modules', '@tanstack', 'react-db') + writeJson(join(reactDir, 'package.json'), { + name: '@tanstack/react-db', + version: '0.5.0', + intent: { + version: 1, + repo: 'TanStack/db', + docs: 'docs/', + requires: ['@tanstack/db'], + }, + }) + const reactSkill = createDir(reactDir, 'skills', 'react-db') + writeSkillMd(reactSkill, { + name: 'react-db', + description: 'React bindings', + }) + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(2) + // Core should come first + expect(result.packages[0]!.name).toBe('@tanstack/db') + expect(result.packages[1]!.name).toBe('@tanstack/react-db') + }) + + it('skips packages without skills/ directory', async () => { + const pkgDir = createDir(root, 'node_modules', 'no-skills') + writeJson(join(pkgDir, 'package.json'), { + name: 'no-skills', + version: '1.0.0', + intent: { version: 1, repo: 'foo/bar', docs: 'docs/' }, + }) + // No skills/ directory + + const result = await scanForIntents(root) + expect(result.packages).toHaveLength(0) + expect(result.warnings).toHaveLength(0) + }) +}) + +describe('package manager detection', () => { + it('detects npm from package-lock.json', async () => { + writeFileSync(join(root, 'package-lock.json'), '{}') + createDir(root, 'node_modules') + const result = await scanForIntents(root) + expect(result.packageManager).toBe('npm') + }) + + it('detects pnpm from pnpm-lock.yaml', async () => { + writeFileSync(join(root, 'pnpm-lock.yaml'), '') + createDir(root, 'node_modules') + const result = await scanForIntents(root) + expect(result.packageManager).toBe('pnpm') + }) + + it('detects yarn from yarn.lock', async () => { + writeFileSync(join(root, 'yarn.lock'), '') + createDir(root, 'node_modules') + const result = await scanForIntents(root) + expect(result.packageManager).toBe('yarn') + }) + + it('detects bun from bun.lockb', async () => { + writeFileSync(join(root, 'bun.lockb'), '') + createDir(root, 'node_modules') + const result = await scanForIntents(root) + expect(result.packageManager).toBe('bun') + }) + + it('returns unknown when no lockfile found', async () => { + createDir(root, 'node_modules') + const result = await scanForIntents(root) + expect(result.packageManager).toBe('unknown') + }) + + it('throws for Yarn PnP', async () => { + writeFileSync(join(root, '.pnp.cjs'), '') + await expect(scanForIntents(root)).rejects.toThrow('Yarn PnP') + }) + + it('throws for Deno without node_modules', async () => { + writeFileSync(join(root, 'deno.json'), '{}') + // No node_modules dir + await expect(scanForIntents(root)).rejects.toThrow( + 'Deno without node_modules', + ) + }) +}) diff --git a/packages/intent/tests/setup.test.ts b/packages/intent/tests/setup.test.ts index 2144ea20..06aee6c6 100644 --- a/packages/intent/tests/setup.test.ts +++ b/packages/intent/tests/setup.test.ts @@ -1,90 +1,90 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { - existsSync, - mkdirSync, - mkdtempSync, - readFileSync, - rmSync, - writeFileSync, -} from 'node:fs' -import { join } from 'node:path' -import { tmpdir } from 'node:os' -import { runSetup } from '../src/setup.js' - -let root: string -let metaDir: string - -beforeEach(() => { - root = mkdtempSync(join(tmpdir(), 'setup-test-')) - metaDir = join(root, 'meta') - - // Create mock templates - mkdirSync(join(metaDir, 'templates', 'workflows'), { recursive: true }) - - writeFileSync( - join(metaDir, 'templates', 'workflows', 'notify-intent.yml'), - 'package: {{PACKAGE_NAME}}\nrepo: {{REPO}}\ndocs: {{DOCS_PATH}}\nsrc: {{SRC_PATH}}', - ) -}) - -afterEach(() => { - rmSync(root, { recursive: true, force: true }) -}) - -describe('runSetup', () => { - it('copies workflow templates with defaults', () => { - const result = runSetup(root, metaDir, []) - expect(result.workflows).toHaveLength(1) - expect(result.skipped).toHaveLength(0) - - const wfPath = join(root, '.github', 'workflows', 'notify-intent.yml') - expect(existsSync(wfPath)).toBe(true) - const content = readFileSync(wfPath, 'utf8') - expect(content).toContain('package: unknown') - }) - - it('substitutes variables from package.json intent field', () => { - writeFileSync( - join(root, 'package.json'), - JSON.stringify({ - name: '@tanstack/query', - intent: { repo: 'TanStack/query', docs: 'docs/' }, - }), - ) - - const result = runSetup(root, metaDir, []) - const wfContent = readFileSync( - join(root, '.github', 'workflows', 'notify-intent.yml'), - 'utf8', - ) - expect(wfContent).toContain('package: @tanstack/query') - expect(wfContent).toContain('repo: TanStack/query') - expect(wfContent).toContain('docs: docs/**') - }) - - it('only copies workflows with --workflows flag', () => { - const result = runSetup(root, metaDir, ['--workflows']) - expect(result.workflows).toHaveLength(1) - }) - - it('copies all with --all flag', () => { - const result = runSetup(root, metaDir, ['--all']) - expect(result.workflows).toHaveLength(1) - }) - - it('skips existing files', () => { - // First run - runSetup(root, metaDir, []) - // Second run - const result = runSetup(root, metaDir, []) - expect(result.workflows).toHaveLength(0) - expect(result.skipped).toHaveLength(2) - }) - - it('handles missing templates directory gracefully', () => { - const emptyMeta = join(root, 'empty-meta') - mkdirSync(emptyMeta) - const result = runSetup(root, emptyMeta, []) - expect(result.workflows).toHaveLength(0) - }) -}) +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { + existsSync, + mkdirSync, + mkdtempSync, + readFileSync, + rmSync, + writeFileSync, +} from 'node:fs' +import { join } from 'node:path' +import { tmpdir } from 'node:os' +import { runSetup } from '../src/setup.js' + +let root: string +let metaDir: string + +beforeEach(() => { + root = mkdtempSync(join(tmpdir(), 'setup-test-')) + metaDir = join(root, 'meta') + + // Create mock templates + mkdirSync(join(metaDir, 'templates', 'workflows'), { recursive: true }) + + writeFileSync( + join(metaDir, 'templates', 'workflows', 'notify-intent.yml'), + 'package: {{PACKAGE_NAME}}\nrepo: {{REPO}}\ndocs: {{DOCS_PATH}}\nsrc: {{SRC_PATH}}', + ) +}) + +afterEach(() => { + rmSync(root, { recursive: true, force: true }) +}) + +describe('runSetup', () => { + it('copies workflow templates with defaults', () => { + const result = runSetup(root, metaDir, []) + expect(result.workflows).toHaveLength(1) + expect(result.skipped).toHaveLength(0) + + const wfPath = join(root, '.github', 'workflows', 'notify-intent.yml') + expect(existsSync(wfPath)).toBe(true) + const content = readFileSync(wfPath, 'utf8') + expect(content).toContain('package: unknown') + }) + + it('substitutes variables from package.json intent field', () => { + writeFileSync( + join(root, 'package.json'), + JSON.stringify({ + name: '@tanstack/query', + intent: { repo: 'TanStack/query', docs: 'docs/' }, + }), + ) + + const result = runSetup(root, metaDir, []) + const wfContent = readFileSync( + join(root, '.github', 'workflows', 'notify-intent.yml'), + 'utf8', + ) + expect(wfContent).toContain('package: @tanstack/query') + expect(wfContent).toContain('repo: TanStack/query') + expect(wfContent).toContain('docs: docs/**') + }) + + it('only copies workflows with --workflows flag', () => { + const result = runSetup(root, metaDir, ['--workflows']) + expect(result.workflows).toHaveLength(1) + }) + + it('copies all with --all flag', () => { + const result = runSetup(root, metaDir, ['--all']) + expect(result.workflows).toHaveLength(1) + }) + + it('skips existing files', () => { + // First run + runSetup(root, metaDir, []) + // Second run + const result = runSetup(root, metaDir, []) + expect(result.workflows).toHaveLength(0) + expect(result.skipped).toHaveLength(2) + }) + + it('handles missing templates directory gracefully', () => { + const emptyMeta = join(root, 'empty-meta') + mkdirSync(emptyMeta) + const result = runSetup(root, emptyMeta, []) + expect(result.workflows).toHaveLength(0) + }) +}) diff --git a/packages/intent/tests/skills.test.ts b/packages/intent/tests/skills.test.ts index 66015eb8..e9a279ae 100644 --- a/packages/intent/tests/skills.test.ts +++ b/packages/intent/tests/skills.test.ts @@ -1,130 +1,130 @@ -import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs' -import { join, relative, sep } from 'node:path' -import { describe, expect, it } from 'vitest' -import { parse as parseYaml } from 'yaml' - -// ── Types ── - -interface SkillFrontmatter { - name: string - description: string - type?: string - library?: string - framework?: string - library_version?: string - requires?: Array - sources?: Array -} - -// ── Helpers ── - -const META_DIR = join(__dirname, '..', 'meta') -const MAX_META_SKILL_LINES = 1000 - -function findSkillFiles(dir: string): Array { - const files: Array = [] - if (!existsSync(dir)) return files - - for (const entry of readdirSync(dir)) { - const fullPath = join(dir, entry) - const stat = statSync(fullPath) - if (stat.isDirectory()) { - files.push(...findSkillFiles(fullPath)) - } else if (entry === 'SKILL.md') { - files.push(fullPath) - } - } - return files -} - -function extractFrontmatter( - content: string, -): { frontmatter: SkillFrontmatter; body: string } | null { - const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)/) - if (!match) return null - - try { - const frontmatter = parseYaml(match[1]) as SkillFrontmatter - return { frontmatter, body: match[2] } - } catch { - return null - } -} - -function skillPathFromFile(baseDir: string, filePath: string): string { - return relative(baseDir, filePath) - .replace(/[/\\]SKILL\.md$/, '') - .split(sep) - .join('/') -} - -// ── Collect meta-skills ── - -const metaSkillFiles = findSkillFiles(META_DIR) -const metaSkills = metaSkillFiles.map((filePath) => { - const content = readFileSync(filePath, 'utf-8') - const parsed = extractFrontmatter(content) - const relPath = skillPathFromFile(META_DIR, filePath) - return { filePath, content, parsed, relPath } -}) - -// ── Tests ── - -describe('meta-skill discovery', () => { - it('should find meta-skill files', () => { - expect(metaSkillFiles.length).toBeGreaterThan(0) - }) - - it('should include domain-discovery', () => { - expect( - metaSkills.find((s) => s.relPath === 'domain-discovery'), - ).toBeDefined() - }) - - it('should include tree-generator', () => { - expect(metaSkills.find((s) => s.relPath === 'tree-generator')).toBeDefined() - }) - - it('should include generate-skill', () => { - expect(metaSkills.find((s) => s.relPath === 'generate-skill')).toBeDefined() - }) - - it('should include skill-staleness-check', () => { - expect( - metaSkills.find((s) => s.relPath === 'skill-staleness-check'), - ).toBeDefined() - }) -}) - -describe('meta-skill frontmatter', () => { - for (const skill of metaSkills) { - describe(skill.relPath, () => { - it('should have valid frontmatter', () => { - expect(skill.parsed).not.toBeNull() - }) - - if (!skill.parsed) return - - const { frontmatter } = skill.parsed - - it('should have a name', () => { - expect(frontmatter.name).toBeTruthy() - }) - - it('should have a description', () => { - expect(frontmatter.description).toBeTruthy() - }) - }) - } -}) - -describe('meta-skill content', () => { - for (const skill of metaSkills) { - describe(skill.relPath, () => { - it(`should not exceed ${MAX_META_SKILL_LINES} lines`, () => { - const lineCount = skill.content.split(/\r?\n/).length - expect(lineCount).toBeLessThanOrEqual(MAX_META_SKILL_LINES) - }) - }) - } -}) +import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs' +import { join, relative, sep } from 'node:path' +import { describe, expect, it } from 'vitest' +import { parse as parseYaml } from 'yaml' + +// ── Types ── + +interface SkillFrontmatter { + name: string + description: string + type?: string + library?: string + framework?: string + library_version?: string + requires?: Array + sources?: Array +} + +// ── Helpers ── + +const META_DIR = join(__dirname, '..', 'meta') +const MAX_META_SKILL_LINES = 1000 + +function findSkillFiles(dir: string): Array { + const files: Array = [] + if (!existsSync(dir)) return files + + for (const entry of readdirSync(dir)) { + const fullPath = join(dir, entry) + const stat = statSync(fullPath) + if (stat.isDirectory()) { + files.push(...findSkillFiles(fullPath)) + } else if (entry === 'SKILL.md') { + files.push(fullPath) + } + } + return files +} + +function extractFrontmatter( + content: string, +): { frontmatter: SkillFrontmatter; body: string } | null { + const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)/) + if (!match) return null + + try { + const frontmatter = parseYaml(match[1]) as SkillFrontmatter + return { frontmatter, body: match[2] } + } catch { + return null + } +} + +function skillPathFromFile(baseDir: string, filePath: string): string { + return relative(baseDir, filePath) + .replace(/[/\\]SKILL\.md$/, '') + .split(sep) + .join('/') +} + +// ── Collect meta-skills ── + +const metaSkillFiles = findSkillFiles(META_DIR) +const metaSkills = metaSkillFiles.map((filePath) => { + const content = readFileSync(filePath, 'utf-8') + const parsed = extractFrontmatter(content) + const relPath = skillPathFromFile(META_DIR, filePath) + return { filePath, content, parsed, relPath } +}) + +// ── Tests ── + +describe('meta-skill discovery', () => { + it('should find meta-skill files', () => { + expect(metaSkillFiles.length).toBeGreaterThan(0) + }) + + it('should include domain-discovery', () => { + expect( + metaSkills.find((s) => s.relPath === 'domain-discovery'), + ).toBeDefined() + }) + + it('should include tree-generator', () => { + expect(metaSkills.find((s) => s.relPath === 'tree-generator')).toBeDefined() + }) + + it('should include generate-skill', () => { + expect(metaSkills.find((s) => s.relPath === 'generate-skill')).toBeDefined() + }) + + it('should include skill-staleness-check', () => { + expect( + metaSkills.find((s) => s.relPath === 'skill-staleness-check'), + ).toBeDefined() + }) +}) + +describe('meta-skill frontmatter', () => { + for (const skill of metaSkills) { + describe(skill.relPath, () => { + it('should have valid frontmatter', () => { + expect(skill.parsed).not.toBeNull() + }) + + if (!skill.parsed) return + + const { frontmatter } = skill.parsed + + it('should have a name', () => { + expect(frontmatter.name).toBeTruthy() + }) + + it('should have a description', () => { + expect(frontmatter.description).toBeTruthy() + }) + }) + } +}) + +describe('meta-skill content', () => { + for (const skill of metaSkills) { + describe(skill.relPath, () => { + it(`should not exceed ${MAX_META_SKILL_LINES} lines`, () => { + const lineCount = skill.content.split(/\r?\n/).length + expect(lineCount).toBeLessThanOrEqual(MAX_META_SKILL_LINES) + }) + }) + } +}) diff --git a/packages/intent/tests/staleness.test.ts b/packages/intent/tests/staleness.test.ts index 32d37488..646c293d 100644 --- a/packages/intent/tests/staleness.test.ts +++ b/packages/intent/tests/staleness.test.ts @@ -1,286 +1,286 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs' -import { join } from 'node:path' -import { tmpdir } from 'node:os' -import { checkStaleness } from '../src/staleness.js' - -// --------------------------------------------------------------------------- -// Fixture helpers -// --------------------------------------------------------------------------- - -let tmpDir: string - -function setupDir(): string { - const dir = join( - tmpdir(), - `intent-stale-test-${Date.now()}-${Math.random().toString(36).slice(2)}`, - ) - mkdirSync(dir, { recursive: true }) - return dir -} - -function writeSkill( - dir: string, - name: string, - fm: Record, - body = '# Skill\n', -): void { - const skillDir = join(dir, 'skills', ...name.split('/')) - mkdirSync(skillDir, { recursive: true }) - - const fmStr = Object.entries(fm) - .map(([k, v]) => { - if (Array.isArray(v)) { - return `${k}:\n${v.map((i) => ` - ${i}`).join('\n')}` - } - return `${k}: ${v}` - }) - .join('\n') - - writeFileSync(join(skillDir, 'SKILL.md'), `---\n${fmStr}\n---\n${body}`) -} - -function writeSyncState(dir: string, state: Record): void { - const skillsDir = join(dir, 'skills') - mkdirSync(skillsDir, { recursive: true }) - writeFileSync(join(skillsDir, 'sync-state.json'), JSON.stringify(state)) -} - -// --------------------------------------------------------------------------- -// Mock fetch for npm registry -// --------------------------------------------------------------------------- - -const originalFetch = globalThis.fetch - -beforeEach(() => { - tmpDir = setupDir() -}) - -afterEach(() => { - globalThis.fetch = originalFetch - if (existsSync(tmpDir)) { - rmSync(tmpDir, { recursive: true, force: true }) - } -}) - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -describe('checkStaleness', () => { - it('returns empty skills when no skills directory exists', async () => { - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.library).toBe('@example/lib') - expect(report.skills).toHaveLength(0) - expect(report.currentVersion).toBeNull() - expect(report.skillVersion).toBeNull() - expect(report.versionDrift).toBeNull() - }) - - it('defaults library to "unknown" when no name provided', async () => { - const report = await checkStaleness(tmpDir) - expect(report.library).toBe('unknown') - }) - - it('detects skills from SKILL.md files', async () => { - writeSkill(tmpDir, 'basics', { - name: 'basics', - description: 'Core concepts', - }) - writeSkill(tmpDir, 'advanced', { - name: 'advanced', - description: 'Advanced usage', - }) - - globalThis.fetch = vi.fn().mockResolvedValue({ ok: false } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.skills).toHaveLength(2) - expect(report.skills.map((s) => s.name).sort()).toEqual([ - 'advanced', - 'basics', - ]) - }) - - it('detects major version drift', async () => { - writeSkill(tmpDir, 'core', { - name: 'core', - description: 'Core', - library_version: '1.2.3', - }) - - globalThis.fetch = vi.fn().mockResolvedValue({ - ok: true, - json: async () => ({ version: '2.0.0' }), - } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.skillVersion).toBe('1.2.3') - expect(report.currentVersion).toBe('2.0.0') - expect(report.versionDrift).toBe('major') - expect(report.skills[0].needsReview).toBe(true) - expect(report.skills[0].reasons[0]).toContain('version drift') - }) - - it('detects minor version drift', async () => { - writeSkill(tmpDir, 'core', { - name: 'core', - description: 'Core', - library_version: '1.2.3', - }) - - globalThis.fetch = vi.fn().mockResolvedValue({ - ok: true, - json: async () => ({ version: '1.4.0' }), - } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.versionDrift).toBe('minor') - }) - - it('detects patch version drift', async () => { - writeSkill(tmpDir, 'core', { - name: 'core', - description: 'Core', - library_version: '1.2.3', - }) - - globalThis.fetch = vi.fn().mockResolvedValue({ - ok: true, - json: async () => ({ version: '1.2.5' }), - } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.versionDrift).toBe('patch') - }) - - it('reports no drift when versions match', async () => { - writeSkill(tmpDir, 'core', { - name: 'core', - description: 'Core', - library_version: '1.2.3', - }) - - globalThis.fetch = vi.fn().mockResolvedValue({ - ok: true, - json: async () => ({ version: '1.2.3' }), - } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.versionDrift).toBeNull() - expect(report.skills[0].needsReview).toBe(false) - }) - - it('handles npm fetch failure gracefully', async () => { - writeSkill(tmpDir, 'core', { - name: 'core', - description: 'Core', - library_version: '1.0.0', - }) - - globalThis.fetch = vi.fn().mockRejectedValue(new Error('Network error')) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.currentVersion).toBeNull() - expect(report.versionDrift).toBeNull() - }) - - it('flags new sources not present in sync-state', async () => { - writeSkill(tmpDir, 'core', { - name: 'core', - description: 'Core', - sources: ['docs/api.md', 'docs/guide.md'], - }) - - writeSyncState(tmpDir, { - skills: { - core: { - sources_sha: { - 'docs/api.md': 'abc123', - // docs/guide.md intentionally missing - }, - }, - }, - }) - - globalThis.fetch = vi.fn().mockResolvedValue({ ok: false } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.skills[0].needsReview).toBe(true) - expect(report.skills[0].reasons).toEqual( - expect.arrayContaining([expect.stringContaining('new source')]), - ) - }) - - it('does not flag sources when no sync-state exists', async () => { - writeSkill(tmpDir, 'core', { - name: 'core', - description: 'Core', - sources: ['docs/api.md'], - }) - - globalThis.fetch = vi.fn().mockResolvedValue({ ok: false } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.skills[0].needsReview).toBe(false) - }) - - it('handles nested skill directories', async () => { - writeSkill(tmpDir, 'react/hooks', { - name: 'react/hooks', - description: 'React hooks', - library_version: '1.0.0', - }) - - globalThis.fetch = vi.fn().mockResolvedValue({ - ok: true, - json: async () => ({ version: '2.0.0' }), - } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.skills).toHaveLength(1) - expect(report.skills[0].name).toBe('react/hooks') - expect(report.skills[0].needsReview).toBe(true) - }) - - it('uses directory name when frontmatter has no name', async () => { - writeSkill(tmpDir, 'my-skill', { - description: 'A skill with no name field', - }) - - globalThis.fetch = vi.fn().mockResolvedValue({ ok: false } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.skills[0].name).toBe('my-skill') - }) - - it('uses skillVersion from first skill that has library_version', async () => { - writeSkill(tmpDir, 'a', { name: 'a', description: 'No version' }) - writeSkill(tmpDir, 'b', { - name: 'b', - description: 'Has version', - library_version: '3.5.0', - }) - - globalThis.fetch = vi.fn().mockResolvedValue({ - ok: true, - json: async () => ({ version: '4.0.0' }), - } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.skillVersion).toBe('3.5.0') - expect(report.versionDrift).toBe('major') - }) - - it('handles malformed SKILL.md without crashing', async () => { - const skillDir = join(tmpDir, 'skills', 'broken') - mkdirSync(skillDir, { recursive: true }) - writeFileSync(join(skillDir, 'SKILL.md'), 'no frontmatter here') - - globalThis.fetch = vi.fn().mockResolvedValue({ ok: false } as Response) - - const report = await checkStaleness(tmpDir, '@example/lib') - expect(report.skills).toHaveLength(1) - expect(report.skills[0].needsReview).toBe(false) - }) -}) +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs' +import { join } from 'node:path' +import { tmpdir } from 'node:os' +import { checkStaleness } from '../src/staleness.js' + +// --------------------------------------------------------------------------- +// Fixture helpers +// --------------------------------------------------------------------------- + +let tmpDir: string + +function setupDir(): string { + const dir = join( + tmpdir(), + `intent-stale-test-${Date.now()}-${Math.random().toString(36).slice(2)}`, + ) + mkdirSync(dir, { recursive: true }) + return dir +} + +function writeSkill( + dir: string, + name: string, + fm: Record, + body = '# Skill\n', +): void { + const skillDir = join(dir, 'skills', ...name.split('/')) + mkdirSync(skillDir, { recursive: true }) + + const fmStr = Object.entries(fm) + .map(([k, v]) => { + if (Array.isArray(v)) { + return `${k}:\n${v.map((i) => ` - ${i}`).join('\n')}` + } + return `${k}: ${v}` + }) + .join('\n') + + writeFileSync(join(skillDir, 'SKILL.md'), `---\n${fmStr}\n---\n${body}`) +} + +function writeSyncState(dir: string, state: Record): void { + const skillsDir = join(dir, 'skills') + mkdirSync(skillsDir, { recursive: true }) + writeFileSync(join(skillsDir, 'sync-state.json'), JSON.stringify(state)) +} + +// --------------------------------------------------------------------------- +// Mock fetch for npm registry +// --------------------------------------------------------------------------- + +const originalFetch = globalThis.fetch + +beforeEach(() => { + tmpDir = setupDir() +}) + +afterEach(() => { + globalThis.fetch = originalFetch + if (existsSync(tmpDir)) { + rmSync(tmpDir, { recursive: true, force: true }) + } +}) + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +describe('checkStaleness', () => { + it('returns empty skills when no skills directory exists', async () => { + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.library).toBe('@example/lib') + expect(report.skills).toHaveLength(0) + expect(report.currentVersion).toBeNull() + expect(report.skillVersion).toBeNull() + expect(report.versionDrift).toBeNull() + }) + + it('defaults library to "unknown" when no name provided', async () => { + const report = await checkStaleness(tmpDir) + expect(report.library).toBe('unknown') + }) + + it('detects skills from SKILL.md files', async () => { + writeSkill(tmpDir, 'basics', { + name: 'basics', + description: 'Core concepts', + }) + writeSkill(tmpDir, 'advanced', { + name: 'advanced', + description: 'Advanced usage', + }) + + globalThis.fetch = vi.fn().mockResolvedValue({ ok: false } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.skills).toHaveLength(2) + expect(report.skills.map((s) => s.name).sort()).toEqual([ + 'advanced', + 'basics', + ]) + }) + + it('detects major version drift', async () => { + writeSkill(tmpDir, 'core', { + name: 'core', + description: 'Core', + library_version: '1.2.3', + }) + + globalThis.fetch = vi.fn().mockResolvedValue({ + ok: true, + json: async () => ({ version: '2.0.0' }), + } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.skillVersion).toBe('1.2.3') + expect(report.currentVersion).toBe('2.0.0') + expect(report.versionDrift).toBe('major') + expect(report.skills[0].needsReview).toBe(true) + expect(report.skills[0].reasons[0]).toContain('version drift') + }) + + it('detects minor version drift', async () => { + writeSkill(tmpDir, 'core', { + name: 'core', + description: 'Core', + library_version: '1.2.3', + }) + + globalThis.fetch = vi.fn().mockResolvedValue({ + ok: true, + json: async () => ({ version: '1.4.0' }), + } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.versionDrift).toBe('minor') + }) + + it('detects patch version drift', async () => { + writeSkill(tmpDir, 'core', { + name: 'core', + description: 'Core', + library_version: '1.2.3', + }) + + globalThis.fetch = vi.fn().mockResolvedValue({ + ok: true, + json: async () => ({ version: '1.2.5' }), + } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.versionDrift).toBe('patch') + }) + + it('reports no drift when versions match', async () => { + writeSkill(tmpDir, 'core', { + name: 'core', + description: 'Core', + library_version: '1.2.3', + }) + + globalThis.fetch = vi.fn().mockResolvedValue({ + ok: true, + json: async () => ({ version: '1.2.3' }), + } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.versionDrift).toBeNull() + expect(report.skills[0].needsReview).toBe(false) + }) + + it('handles npm fetch failure gracefully', async () => { + writeSkill(tmpDir, 'core', { + name: 'core', + description: 'Core', + library_version: '1.0.0', + }) + + globalThis.fetch = vi.fn().mockRejectedValue(new Error('Network error')) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.currentVersion).toBeNull() + expect(report.versionDrift).toBeNull() + }) + + it('flags new sources not present in sync-state', async () => { + writeSkill(tmpDir, 'core', { + name: 'core', + description: 'Core', + sources: ['docs/api.md', 'docs/guide.md'], + }) + + writeSyncState(tmpDir, { + skills: { + core: { + sources_sha: { + 'docs/api.md': 'abc123', + // docs/guide.md intentionally missing + }, + }, + }, + }) + + globalThis.fetch = vi.fn().mockResolvedValue({ ok: false } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.skills[0].needsReview).toBe(true) + expect(report.skills[0].reasons).toEqual( + expect.arrayContaining([expect.stringContaining('new source')]), + ) + }) + + it('does not flag sources when no sync-state exists', async () => { + writeSkill(tmpDir, 'core', { + name: 'core', + description: 'Core', + sources: ['docs/api.md'], + }) + + globalThis.fetch = vi.fn().mockResolvedValue({ ok: false } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.skills[0].needsReview).toBe(false) + }) + + it('handles nested skill directories', async () => { + writeSkill(tmpDir, 'react/hooks', { + name: 'react/hooks', + description: 'React hooks', + library_version: '1.0.0', + }) + + globalThis.fetch = vi.fn().mockResolvedValue({ + ok: true, + json: async () => ({ version: '2.0.0' }), + } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.skills).toHaveLength(1) + expect(report.skills[0].name).toBe('react/hooks') + expect(report.skills[0].needsReview).toBe(true) + }) + + it('uses directory name when frontmatter has no name', async () => { + writeSkill(tmpDir, 'my-skill', { + description: 'A skill with no name field', + }) + + globalThis.fetch = vi.fn().mockResolvedValue({ ok: false } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.skills[0].name).toBe('my-skill') + }) + + it('uses skillVersion from first skill that has library_version', async () => { + writeSkill(tmpDir, 'a', { name: 'a', description: 'No version' }) + writeSkill(tmpDir, 'b', { + name: 'b', + description: 'Has version', + library_version: '3.5.0', + }) + + globalThis.fetch = vi.fn().mockResolvedValue({ + ok: true, + json: async () => ({ version: '4.0.0' }), + } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.skillVersion).toBe('3.5.0') + expect(report.versionDrift).toBe('major') + }) + + it('handles malformed SKILL.md without crashing', async () => { + const skillDir = join(tmpDir, 'skills', 'broken') + mkdirSync(skillDir, { recursive: true }) + writeFileSync(join(skillDir, 'SKILL.md'), 'no frontmatter here') + + globalThis.fetch = vi.fn().mockResolvedValue({ ok: false } as Response) + + const report = await checkStaleness(tmpDir, '@example/lib') + expect(report.skills).toHaveLength(1) + expect(report.skills[0].needsReview).toBe(false) + }) +}) diff --git a/packages/intent/tsconfig.json b/packages/intent/tsconfig.json index 7ed40a9d..2696e251 100644 --- a/packages/intent/tsconfig.json +++ b/packages/intent/tsconfig.json @@ -1,9 +1,9 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "dist", - "noEmit": false, - "declaration": true - }, - "include": ["src"] -} +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "noEmit": false, + "declaration": true + }, + "include": ["src"] +} diff --git a/packages/intent/vitest.config.ts b/packages/intent/vitest.config.ts index d38b74e7..052d46bc 100644 --- a/packages/intent/vitest.config.ts +++ b/packages/intent/vitest.config.ts @@ -1,8 +1,8 @@ -import { defineConfig } from 'vitest/config' - -export default defineConfig({ - test: { - name: 'intent', - include: ['tests/**/*.test.ts'], - }, -}) +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + name: 'intent', + include: ['tests/**/*.test.ts'], + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5aa7ba8c..50fdd4d8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5381 +1,5381 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@tanstack/typedoc-config': - specifier: ^0.3.3 - version: 0.3.3(typescript@5.9.3) - devDependencies: - '@changesets/cli': - specifier: ^2.29.8 - version: 2.29.8(@types/node@25.0.9) - '@faker-js/faker': - specifier: ^10.2.0 - version: 10.2.0 - '@svitejs/changesets-changelog-github-compact': - specifier: ^1.2.0 - version: 1.2.0 - '@tanstack/eslint-config': - specifier: 0.3.4 - version: 0.3.4(@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@types/node': - specifier: ^25.0.7 - version: 25.0.9 - eslint: - specifier: ^9.39.2 - version: 9.39.2(jiti@2.6.1) - eslint-plugin-unused-imports: - specifier: ^4.3.0 - version: 4.3.0(@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) - happy-dom: - specifier: ^20.1.0 - version: 20.3.1 - knip: - specifier: ^5.80.2 - version: 5.81.0(@types/node@25.0.9)(typescript@5.9.3) - markdown-link-extractor: - specifier: ^4.0.3 - version: 4.0.3 - nx: - specifier: ^22.3.3 - version: 22.3.3 - prettier: - specifier: ^3.7.4 - version: 3.8.0 - prettier-plugin-svelte: - specifier: ^3.4.1 - version: 3.4.1(prettier@3.8.0)(svelte@5.46.4) - sherif: - specifier: ^1.9.0 - version: 1.10.0 - tinyglobby: - specifier: ^0.2.15 - version: 0.2.15 - typescript: - specifier: 5.9.3 - version: 5.9.3 - vitest: - specifier: ^4.0.17 - version: 4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(yaml@2.8.2) - yaml: - specifier: ^2.7.0 - version: 2.8.2 - - packages/intent: - dependencies: - yaml: - specifier: ^2.7.0 - version: 2.8.2 - devDependencies: - tsdown: - specifier: ^0.19.0 - version: 0.19.0(oxc-resolver@11.16.3)(typescript@5.9.3) - -packages: - - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.0': - resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/runtime@7.28.6': - resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} - - '@changesets/apply-release-plan@7.0.14': - resolution: {integrity: sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==} - - '@changesets/assemble-release-plan@6.0.9': - resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} - - '@changesets/changelog-git@0.2.1': - resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} - - '@changesets/cli@2.29.8': - resolution: {integrity: sha512-1weuGZpP63YWUYjay/E84qqwcnt5yJMM0tep10Up7Q5cS/DGe2IZ0Uj3HNMxGhCINZuR7aO9WBMdKnPit5ZDPA==} - hasBin: true - - '@changesets/config@3.1.2': - resolution: {integrity: sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==} - - '@changesets/errors@0.2.0': - resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} - - '@changesets/get-dependents-graph@2.1.3': - resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} - - '@changesets/get-github-info@0.6.0': - resolution: {integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==} - - '@changesets/get-release-plan@4.0.14': - resolution: {integrity: sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==} - - '@changesets/get-version-range-type@0.4.0': - resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} - - '@changesets/git@3.0.4': - resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} - - '@changesets/logger@0.1.1': - resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} - - '@changesets/parse@0.4.2': - resolution: {integrity: sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==} - - '@changesets/pre@2.0.2': - resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} - - '@changesets/read@0.6.6': - resolution: {integrity: sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==} - - '@changesets/should-skip-package@0.1.2': - resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} - - '@changesets/types@4.1.0': - resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} - - '@changesets/types@6.1.0': - resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} - - '@changesets/write@0.4.0': - resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} - - '@emnapi/core@1.8.1': - resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} - - '@emnapi/runtime@1.8.1': - resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - - '@emnapi/wasi-threads@1.1.0': - resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - - '@esbuild/aix-ppc64@0.27.2': - resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.27.2': - resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.27.2': - resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.27.2': - resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.27.2': - resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.27.2': - resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.27.2': - resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.27.2': - resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.27.2': - resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.27.2': - resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.27.2': - resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.27.2': - resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.27.2': - resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.27.2': - resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.27.2': - resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.27.2': - resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.27.2': - resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.27.2': - resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.27.2': - resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.27.2': - resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.27.2': - resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.27.2': - resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.27.2': - resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.27.2': - resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.27.2': - resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.27.2': - resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.21.1': - resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.4.2': - resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.17.0': - resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.3': - resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.39.2': - resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.7': - resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.4.1': - resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@faker-js/faker@10.2.0': - resolution: {integrity: sha512-rTXwAsIxpCqzUnZvrxVh3L0QA0NzToqWBLAhV+zDV3MIIwiQhAZHMdPCIaj5n/yADu/tyk12wIPgL6YHGXJP+g==} - engines: {node: ^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0, npm: '>=10'} - - '@gerrit0/mini-shiki@3.23.0': - resolution: {integrity: sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==} - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@inquirer/external-editor@1.0.3': - resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - - '@jest/diff-sequences@30.0.1': - resolution: {integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/get-type@30.1.0': - resolution: {integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/schemas@30.0.5': - resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@manypkg/find-root@1.1.0': - resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} - - '@manypkg/get-packages@1.1.3': - resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - - '@napi-rs/wasm-runtime@0.2.4': - resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} - - '@napi-rs/wasm-runtime@1.1.1': - resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@nx/nx-darwin-arm64@22.3.3': - resolution: {integrity: sha512-zBAGFGLal09CxhQkdMpOVwcwa9Y01aFm88jTTn35s/DdIWsfngmPzz0t4mG7u2D05q7TJfGQ31pIf5GkNUjo6g==} - cpu: [arm64] - os: [darwin] - - '@nx/nx-darwin-x64@22.3.3': - resolution: {integrity: sha512-6ZQ6rMqH8NY4Jz+Gc89D5bIH2NxZb5S/vaA4yJ9RrqAfl4QWchNFD5na+aRivSd+UdsYLPKKl6qohet5SE6vOg==} - cpu: [x64] - os: [darwin] - - '@nx/nx-freebsd-x64@22.3.3': - resolution: {integrity: sha512-J/PP5pIOQtR7ZzrFwP6d6h0yfY7r9EravG2m940GsgzGbtZGYIDqnh5Wdt+4uBWPH8VpdNOwFqH0afELtJA3MA==} - cpu: [x64] - os: [freebsd] - - '@nx/nx-linux-arm-gnueabihf@22.3.3': - resolution: {integrity: sha512-/zn0altzM15S7qAgXMaB41vHkEn18HyTVUvRrjmmwaVqk9WfmDmqOQlGWoJ6XCbpvKQ8bh14RyhR9LGw1JJkNA==} - cpu: [arm] - os: [linux] - - '@nx/nx-linux-arm64-gnu@22.3.3': - resolution: {integrity: sha512-NmPeCexWIZHW9RM3lDdFENN9C3WtlQ5L4RSNFESIjreS921rgePhulsszYdGnHdcnKPYlBBJnX/NxVsfioBbnQ==} - cpu: [arm64] - os: [linux] - - '@nx/nx-linux-arm64-musl@22.3.3': - resolution: {integrity: sha512-K02U88Q0dpvCfmSXXvY7KbYQSa1m+mkYeqDBRHp11yHk1GoIqaHp8oEWda7FV4gsriNExPSS5tX1/QGVoLZrCw==} - cpu: [arm64] - os: [linux] - - '@nx/nx-linux-x64-gnu@22.3.3': - resolution: {integrity: sha512-04TEbvgwRaB9ifr39YwJmWh3RuXb4Ry4m84SOJyjNXAfPrepcWgfIQn1VL2ul1Ybq+P023dLO9ME8uqFh6j1YQ==} - cpu: [x64] - os: [linux] - - '@nx/nx-linux-x64-musl@22.3.3': - resolution: {integrity: sha512-uxBXx5q+S5OGatbYDxnamsKXRKlYn+Eq1nrCAHaf8rIfRoHlDiRV2PqtWuF+O2pxR5FWKpvr+/sZtt9rAf7KMw==} - cpu: [x64] - os: [linux] - - '@nx/nx-win32-arm64-msvc@22.3.3': - resolution: {integrity: sha512-aOwlfD6ZA1K6hjZtbhBSp7s1yi3sHbMpLCa4stXzfhCCpKUv46HU/EdiWdE1N8AsyNFemPZFq81k1VTowcACdg==} - cpu: [arm64] - os: [win32] - - '@nx/nx-win32-x64-msvc@22.3.3': - resolution: {integrity: sha512-EDR8BtqeDvVNQ+kPwnfeSfmerYetitU3tDkxOMIybjKJDh69U2JwTB8n9ARwNaZQbNk7sCGNRUSZFTbAAUKvuQ==} - cpu: [x64] - os: [win32] - - '@oxc-project/types@0.107.0': - resolution: {integrity: sha512-QFDRbYfV2LVx8tyqtyiah3jQPUj1mK2+RYwxyFWyGoys6XJnwTdlzO6rdNNHOPorHAu5Uo34oWRKcvNpbJarmQ==} - - '@oxc-project/types@0.112.0': - resolution: {integrity: sha512-m6RebKHIRsax2iCwVpYW2ErQwa4ywHJrE4sCK3/8JK8ZZAWOKXaRJFl/uP51gaVyyXlaS4+chU1nSCdzYf6QqQ==} - - '@oxc-resolver/binding-android-arm-eabi@11.16.3': - resolution: {integrity: sha512-CVyWHu6ACDqDcJxR4nmGiG8vDF4TISJHqRNzac5z/gPQycs/QrP/1pDsJBy0MD7jSw8nVq2E5WqeHQKabBG/Jg==} - cpu: [arm] - os: [android] - - '@oxc-resolver/binding-android-arm64@11.16.3': - resolution: {integrity: sha512-tTIoB7plLeh2o6Ay7NnV5CJb6QUXdxI7Shnsp2ECrLSV81k+oVE3WXYrQSh4ltWL75i0OgU5Bj3bsuyg5SMepw==} - cpu: [arm64] - os: [android] - - '@oxc-resolver/binding-darwin-arm64@11.16.3': - resolution: {integrity: sha512-OXKVH7uwYd3Rbw1s2yJZd6/w+6b01iaokZubYhDAq4tOYArr+YCS+lr81q1hsTPPRZeIsWE+rJLulmf1qHdYZA==} - cpu: [arm64] - os: [darwin] - - '@oxc-resolver/binding-darwin-x64@11.16.3': - resolution: {integrity: sha512-WwjQ4WdnCxVYZYd3e3oY5XbV3JeLy9pPMK+eQQ2m8DtqUtbxnvPpAYC2Knv/2bS6q5JiktqOVJ2Hfia3OSo0/A==} - cpu: [x64] - os: [darwin] - - '@oxc-resolver/binding-freebsd-x64@11.16.3': - resolution: {integrity: sha512-4OHKFGJBBfOnuJnelbCS4eBorI6cj54FUxcZJwEXPeoLc8yzORBoJ2w+fQbwjlQcUUZLEg92uGhKCRiUoqznjg==} - cpu: [x64] - os: [freebsd] - - '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.3': - resolution: {integrity: sha512-OM3W0NLt9u7uKwG/yZbeXABansZC0oZeDF1nKgvcZoRw4/Yak6/l4S0onBfDFeYMY94eYeAt2bl60e30lgsb5A==} - cpu: [arm] - os: [linux] - - '@oxc-resolver/binding-linux-arm-musleabihf@11.16.3': - resolution: {integrity: sha512-MRs7D7i1t7ACsAdTuP81gLZES918EpBmiUyEl8fu302yQB+4L7L7z0Ui8BWnthUTQd3nAU9dXvENLK/SqRVH8A==} - cpu: [arm] - os: [linux] - - '@oxc-resolver/binding-linux-arm64-gnu@11.16.3': - resolution: {integrity: sha512-0eVYZxSceNqGADzhlV4ZRqkHF0fjWxRXQOB7Qwl5y1gN/XYUDvMfip+ngtzj4dM7zQT4U97hUhJ7PUKSy/JIGQ==} - cpu: [arm64] - os: [linux] - - '@oxc-resolver/binding-linux-arm64-musl@11.16.3': - resolution: {integrity: sha512-B1BvLeZbgDdVN0FvU40l5Q7lej8310WlabCBaouk8jY7H7xbI8phtomTtk3Efmevgfy5hImaQJu6++OmcFb2NQ==} - cpu: [arm64] - os: [linux] - - '@oxc-resolver/binding-linux-ppc64-gnu@11.16.3': - resolution: {integrity: sha512-q7khglic3Jqak7uDgA3MFnjDeI7krQT595GDZpvFq785fmFYSx8rlTkoHzmhQtUisYtl4XG7WUscwsoidFUI4w==} - cpu: [ppc64] - os: [linux] - - '@oxc-resolver/binding-linux-riscv64-gnu@11.16.3': - resolution: {integrity: sha512-aFRNmQNPzDgQEbw2s3c8yJYRimacSDI+u9df8rn5nSKzTVitHmbEpZqfxpwNLCKIuLSNmozHR1z1OT+oZVeYqg==} - cpu: [riscv64] - os: [linux] - - '@oxc-resolver/binding-linux-riscv64-musl@11.16.3': - resolution: {integrity: sha512-vZI85SvSMADcEL9G1TIrV0Rlkc1fY5Mup0DdlVC5EHPysZB4hXXHpr+h09pjlK5y+5om5foIzDRxE1baUCaWOA==} - cpu: [riscv64] - os: [linux] - - '@oxc-resolver/binding-linux-s390x-gnu@11.16.3': - resolution: {integrity: sha512-xiLBnaUlddFEzRHiHiSGEMbkg8EwZY6VD8F+3GfnFsiK3xg/4boaUV2bwXd+nUzl3UDQOMW1QcZJ4jJSb0qiJA==} - cpu: [s390x] - os: [linux] - - '@oxc-resolver/binding-linux-x64-gnu@11.16.3': - resolution: {integrity: sha512-6y0b05wIazJJgwu7yU/AYGFswzQQudYJBOb/otDhiDacp1+6ye8egoxx63iVo9lSpDbipL++54AJQFlcOHCB+g==} - cpu: [x64] - os: [linux] - - '@oxc-resolver/binding-linux-x64-musl@11.16.3': - resolution: {integrity: sha512-RmMgwuMa42c9logS7Pjprf5KCp8J1a1bFiuBFtG9/+yMu0BhY2t+0VR/um7pwtkNFvIQqAVh6gDOg/PnoKRcdQ==} - cpu: [x64] - os: [linux] - - '@oxc-resolver/binding-openharmony-arm64@11.16.3': - resolution: {integrity: sha512-/7AYRkjjW7xu1nrHgWUFy99Duj4/ydOBVaHtODie9/M6fFngo+8uQDFFnzmr4q//sd/cchIerISp/8CQ5TsqIA==} - cpu: [arm64] - os: [openharmony] - - '@oxc-resolver/binding-wasm32-wasi@11.16.3': - resolution: {integrity: sha512-urM6aIPbi5di4BSlnpd/TWtDJgG6RD06HvLBuNM+qOYuFtY1/xPbzQ2LanBI2ycpqIoIZwsChyplALwAMdyfCQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@oxc-resolver/binding-win32-arm64-msvc@11.16.3': - resolution: {integrity: sha512-QuvLqGKf7frxWHQ5TnrcY0C/hJpANsaez99Q4dAk1hen7lDTD4FBPtBzPnntLFXeaVG3PnSmnVjlv0vMILwU7Q==} - cpu: [arm64] - os: [win32] - - '@oxc-resolver/binding-win32-ia32-msvc@11.16.3': - resolution: {integrity: sha512-QR/witXK6BmYTlEP8CCjC5fxeG5U9A6a50pNpC1nLnhAcJjtzFG8KcQ5etVy/XvCLiDc7fReaAWRNWtCaIhM8Q==} - cpu: [ia32] - os: [win32] - - '@oxc-resolver/binding-win32-x64-msvc@11.16.3': - resolution: {integrity: sha512-bFuJRKOscsDAEZ/a8BezcTMAe2BQ/OBRfuMLFUuINfTR5qGVcm4a3xBIrQVepBaPxFj16SJdRjGe05vDiwZmFw==} - cpu: [x64] - os: [win32] - - '@quansync/fs@1.0.0': - resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} - - '@rolldown/binding-android-arm64@1.0.0-beta.59': - resolution: {integrity: sha512-6yLLgyswYwiCfls9+hoNFY9F8TQdwo15hpXDHzlAR0X/GojeKF+AuNcXjYNbOJ4zjl/5D6lliE8CbpB5t1OWIQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-android-arm64@1.0.0-rc.3': - resolution: {integrity: sha512-0T1k9FinuBZ/t7rZ8jN6OpUKPnUjNdYHoj/cESWrQ3ZraAJ4OMm6z7QjSfCxqj8mOp9kTKc1zHK3kGz5vMu+nQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.0.0-beta.59': - resolution: {integrity: sha512-hqGXRc162qCCIOAcHN2Cw4eXiVTwYsMFLOhAy1IG2CxY+dwc/l4Ga+dLPkLor3Ikqy5WDn+7kxHbbh6EmshEpQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-arm64@1.0.0-rc.3': - resolution: {integrity: sha512-JWWLzvcmc/3pe7qdJqPpuPk91SoE/N+f3PcWx/6ZwuyDVyungAEJPvKm/eEldiDdwTmaEzWfIR+HORxYWrCi1A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.0.0-beta.59': - resolution: {integrity: sha512-ezvvGuhteE15JmMhJW0wS7BaXmhwLy1YHeEwievYaPC1PgGD86wgBKfOpHr9tSKllAXbCe0BeeMvasscWLhKdA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.0.0-rc.3': - resolution: {integrity: sha512-MTakBxfx3tde5WSmbHxuqlDsIW0EzQym+PJYGF4P6lG2NmKzi128OGynoFUqoD5ryCySEY85dug4v+LWGBElIw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.0.0-beta.59': - resolution: {integrity: sha512-4fhKVJiEYVd5n6no/mrL3LZ9kByfCGwmONOrdtvx8DJGDQhehH/q3RfhG3V/4jGKhpXgbDjpIjkkFdybCTcgew==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-freebsd-x64@1.0.0-rc.3': - resolution: {integrity: sha512-jje3oopyOLs7IwfvXoS6Lxnmie5JJO7vW29fdGFu5YGY1EDbVDhD+P9vDihqS5X6fFiqL3ZQZCMBg6jyHkSVww==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.59': - resolution: {integrity: sha512-T3Y52sW6JAhvIqArBw+wtjNU1Ieaz4g0NBxyjSJoW971nZJBZygNlSYx78G4cwkCmo1dYTciTPDOnQygLV23pA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3': - resolution: {integrity: sha512-A0n8P3hdLAaqzSFrQoA42p23ZKBYQOw+8EH5r15Sa9X1kD9/JXe0YT2gph2QTWvdr0CVK2BOXiK6ENfy6DXOag==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.59': - resolution: {integrity: sha512-NIW40jQDSQap2KDdmm9z3B/4OzWJ6trf8dwx3FD74kcQb3v34ThsBFTtzE5KjDuxnxgUlV+DkAu+XgSMKrgufw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3': - resolution: {integrity: sha512-kWXkoxxarYISBJ4bLNf5vFkEbb4JvccOwxWDxuK9yee8lg5XA7OpvlTptfRuwEvYcOZf+7VS69Uenpmpyo5Bjw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.59': - resolution: {integrity: sha512-CCKEk+H+8c0WGe/8n1E20n85Tq4Pv+HNAbjP1KfUXW+01aCWSMjU56ChNrM2tvHnXicfm7QRNoZyfY8cWh7jLQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.3': - resolution: {integrity: sha512-Z03/wrqau9Bicfgb3Dbs6SYTHliELk2PM2LpG2nFd+cGupTMF5kanLEcj2vuuJLLhptNyS61rtk7SOZ+lPsTUA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.59': - resolution: {integrity: sha512-VlfwJ/HCskPmQi8R0JuAFndySKVFX7yPhE658o27cjSDWWbXVtGkSbwaxstii7Q+3Rz87ZXN+HLnb1kd4R9Img==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.3': - resolution: {integrity: sha512-iSXXZsQp08CSilff/DCTFZHSVEpEwdicV3W8idHyrByrcsRDVh9sGC3sev6d8BygSGj3vt8GvUKBPCoyMA4tgQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@rolldown/binding-linux-x64-musl@1.0.0-beta.59': - resolution: {integrity: sha512-kuO92hTRyGy0Ts3Nsqll0rfO8eFsEJe9dGQGktkQnZ2hrJrDVN0y419dMgKy/gB2S2o7F2dpWhpfQOBehZPwVA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@rolldown/binding-linux-x64-musl@1.0.0-rc.3': - resolution: {integrity: sha512-qaj+MFudtdCv9xZo9znFvkgoajLdc+vwf0Kz5N44g+LU5XMe+IsACgn3UG7uTRlCCvhMAGXm1XlpEA5bZBrOcw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@rolldown/binding-openharmony-arm64@1.0.0-beta.59': - resolution: {integrity: sha512-PXAebvNL4sYfCqi8LdY4qyFRacrRoiPZLo3NoUmiTxm7MPtYYR8CNtBGNokqDmMuZIQIecRaD/jbmFAIDz7DxQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.3': - resolution: {integrity: sha512-U662UnMETyjT65gFmG9ma+XziENrs7BBnENi/27swZPYagubfHRirXHG2oMl+pEax2WvO7Kb9gHZmMakpYqBHQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.0.0-beta.59': - resolution: {integrity: sha512-yJoklQg7XIZq8nAg0bbkEXcDK6sfpjxQGxpg2Nd6ERNtvg+eOaEBRgPww0BVTrYFQzje1pB5qPwC2VnJHT3koQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@rolldown/binding-wasm32-wasi@1.0.0-rc.3': - resolution: {integrity: sha512-gekrQ3Q2HiC1T5njGyuUJoGpK/l6B/TNXKed3fZXNf9YRTJn3L5MOZsFBn4bN2+UX+8+7hgdlTcEsexX988G4g==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.59': - resolution: {integrity: sha512-ljZ4+McmCbIuZwEBaoGtiG8Rq2nJjaXEnLEIx+usWetXn1ECjXY0LAhkELxOV6ytv4ensEmoJJ8nXg47hRMjlw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3': - resolution: {integrity: sha512-85y5JifyMgs8m5K2XzR/VDsapKbiFiohl7s5lEj7nmNGO0pkTXE7q6TQScei96BNAsoK7JC3pA7ukA8WRHVJpg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.59': - resolution: {integrity: sha512-bMY4tTIwbdZljW+xe/ln1hvs0SRitahQSXfWtvgAtIzgSX9Ar7KqJzU7lRm33YTRFIHLULRi53yNjw9nJGd6uQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.3': - resolution: {integrity: sha512-a4VUQZH7LxGbUJ3qJ/TzQG8HxdHvf+jOnqf7B7oFx1TEBm+j2KNL2zr5SQ7wHkNAcaPevF6gf9tQnVBnC4mD+A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.0-beta.59': - resolution: {integrity: sha512-aoh6LAJRyhtazs98ydgpNOYstxUlsOV1KJXcpf/0c0vFcUA8uyd/hwKRhqE/AAPNqAho9RliGsvitCoOzREoVA==} - - '@rolldown/pluginutils@1.0.0-rc.3': - resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} - - '@rollup/rollup-android-arm-eabi@4.55.1': - resolution: {integrity: sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.55.1': - resolution: {integrity: sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.55.1': - resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.55.1': - resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.55.1': - resolution: {integrity: sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.55.1': - resolution: {integrity: sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.55.1': - resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.55.1': - resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.55.1': - resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.55.1': - resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loong64-gnu@4.55.1': - resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-loong64-musl@4.55.1': - resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.55.1': - resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-ppc64-musl@4.55.1': - resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.55.1': - resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.55.1': - resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.55.1': - resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.55.1': - resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.55.1': - resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-openbsd-x64@4.55.1': - resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.55.1': - resolution: {integrity: sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.55.1': - resolution: {integrity: sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.55.1': - resolution: {integrity: sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.55.1': - resolution: {integrity: sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.55.1': - resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==} - cpu: [x64] - os: [win32] - - '@shikijs/engine-oniguruma@3.23.0': - resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} - - '@shikijs/langs@3.23.0': - resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} - - '@shikijs/themes@3.23.0': - resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} - - '@shikijs/types@3.23.0': - resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} - - '@shikijs/vscode-textmate@10.0.2': - resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - - '@sinclair/typebox@0.34.47': - resolution: {integrity: sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw==} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@stylistic/eslint-plugin@5.7.0': - resolution: {integrity: sha512-PsSugIf9ip1H/mWKj4bi/BlEoerxXAda9ByRFsYuwsmr6af9NxJL0AaiNXs8Le7R21QR5KMiD/KdxZZ71LjAxQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: '>=9.0.0' - - '@sveltejs/acorn-typescript@1.0.8': - resolution: {integrity: sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA==} - peerDependencies: - acorn: ^8.9.0 - - '@svitejs/changesets-changelog-github-compact@1.2.0': - resolution: {integrity: sha512-08eKiDAjj4zLug1taXSIJ0kGL5cawjVCyJkBb6EWSg5fEPX6L+Wtr0CH2If4j5KYylz85iaZiFlUItvgJvll5g==} - engines: {node: ^14.13.1 || ^16.0.0 || >=18} - - '@tanstack/eslint-config@0.3.4': - resolution: {integrity: sha512-5Ou1XWJRCTx5G8WoCbT7+6nQ4iNdsISzBAc4lXpFy2fEOO7xioOSPvcPIv+r9V0drPPETou2tr6oLGZZ909FKg==} - engines: {node: '>=18'} - peerDependencies: - eslint: ^8.0.0 || ^9.0.0 - - '@tanstack/typedoc-config@0.3.3': - resolution: {integrity: sha512-wVT2YfKDSpd+4f7fk6UaPIP3a2J7LSovlyVuFF1PH2yQb7gjqehod5zdFiwFyEXgvI9XGuFvvs1OehkKNYcr6A==} - engines: {node: '>=18'} - - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} - - '@tybys/wasm-util@0.9.0': - resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} - - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/node@12.20.55': - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - - '@types/node@20.19.30': - resolution: {integrity: sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==} - - '@types/node@25.0.9': - resolution: {integrity: sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==} - - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - - '@types/whatwg-mimetype@3.0.2': - resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} - - '@types/ws@8.18.1': - resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - - '@typescript-eslint/eslint-plugin@8.53.0': - resolution: {integrity: sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.53.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/parser@8.53.0': - resolution: {integrity: sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/project-service@8.53.0': - resolution: {integrity: sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/scope-manager@8.53.0': - resolution: {integrity: sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.53.0': - resolution: {integrity: sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/type-utils@8.53.0': - resolution: {integrity: sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/types@8.53.0': - resolution: {integrity: sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.53.0': - resolution: {integrity: sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/utils@8.53.0': - resolution: {integrity: sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/visitor-keys@8.53.0': - resolution: {integrity: sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} - cpu: [arm] - os: [android] - - '@unrs/resolver-binding-android-arm64@1.11.1': - resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} - cpu: [arm64] - os: [android] - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} - cpu: [arm64] - os: [darwin] - - '@unrs/resolver-binding-darwin-x64@1.11.1': - resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} - cpu: [x64] - os: [darwin] - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} - cpu: [x64] - os: [freebsd] - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} - cpu: [ppc64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} - cpu: [s390x] - os: [linux] - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} - cpu: [arm64] - os: [win32] - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} - cpu: [ia32] - os: [win32] - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} - cpu: [x64] - os: [win32] - - '@vitest/expect@4.0.17': - resolution: {integrity: sha512-mEoqP3RqhKlbmUmntNDDCJeTDavDR+fVYkSOw8qRwJFaW/0/5zA9zFeTrHqNtcmwh6j26yMmwx2PqUDPzt5ZAQ==} - - '@vitest/mocker@4.0.17': - resolution: {integrity: sha512-+ZtQhLA3lDh1tI2wxe3yMsGzbp7uuJSWBM1iTIKCbppWTSBN09PUC+L+fyNlQApQoR+Ps8twt2pbSSXg2fQVEQ==} - peerDependencies: - msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0-0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - - '@vitest/pretty-format@4.0.17': - resolution: {integrity: sha512-Ah3VAYmjcEdHg6+MwFE17qyLqBHZ+ni2ScKCiW2XrlSBV4H3Z7vYfPfz7CWQ33gyu76oc0Ai36+kgLU3rfF4nw==} - - '@vitest/runner@4.0.17': - resolution: {integrity: sha512-JmuQyf8aMWoo/LmNFppdpkfRVHJcsgzkbCA+/Bk7VfNH7RE6Ut2qxegeyx2j3ojtJtKIbIGy3h+KxGfYfk28YQ==} - - '@vitest/snapshot@4.0.17': - resolution: {integrity: sha512-npPelD7oyL+YQM2gbIYvlavlMVWUfNNGZPcu0aEUQXt7FXTuqhmgiYupPnAanhKvyP6Srs2pIbWo30K0RbDtRQ==} - - '@vitest/spy@4.0.17': - resolution: {integrity: sha512-I1bQo8QaP6tZlTomQNWKJE6ym4SHf3oLS7ceNjozxxgzavRAgZDc06T7kD8gb9bXKEgcLNt00Z+kZO6KaJ62Ew==} - - '@vitest/utils@4.0.17': - resolution: {integrity: sha512-RG6iy+IzQpa9SB8HAFHJ9Y+pTzI+h8553MrciN9eC6TFBErqrQaTas4vG+MVj8S4uKk8uTT2p0vgZPnTdxd96w==} - - '@yarnpkg/lockfile@1.1.0': - resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - - '@yarnpkg/parsers@3.0.2': - resolution: {integrity: sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA==} - engines: {node: '>=18.12.0'} - - '@zkochan/js-yaml@0.0.7': - resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} - hasBin: true - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - - ansis@4.2.0: - resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} - engines: {node: '>=14'} - - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - - ast-kit@2.2.0: - resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} - engines: {node: '>=20.19.0'} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - axios@1.13.2: - resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} - - axobject-query@4.1.0: - resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} - engines: {node: '>= 0.4'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - better-path-resolve@1.0.0: - resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} - engines: {node: '>=4'} - - birpc@4.0.0: - resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} - engines: {node: '>=18'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chardet@2.1.1: - resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - - cheerio-select@2.1.0: - resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - - cheerio@1.1.2: - resolution: {integrity: sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==} - engines: {node: '>=20.18.1'} - - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@2.6.1: - resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} - engines: {node: '>=6'} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - comment-parser@1.4.4: - resolution: {integrity: sha512-0D6qSQ5IkeRrGJFHRClzaMOenMeT0gErz3zIw3AprKMqhRN6LNU2jQOdkPG/FZ+8bCgXE1VidrgSzlBBDZRr8A==} - engines: {node: '>= 12.0.0'} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} - - css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} - engines: {node: '>= 6'} - - dataloader@1.4.0: - resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - - define-lazy-prop@2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} - - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - detect-indent@6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} - engines: {node: '>=8'} - - devalue@5.6.2: - resolution: {integrity: sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - - domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - - domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - - domutils@3.2.2: - resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - - dotenv-expand@11.0.7: - resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} - engines: {node: '>=12'} - - dotenv@16.4.7: - resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} - engines: {node: '>=12'} - - dotenv@16.6.1: - resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} - engines: {node: '>=12'} - - dts-resolver@2.1.3: - resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==} - engines: {node: '>=20.19.0'} - peerDependencies: - oxc-resolver: '>=11.0.0' - peerDependenciesMeta: - oxc-resolver: - optional: true - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - empathic@2.0.0: - resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} - engines: {node: '>=14'} - - encoding-sniffer@0.2.1: - resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} - - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - - enhanced-resolve@5.18.4: - resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} - engines: {node: '>=10.13.0'} - - enquirer@2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} - - enquirer@2.4.1: - resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} - engines: {node: '>=8.6'} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - esbuild@0.27.2: - resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-compat-utils@0.5.1: - resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} - engines: {node: '>=12'} - peerDependencies: - eslint: '>=6.0.0' - - eslint-import-context@0.1.9: - resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - peerDependencies: - unrs-resolver: ^1.0.0 - peerDependenciesMeta: - unrs-resolver: - optional: true - - eslint-plugin-es-x@7.8.0: - resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '>=8' - - eslint-plugin-import-x@4.16.1: - resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/utils': ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 - eslint-import-resolver-node: '*' - peerDependenciesMeta: - '@typescript-eslint/utils': - optional: true - eslint-import-resolver-node: - optional: true - - eslint-plugin-n@17.23.2: - resolution: {integrity: sha512-RhWBeb7YVPmNa2eggvJooiuehdL76/bbfj/OJewyoGT80qn5PXdz8zMOTO6YHOsI7byPt7+Ighh/i/4a5/v7hw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: '>=8.23.0' - - eslint-plugin-unused-imports@4.3.0: - resolution: {integrity: sha512-ZFBmXMGBYfHttdRtOG9nFFpmUvMtbHSjsKrS20vdWdbfiVYsO3yA2SGYy9i9XmZJDfMGBflZGBCm70SEnFQtOA==} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 - eslint: ^9.0.0 || ^8.0.0 - peerDependenciesMeta: - '@typescript-eslint/eslint-plugin': - optional: true - - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@5.0.0: - resolution: {integrity: sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - eslint@9.39.2: - resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - esm-env@1.2.2: - resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - espree@11.0.0: - resolution: {integrity: sha512-+gMeWRrIh/NsG+3NaLeWHuyeyk70p2tbvZIWBYcqQ4/7Xvars6GYTZNhF1sIeLcc6Wb11He5ffz3hsHyXFrw5A==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} - - esrap@2.2.1: - resolution: {integrity: sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} - engines: {node: '>=12.0.0'} - - extendable-error@0.1.7: - resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - - fd-package-json@2.0.0: - resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} - - formatly@0.3.0: - resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==} - engines: {node: '>=18.3.0'} - hasBin: true - - front-matter@4.0.2: - resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} - - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - - fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} - - fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-tsconfig@4.13.0: - resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - globals@15.15.0: - resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} - engines: {node: '>=18'} - - globals@16.5.0: - resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} - engines: {node: '>=18'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - globrex@0.1.2: - resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - happy-dom@20.3.1: - resolution: {integrity: sha512-tLvsizNno05Hij0PoB0QN/S8xf0YU2AGvO11/JlJDw5McA/gzyn0Ni1RwbTI1/zteUbOekJH0t6q8HFvjbxsGg==} - engines: {node: '>=20.0.0'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - hookable@6.0.1: - resolution: {integrity: sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==} - - html-link-extractor@1.0.5: - resolution: {integrity: sha512-ADd49pudM157uWHwHQPUSX4ssMsvR/yHIswOR5CUfBdK9g9ZYGMhVSE6KZVHJ6kCkR0gH4htsfzU6zECDNVwyw==} - - htmlparser2@10.0.0: - resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} - - human-id@4.1.3: - resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} - hasBin: true - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - iconv-lite@0.7.2: - resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} - engines: {node: '>=0.10.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - import-without-cache@0.2.5: - resolution: {integrity: sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A==} - engines: {node: '>=20.19.0'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-reference@3.0.3: - resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} - - is-subdir@1.2.0: - resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} - engines: {node: '>=4'} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - - is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jest-diff@30.2.0: - resolution: {integrity: sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} - hasBin: true - - js-yaml@3.14.2: - resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} - hasBin: true - - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} - hasBin: true - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - knip@5.81.0: - resolution: {integrity: sha512-EM9YdNg6zU2DWMJuc9zD8kPUpj0wvPspa63Qe9DPGygzL956uYThfoUQk5aNpPmMr9hs/k+Xm7FLuWFKERFkrQ==} - engines: {node: '>=18.18.0'} - hasBin: true - peerDependencies: - '@types/node': '>=18' - typescript: '>=5.0.4 <7' - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - lines-and-columns@2.0.3: - resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - linkify-it@5.0.0: - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - - locate-character@3.0.0: - resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} - - locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash.startcase@4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - lunr@2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - markdown-it@14.1.1: - resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} - hasBin: true - - markdown-link-extractor@4.0.3: - resolution: {integrity: sha512-aEltJiQ4/oC0h6Jbw/uuATGSHZPkcH8DIunNH1A0e+GSFkvZ6BbBkdvBTVfIV8r6HapCU3yTd0eFdi3ZeM1eAQ==} - - marked@17.0.1: - resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==} - engines: {node: '>= 20'} - hasBin: true - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - mdurl@2.0.0: - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - napi-postinstall@0.3.4: - resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-machine-id@1.1.12: - resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - - nx@22.3.3: - resolution: {integrity: sha512-pOxtKWUfvf0oD8Geqs8D89Q2xpstRTaSY+F6Ut/Wd0GnEjUjO32SS1ymAM6WggGPHDZN4qpNrd5cfIxQmAbRLg==} - hasBin: true - peerDependencies: - '@swc-node/register': ^1.8.0 - '@swc/core': ^1.3.85 - peerDependenciesMeta: - '@swc-node/register': - optional: true - '@swc/core': - optional: true - - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - open@8.4.2: - resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} - engines: {node: '>=12'} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - ora@5.3.0: - resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} - engines: {node: '>=10'} - - outdent@0.5.0: - resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - - oxc-resolver@11.16.3: - resolution: {integrity: sha512-goLOJH3x69VouGWGp5CgCIHyksmOZzXr36lsRmQz1APg3SPFORrvV2q7nsUHMzLVa6ZJgNwkgUSJFsbCpAWkCA==} - - p-filter@2.1.0: - resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} - engines: {node: '>=8'} - - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - p-map@2.1.0: - resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} - engines: {node: '>=6'} - - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - - package-manager-detector@0.2.11: - resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parse5-htmlparser2-tree-adapter@7.1.0: - resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} - - parse5-parser-stream@7.1.2: - resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} - - parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier-plugin-svelte@3.4.1: - resolution: {integrity: sha512-xL49LCloMoZRvSwa6IEdN2GV6cq2IqpYGstYtMT+5wmml1/dClEoI0MZR78MiVPpu6BdQFfN0/y73yO6+br5Pg==} - peerDependencies: - prettier: ^3.0.0 - svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 - - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true - - prettier@3.8.0: - resolution: {integrity: sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==} - engines: {node: '>=14'} - hasBin: true - - pretty-format@30.2.0: - resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - quansync@0.2.11: - resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} - - quansync@1.0.0: - resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - - read-yaml-file@1.1.0: - resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} - engines: {node: '>=6'} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve.exports@2.0.3: - resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} - engines: {node: '>=10'} - - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rolldown-plugin-dts@0.20.0: - resolution: {integrity: sha512-cLAY1kN2ilTYMfZcFlGWbXnu6Nb+8uwUBsi+Mjbh4uIx7IN8uMOmJ7RxrrRgPsO4H7eSz3E+JwGoL1gyugiyUA==} - engines: {node: '>=20.19.0'} - peerDependencies: - '@ts-macro/tsc': ^0.3.6 - '@typescript/native-preview': '>=7.0.0-dev.20250601.1' - rolldown: ^1.0.0-beta.57 - typescript: ^5.0.0 - vue-tsc: ~3.2.0 - peerDependenciesMeta: - '@ts-macro/tsc': - optional: true - '@typescript/native-preview': - optional: true - typescript: - optional: true - vue-tsc: - optional: true - - rolldown@1.0.0-beta.59: - resolution: {integrity: sha512-Slm000Gd8/AO9z4Kxl4r8mp/iakrbAuJ1L+7ddpkNxgQ+Vf37WPvY63l3oeyZcfuPD1DRrUYBsRPIXSOhvOsmw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - rolldown@1.0.0-rc.3: - resolution: {integrity: sha512-Po/YZECDOqVXjIXrtC5h++a5NLvKAQNrd9ggrIG3sbDfGO5BqTUsrI6l8zdniKRp3r5Tp/2JTrXqx4GIguFCMw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - rollup@4.55.1: - resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - sherif-darwin-arm64@1.10.0: - resolution: {integrity: sha512-fHRg/fgyxHebCH9vuGEhImyGqmwlBq67BVyI8Ugda8GM+W+Ofj1cQnzDX82cYuCHU+KJ7hQFq8iPHkRizXWOrA==} - cpu: [arm64] - os: [darwin] - - sherif-darwin-x64@1.10.0: - resolution: {integrity: sha512-7rhayQ+jlIj3SscnHMi6JVCYR9od/HiqIGIBgOQeux31YRzc/XvfKjE9X+FrCRU+72qz7sqw5ZY7jl7bRxbOUg==} - cpu: [x64] - os: [darwin] - - sherif-linux-arm64-musl@1.10.0: - resolution: {integrity: sha512-TsaQSefkaIJ+oFGGaaPm5BzrjVRnvcquh4q3/e5LB6JdhPTveNPo3o2Pzmq6sKry9dzk3p7sKtzJpLz4q5V/+Q==} - cpu: [arm64] - os: [linux] - - sherif-linux-arm64@1.10.0: - resolution: {integrity: sha512-QtEju3eLPpEb7hv9QRVdsi2J3bhIFEBbRk0vjdnAEKyRb3q9MjyqEhps69JgaCv8olEiBjGcU1hGP7vl5QVG4A==} - cpu: [arm64] - os: [linux] - - sherif-linux-x64-musl@1.10.0: - resolution: {integrity: sha512-iSYRYEFE0xfOJVwPjsUN4o8CoNSEyxJHsSliBDxfEZQubN0rmE9f1hs83HPPAkEozGestI7PxKFKcyTgTxEoXg==} - cpu: [x64] - os: [linux] - - sherif-linux-x64@1.10.0: - resolution: {integrity: sha512-/1ydjgJxXbqnGWViAENHxlX9lEDhATO99qtFcMseUFkPpEAxQ9qFctWf3OB2rciPlHLuPzhphkJAt7ZkX1R5eA==} - cpu: [x64] - os: [linux] - - sherif-windows-arm64@1.10.0: - resolution: {integrity: sha512-CBNys+m7TsWD/1/5WQRJCNjfm08VhmBP9JSmecoHCsfDF+o0vt52NDrzVOOeai/c/yYunCBvAAx9EIFXBmgpHw==} - cpu: [arm64] - os: [win32] - - sherif-windows-x64@1.10.0: - resolution: {integrity: sha512-XRN4SuZQud0X4UKZZxLe4IyVkbo9qa8rvmFhgCoULaRScucNdJJ4r6hnjZ7DR0spl7zSPJNZUNcgnnJmxWfs1Q==} - cpu: [x64] - os: [win32] - - sherif@1.10.0: - resolution: {integrity: sha512-DHg6+Pj7ORhYyC+CaSAr8DeRxqf9GXB90yqLmUILPtY7WhZuJatMir3id2MNjuF5I/1313SbrTTItIDu//G4jg==} - hasBin: true - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - smol-toml@1.6.0: - resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} - engines: {node: '>= 18'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - spawndamnit@3.0.1: - resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - stable-hash-x@0.2.0: - resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} - engines: {node: '>=12.0.0'} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - strip-json-comments@5.0.3: - resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} - engines: {node: '>=14.16'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - svelte@5.46.4: - resolution: {integrity: sha512-VJwdXrmv9L8L7ZasJeWcCjoIuMRVbhuxbss0fpVnR8yorMmjNDwcjIH08vS6wmSzzzgAG5CADQ1JuXPS2nwt9w==} - engines: {node: '>=18'} - - tapable@2.3.0: - resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} - engines: {node: '>=6'} - - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - - term-size@2.2.1: - resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} - engines: {node: '>=8'} - - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@1.0.2: - resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} - engines: {node: '>=18'} - - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - - tinyrainbow@3.0.3: - resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} - engines: {node: '>=14.0.0'} - - tmp@0.2.5: - resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} - engines: {node: '>=14.14'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - ts-declaration-location@1.0.7: - resolution: {integrity: sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==} - peerDependencies: - typescript: '>=4.0.0' - - tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} - - tsdown@0.19.0: - resolution: {integrity: sha512-uqg8yzlS7GemFWcM6aCp/sptF4bJiJbWUibuHTRLLCBEsGCgJxuqxPhuVTqyHXqoEkh9ohwAdlyDKli5MEWCyQ==} - engines: {node: '>=20.19.0'} - hasBin: true - peerDependencies: - '@arethetypeswrong/core': ^0.18.1 - '@vitejs/devtools': '*' - publint: ^0.3.0 - typescript: ^5.0.0 - unplugin-lightningcss: ^0.4.0 - unplugin-unused: ^0.5.0 - peerDependenciesMeta: - '@arethetypeswrong/core': - optional: true - '@vitejs/devtools': - optional: true - publint: - optional: true - typescript: - optional: true - unplugin-lightningcss: - optional: true - unplugin-unused: - optional: true - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - typedoc-plugin-frontmatter@1.3.0: - resolution: {integrity: sha512-xYQFMAecMlsRUjmf9oM/Sq2FVz4zlgcbIeVFNLdO118CHTN06gIKJNSlyExh9+Xl8sK0YhIvoQwViUURxritWA==} - peerDependencies: - typedoc-plugin-markdown: '>=4.5.0' - - typedoc-plugin-markdown@4.9.0: - resolution: {integrity: sha512-9Uu4WR9L7ZBgAl60N/h+jqmPxxvnC9nQAlnnO/OujtG2ubjnKTVUFY1XDhcMY+pCqlX3N2HsQM2QTYZIU9tJuw==} - engines: {node: '>= 18'} - peerDependencies: - typedoc: 0.28.x - - typedoc@0.28.14: - resolution: {integrity: sha512-ftJYPvpVfQvFzpkoSfHLkJybdA/geDJ8BGQt/ZnkkhnBYoYW6lBgPQXu6vqLxO4X75dA55hX8Af847H5KXlEFA==} - engines: {node: '>= 18', pnpm: '>= 10'} - hasBin: true - peerDependencies: - typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x - - typescript-eslint@8.53.0: - resolution: {integrity: sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - - unconfig-core@7.5.0: - resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - - undici@7.18.2: - resolution: {integrity: sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==} - engines: {node: '>=20.18.1'} - - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - - unrun@0.2.27: - resolution: {integrity: sha512-Mmur1UJpIbfxasLOhPRvox/QS4xBiDii71hMP7smfRthGcwFL2OAmYRgduLANOAU4LUkvVamuP+02U+c90jlrw==} - engines: {node: '>=20.19.0'} - hasBin: true - peerDependencies: - synckit: ^0.11.11 - peerDependenciesMeta: - synckit: - optional: true - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - vite@7.3.1: - resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' - less: ^4.0.0 - lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitest@4.0.17: - resolution: {integrity: sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.17 - '@vitest/browser-preview': 4.0.17 - '@vitest/browser-webdriverio': 4.0.17 - '@vitest/ui': 4.0.17 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@opentelemetry/api': - optional: true - '@types/node': - optional: true - '@vitest/browser-playwright': - optional: true - '@vitest/browser-preview': - optional: true - '@vitest/browser-webdriverio': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - vue-eslint-parser@10.2.0: - resolution: {integrity: sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - - walk-up-path@4.0.0: - resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} - engines: {node: 20 || >=22} - - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - whatwg-encoding@3.1.1: - resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} - engines: {node: '>=18'} - deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation - - whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} - - whatwg-mimetype@4.0.0: - resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} - engines: {node: '>=18'} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - ws@8.19.0: - resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yaml@2.8.2: - resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} - engines: {node: '>= 14.6'} - hasBin: true - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - zimmerframe@1.1.4: - resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} - - zod@4.3.5: - resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} - -snapshots: - - '@babel/generator@7.29.1': - dependencies: - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.28.5': {} - - '@babel/parser@7.29.0': - dependencies: - '@babel/types': 7.29.0 - - '@babel/runtime@7.28.6': {} - - '@babel/types@7.29.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - - '@changesets/apply-release-plan@7.0.14': - dependencies: - '@changesets/config': 3.1.2 - '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.4 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.8.8 - resolve-from: 5.0.0 - semver: 7.7.3 - - '@changesets/assemble-release-plan@6.0.9': - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.3 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - semver: 7.7.3 - - '@changesets/changelog-git@0.2.1': - dependencies: - '@changesets/types': 6.1.0 - - '@changesets/cli@2.29.8(@types/node@25.0.9)': - dependencies: - '@changesets/apply-release-plan': 7.0.14 - '@changesets/assemble-release-plan': 6.0.9 - '@changesets/changelog-git': 0.2.1 - '@changesets/config': 3.1.2 - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.3 - '@changesets/get-release-plan': 4.0.14 - '@changesets/git': 3.0.4 - '@changesets/logger': 0.1.1 - '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.6 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@25.0.9) - '@manypkg/get-packages': 1.1.3 - ansi-colors: 4.1.3 - ci-info: 3.9.0 - enquirer: 2.4.1 - fs-extra: 7.0.1 - mri: 1.2.0 - p-limit: 2.3.0 - package-manager-detector: 0.2.11 - picocolors: 1.1.1 - resolve-from: 5.0.0 - semver: 7.7.3 - spawndamnit: 3.0.1 - term-size: 2.2.1 - transitivePeerDependencies: - - '@types/node' - - '@changesets/config@3.1.2': - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.3 - '@changesets/logger': 0.1.1 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - micromatch: 4.0.8 - - '@changesets/errors@0.2.0': - dependencies: - extendable-error: 0.1.7 - - '@changesets/get-dependents-graph@2.1.3': - dependencies: - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - picocolors: 1.1.1 - semver: 7.7.3 - - '@changesets/get-github-info@0.6.0': - dependencies: - dataloader: 1.4.0 - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - - '@changesets/get-release-plan@4.0.14': - dependencies: - '@changesets/assemble-release-plan': 6.0.9 - '@changesets/config': 3.1.2 - '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.6 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - - '@changesets/get-version-range-type@0.4.0': {} - - '@changesets/git@3.0.4': - dependencies: - '@changesets/errors': 0.2.0 - '@manypkg/get-packages': 1.1.3 - is-subdir: 1.2.0 - micromatch: 4.0.8 - spawndamnit: 3.0.1 - - '@changesets/logger@0.1.1': - dependencies: - picocolors: 1.1.1 - - '@changesets/parse@0.4.2': - dependencies: - '@changesets/types': 6.1.0 - js-yaml: 4.1.1 - - '@changesets/pre@2.0.2': - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - - '@changesets/read@0.6.6': - dependencies: - '@changesets/git': 3.0.4 - '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.2 - '@changesets/types': 6.1.0 - fs-extra: 7.0.1 - p-filter: 2.1.0 - picocolors: 1.1.1 - - '@changesets/should-skip-package@0.1.2': - dependencies: - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - - '@changesets/types@4.1.0': {} - - '@changesets/types@6.1.0': {} - - '@changesets/write@0.4.0': - dependencies: - '@changesets/types': 6.1.0 - fs-extra: 7.0.1 - human-id: 4.1.3 - prettier: 2.8.8 - - '@emnapi/core@1.8.1': - dependencies: - '@emnapi/wasi-threads': 1.1.0 - tslib: 2.8.1 - - '@emnapi/runtime@1.8.1': - dependencies: - tslib: 2.8.1 - - '@emnapi/wasi-threads@1.1.0': - dependencies: - tslib: 2.8.1 - - '@esbuild/aix-ppc64@0.27.2': - optional: true - - '@esbuild/android-arm64@0.27.2': - optional: true - - '@esbuild/android-arm@0.27.2': - optional: true - - '@esbuild/android-x64@0.27.2': - optional: true - - '@esbuild/darwin-arm64@0.27.2': - optional: true - - '@esbuild/darwin-x64@0.27.2': - optional: true - - '@esbuild/freebsd-arm64@0.27.2': - optional: true - - '@esbuild/freebsd-x64@0.27.2': - optional: true - - '@esbuild/linux-arm64@0.27.2': - optional: true - - '@esbuild/linux-arm@0.27.2': - optional: true - - '@esbuild/linux-ia32@0.27.2': - optional: true - - '@esbuild/linux-loong64@0.27.2': - optional: true - - '@esbuild/linux-mips64el@0.27.2': - optional: true - - '@esbuild/linux-ppc64@0.27.2': - optional: true - - '@esbuild/linux-riscv64@0.27.2': - optional: true - - '@esbuild/linux-s390x@0.27.2': - optional: true - - '@esbuild/linux-x64@0.27.2': - optional: true - - '@esbuild/netbsd-arm64@0.27.2': - optional: true - - '@esbuild/netbsd-x64@0.27.2': - optional: true - - '@esbuild/openbsd-arm64@0.27.2': - optional: true - - '@esbuild/openbsd-x64@0.27.2': - optional: true - - '@esbuild/openharmony-arm64@0.27.2': - optional: true - - '@esbuild/sunos-x64@0.27.2': - optional: true - - '@esbuild/win32-arm64@0.27.2': - optional: true - - '@esbuild/win32-ia32@0.27.2': - optional: true - - '@esbuild/win32-x64@0.27.2': - optional: true - - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2(jiti@2.6.1))': - dependencies: - eslint: 9.39.2(jiti@2.6.1) - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.2': {} - - '@eslint/config-array@0.21.1': - dependencies: - '@eslint/object-schema': 2.1.7 - debug: 4.4.3 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.4.2': - dependencies: - '@eslint/core': 0.17.0 - - '@eslint/core@0.17.0': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.3': - dependencies: - ajv: 6.12.6 - debug: 4.4.3 - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.1 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.39.2': {} - - '@eslint/object-schema@2.1.7': {} - - '@eslint/plugin-kit@0.4.1': - dependencies: - '@eslint/core': 0.17.0 - levn: 0.4.1 - - '@faker-js/faker@10.2.0': {} - - '@gerrit0/mini-shiki@3.23.0': - dependencies: - '@shikijs/engine-oniguruma': 3.23.0 - '@shikijs/langs': 3.23.0 - '@shikijs/themes': 3.23.0 - '@shikijs/types': 3.23.0 - '@shikijs/vscode-textmate': 10.0.2 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.7': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.4.3 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.4.3': {} - - '@inquirer/external-editor@1.0.3(@types/node@25.0.9)': - dependencies: - chardet: 2.1.1 - iconv-lite: 0.7.2 - optionalDependencies: - '@types/node': 25.0.9 - - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': - dependencies: - '@isaacs/balanced-match': 4.0.1 - - '@jest/diff-sequences@30.0.1': {} - - '@jest/get-type@30.1.0': {} - - '@jest/schemas@30.0.5': - dependencies: - '@sinclair/typebox': 0.34.47 - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@manypkg/find-root@1.1.0': - dependencies: - '@babel/runtime': 7.28.6 - '@types/node': 12.20.55 - find-up: 4.1.0 - fs-extra: 8.1.0 - - '@manypkg/get-packages@1.1.3': - dependencies: - '@babel/runtime': 7.28.6 - '@changesets/types': 4.1.0 - '@manypkg/find-root': 1.1.0 - fs-extra: 8.1.0 - globby: 11.1.0 - read-yaml-file: 1.1.0 - - '@napi-rs/wasm-runtime@0.2.12': - dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 - '@tybys/wasm-util': 0.10.1 - optional: true - - '@napi-rs/wasm-runtime@0.2.4': - dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 - '@tybys/wasm-util': 0.9.0 - - '@napi-rs/wasm-runtime@1.1.1': - dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 - '@tybys/wasm-util': 0.10.1 - optional: true - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 - - '@nx/nx-darwin-arm64@22.3.3': - optional: true - - '@nx/nx-darwin-x64@22.3.3': - optional: true - - '@nx/nx-freebsd-x64@22.3.3': - optional: true - - '@nx/nx-linux-arm-gnueabihf@22.3.3': - optional: true - - '@nx/nx-linux-arm64-gnu@22.3.3': - optional: true - - '@nx/nx-linux-arm64-musl@22.3.3': - optional: true - - '@nx/nx-linux-x64-gnu@22.3.3': - optional: true - - '@nx/nx-linux-x64-musl@22.3.3': - optional: true - - '@nx/nx-win32-arm64-msvc@22.3.3': - optional: true - - '@nx/nx-win32-x64-msvc@22.3.3': - optional: true - - '@oxc-project/types@0.107.0': {} - - '@oxc-project/types@0.112.0': {} - - '@oxc-resolver/binding-android-arm-eabi@11.16.3': - optional: true - - '@oxc-resolver/binding-android-arm64@11.16.3': - optional: true - - '@oxc-resolver/binding-darwin-arm64@11.16.3': - optional: true - - '@oxc-resolver/binding-darwin-x64@11.16.3': - optional: true - - '@oxc-resolver/binding-freebsd-x64@11.16.3': - optional: true - - '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.3': - optional: true - - '@oxc-resolver/binding-linux-arm-musleabihf@11.16.3': - optional: true - - '@oxc-resolver/binding-linux-arm64-gnu@11.16.3': - optional: true - - '@oxc-resolver/binding-linux-arm64-musl@11.16.3': - optional: true - - '@oxc-resolver/binding-linux-ppc64-gnu@11.16.3': - optional: true - - '@oxc-resolver/binding-linux-riscv64-gnu@11.16.3': - optional: true - - '@oxc-resolver/binding-linux-riscv64-musl@11.16.3': - optional: true - - '@oxc-resolver/binding-linux-s390x-gnu@11.16.3': - optional: true - - '@oxc-resolver/binding-linux-x64-gnu@11.16.3': - optional: true - - '@oxc-resolver/binding-linux-x64-musl@11.16.3': - optional: true - - '@oxc-resolver/binding-openharmony-arm64@11.16.3': - optional: true - - '@oxc-resolver/binding-wasm32-wasi@11.16.3': - dependencies: - '@napi-rs/wasm-runtime': 1.1.1 - optional: true - - '@oxc-resolver/binding-win32-arm64-msvc@11.16.3': - optional: true - - '@oxc-resolver/binding-win32-ia32-msvc@11.16.3': - optional: true - - '@oxc-resolver/binding-win32-x64-msvc@11.16.3': - optional: true - - '@quansync/fs@1.0.0': - dependencies: - quansync: 1.0.0 - - '@rolldown/binding-android-arm64@1.0.0-beta.59': - optional: true - - '@rolldown/binding-android-arm64@1.0.0-rc.3': - optional: true - - '@rolldown/binding-darwin-arm64@1.0.0-beta.59': - optional: true - - '@rolldown/binding-darwin-arm64@1.0.0-rc.3': - optional: true - - '@rolldown/binding-darwin-x64@1.0.0-beta.59': - optional: true - - '@rolldown/binding-darwin-x64@1.0.0-rc.3': - optional: true - - '@rolldown/binding-freebsd-x64@1.0.0-beta.59': - optional: true - - '@rolldown/binding-freebsd-x64@1.0.0-rc.3': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.59': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.59': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.59': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.3': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.59': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.3': - optional: true - - '@rolldown/binding-linux-x64-musl@1.0.0-beta.59': - optional: true - - '@rolldown/binding-linux-x64-musl@1.0.0-rc.3': - optional: true - - '@rolldown/binding-openharmony-arm64@1.0.0-beta.59': - optional: true - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.3': - optional: true - - '@rolldown/binding-wasm32-wasi@1.0.0-beta.59': - dependencies: - '@napi-rs/wasm-runtime': 1.1.1 - optional: true - - '@rolldown/binding-wasm32-wasi@1.0.0-rc.3': - dependencies: - '@napi-rs/wasm-runtime': 1.1.1 - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.59': - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.59': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.3': - optional: true - - '@rolldown/pluginutils@1.0.0-beta.59': {} - - '@rolldown/pluginutils@1.0.0-rc.3': {} - - '@rollup/rollup-android-arm-eabi@4.55.1': - optional: true - - '@rollup/rollup-android-arm64@4.55.1': - optional: true - - '@rollup/rollup-darwin-arm64@4.55.1': - optional: true - - '@rollup/rollup-darwin-x64@4.55.1': - optional: true - - '@rollup/rollup-freebsd-arm64@4.55.1': - optional: true - - '@rollup/rollup-freebsd-x64@4.55.1': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.55.1': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.55.1': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.55.1': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.55.1': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.55.1': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.55.1': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.55.1': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.55.1': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.55.1': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.55.1': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.55.1': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.55.1': - optional: true - - '@rollup/rollup-linux-x64-musl@4.55.1': - optional: true - - '@rollup/rollup-openbsd-x64@4.55.1': - optional: true - - '@rollup/rollup-openharmony-arm64@4.55.1': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.55.1': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.55.1': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.55.1': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.55.1': - optional: true - - '@shikijs/engine-oniguruma@3.23.0': - dependencies: - '@shikijs/types': 3.23.0 - '@shikijs/vscode-textmate': 10.0.2 - - '@shikijs/langs@3.23.0': - dependencies: - '@shikijs/types': 3.23.0 - - '@shikijs/themes@3.23.0': - dependencies: - '@shikijs/types': 3.23.0 - - '@shikijs/types@3.23.0': - dependencies: - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - - '@shikijs/vscode-textmate@10.0.2': {} - - '@sinclair/typebox@0.34.47': {} - - '@standard-schema/spec@1.1.0': {} - - '@stylistic/eslint-plugin@5.7.0(eslint@9.39.2(jiti@2.6.1))': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/types': 8.53.0 - eslint: 9.39.2(jiti@2.6.1) - eslint-visitor-keys: 5.0.0 - espree: 11.0.0 - estraverse: 5.3.0 - picomatch: 4.0.3 - - '@sveltejs/acorn-typescript@1.0.8(acorn@8.15.0)': - dependencies: - acorn: 8.15.0 - - '@svitejs/changesets-changelog-github-compact@1.2.0': - dependencies: - '@changesets/get-github-info': 0.6.0 - dotenv: 16.6.1 - transitivePeerDependencies: - - encoding - - '@tanstack/eslint-config@0.3.4(@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': - dependencies: - '@eslint/js': 9.39.2 - '@stylistic/eslint-plugin': 5.7.0(eslint@9.39.2(jiti@2.6.1)) - eslint: 9.39.2(jiti@2.6.1) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) - eslint-plugin-n: 17.23.2(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - globals: 16.5.0 - typescript-eslint: 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - vue-eslint-parser: 10.2.0(eslint@9.39.2(jiti@2.6.1)) - transitivePeerDependencies: - - '@typescript-eslint/utils' - - eslint-import-resolver-node - - supports-color - - typescript - - '@tanstack/typedoc-config@0.3.3(typescript@5.9.3)': - dependencies: - typedoc: 0.28.14(typescript@5.9.3) - typedoc-plugin-frontmatter: 1.3.0(typedoc-plugin-markdown@4.9.0(typedoc@0.28.14(typescript@5.9.3))) - typedoc-plugin-markdown: 4.9.0(typedoc@0.28.14(typescript@5.9.3)) - transitivePeerDependencies: - - typescript - - '@tybys/wasm-util@0.10.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@tybys/wasm-util@0.9.0': - dependencies: - tslib: 2.8.1 - - '@types/chai@5.2.3': - dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 - - '@types/deep-eql@4.0.2': {} - - '@types/estree@1.0.8': {} - - '@types/hast@3.0.4': - dependencies: - '@types/unist': 3.0.3 - - '@types/json-schema@7.0.15': {} - - '@types/node@12.20.55': {} - - '@types/node@20.19.30': - dependencies: - undici-types: 6.21.0 - - '@types/node@25.0.9': - dependencies: - undici-types: 7.16.0 - - '@types/unist@3.0.3': {} - - '@types/whatwg-mimetype@3.0.2': {} - - '@types/ws@8.18.1': - dependencies: - '@types/node': 25.0.9 - - '@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': - dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.53.0 - eslint: 9.39.2(jiti@2.6.1) - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.53.0 - debug: 4.4.3 - eslint: 9.39.2(jiti@2.6.1) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.53.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3) - '@typescript-eslint/types': 8.53.0 - debug: 4.4.3 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.53.0': - dependencies: - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/visitor-keys': 8.53.0 - - '@typescript-eslint/tsconfig-utils@8.53.0(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 - - '@typescript-eslint/type-utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': - dependencies: - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - debug: 4.4.3 - eslint: 9.39.2(jiti@2.6.1) - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.53.0': {} - - '@typescript-eslint/typescript-estree@8.53.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.53.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3) - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/visitor-keys': 8.53.0 - debug: 4.4.3 - minimatch: 9.0.5 - semver: 7.7.3 - tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - eslint: 9.39.2(jiti@2.6.1) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.53.0': - dependencies: - '@typescript-eslint/types': 8.53.0 - eslint-visitor-keys: 4.2.1 - - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - optional: true - - '@unrs/resolver-binding-android-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - dependencies: - '@napi-rs/wasm-runtime': 0.2.12 - optional: true - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - optional: true - - '@vitest/expect@4.0.17': - dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.0.17 - '@vitest/utils': 4.0.17 - chai: 6.2.2 - tinyrainbow: 3.0.3 - - '@vitest/mocker@4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2))': - dependencies: - '@vitest/spy': 4.0.17 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2) - - '@vitest/pretty-format@4.0.17': - dependencies: - tinyrainbow: 3.0.3 - - '@vitest/runner@4.0.17': - dependencies: - '@vitest/utils': 4.0.17 - pathe: 2.0.3 - - '@vitest/snapshot@4.0.17': - dependencies: - '@vitest/pretty-format': 4.0.17 - magic-string: 0.30.21 - pathe: 2.0.3 - - '@vitest/spy@4.0.17': {} - - '@vitest/utils@4.0.17': - dependencies: - '@vitest/pretty-format': 4.0.17 - tinyrainbow: 3.0.3 - - '@yarnpkg/lockfile@1.1.0': {} - - '@yarnpkg/parsers@3.0.2': - dependencies: - js-yaml: 3.14.2 - tslib: 2.8.1 - - '@zkochan/js-yaml@0.0.7': - dependencies: - argparse: 2.0.1 - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-colors@4.1.3: {} - - ansi-regex@5.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - - ansis@4.2.0: {} - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - - aria-query@5.3.2: {} - - array-union@2.1.0: {} - - assertion-error@2.0.1: {} - - ast-kit@2.2.0: - dependencies: - '@babel/parser': 7.29.0 - pathe: 2.0.3 - - asynckit@0.4.0: {} - - axios@1.13.2: - dependencies: - follow-redirects: 1.15.11 - form-data: 4.0.5 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - axobject-query@4.1.0: {} - - balanced-match@1.0.2: {} - - base64-js@1.5.1: {} - - better-path-resolve@1.0.0: - dependencies: - is-windows: 1.0.2 - - birpc@4.0.0: {} - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - - boolbase@1.0.0: {} - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - cac@6.7.14: {} - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - callsites@3.1.0: {} - - chai@6.2.2: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chardet@2.1.1: {} - - cheerio-select@2.1.0: - dependencies: - boolbase: 1.0.0 - css-select: 5.2.2 - css-what: 6.2.2 - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.2.2 - - cheerio@1.1.2: - dependencies: - cheerio-select: 2.1.0 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - domutils: 3.2.2 - encoding-sniffer: 0.2.1 - htmlparser2: 10.0.0 - parse5: 7.3.0 - parse5-htmlparser2-tree-adapter: 7.1.0 - parse5-parser-stream: 7.1.2 - undici: 7.18.2 - whatwg-mimetype: 4.0.0 - - ci-info@3.9.0: {} - - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@2.6.1: {} - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clone@1.0.4: {} - - clsx@2.1.1: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - comment-parser@1.4.4: {} - - concat-map@0.0.1: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - css-select@5.2.2: - dependencies: - boolbase: 1.0.0 - css-what: 6.2.2 - domhandler: 5.0.3 - domutils: 3.2.2 - nth-check: 2.1.1 - - css-what@6.2.2: {} - - dataloader@1.4.0: {} - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - deep-is@0.1.4: {} - - defaults@1.0.4: - dependencies: - clone: 1.0.4 - - define-lazy-prop@2.0.0: {} - - defu@6.1.4: {} - - delayed-stream@1.0.0: {} - - detect-indent@6.1.0: {} - - devalue@5.6.2: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - dom-serializer@2.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - - domelementtype@2.3.0: {} - - domhandler@5.0.3: - dependencies: - domelementtype: 2.3.0 - - domutils@3.2.2: - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - - dotenv-expand@11.0.7: - dependencies: - dotenv: 16.4.7 - - dotenv@16.4.7: {} - - dotenv@16.6.1: {} - - dts-resolver@2.1.3(oxc-resolver@11.16.3): - optionalDependencies: - oxc-resolver: 11.16.3 - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - emoji-regex@8.0.0: {} - - empathic@2.0.0: {} - - encoding-sniffer@0.2.1: - dependencies: - iconv-lite: 0.6.3 - whatwg-encoding: 3.1.1 - - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - - enhanced-resolve@5.18.4: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.0 - - enquirer@2.3.6: - dependencies: - ansi-colors: 4.1.3 - - enquirer@2.4.1: - dependencies: - ansi-colors: 4.1.3 - strip-ansi: 6.0.1 - - entities@4.5.0: {} - - entities@6.0.1: {} - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-module-lexer@1.7.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - esbuild@0.27.2: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.2 - '@esbuild/android-arm': 0.27.2 - '@esbuild/android-arm64': 0.27.2 - '@esbuild/android-x64': 0.27.2 - '@esbuild/darwin-arm64': 0.27.2 - '@esbuild/darwin-x64': 0.27.2 - '@esbuild/freebsd-arm64': 0.27.2 - '@esbuild/freebsd-x64': 0.27.2 - '@esbuild/linux-arm': 0.27.2 - '@esbuild/linux-arm64': 0.27.2 - '@esbuild/linux-ia32': 0.27.2 - '@esbuild/linux-loong64': 0.27.2 - '@esbuild/linux-mips64el': 0.27.2 - '@esbuild/linux-ppc64': 0.27.2 - '@esbuild/linux-riscv64': 0.27.2 - '@esbuild/linux-s390x': 0.27.2 - '@esbuild/linux-x64': 0.27.2 - '@esbuild/netbsd-arm64': 0.27.2 - '@esbuild/netbsd-x64': 0.27.2 - '@esbuild/openbsd-arm64': 0.27.2 - '@esbuild/openbsd-x64': 0.27.2 - '@esbuild/openharmony-arm64': 0.27.2 - '@esbuild/sunos-x64': 0.27.2 - '@esbuild/win32-arm64': 0.27.2 - '@esbuild/win32-ia32': 0.27.2 - '@esbuild/win32-x64': 0.27.2 - - escalade@3.2.0: {} - - escape-string-regexp@1.0.5: {} - - escape-string-regexp@4.0.0: {} - - eslint-compat-utils@0.5.1(eslint@9.39.2(jiti@2.6.1)): - dependencies: - eslint: 9.39.2(jiti@2.6.1) - semver: 7.7.3 - - eslint-import-context@0.1.9(unrs-resolver@1.11.1): - dependencies: - get-tsconfig: 4.13.0 - stable-hash-x: 0.2.0 - optionalDependencies: - unrs-resolver: 1.11.1 - - eslint-plugin-es-x@7.8.0(eslint@9.39.2(jiti@2.6.1)): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - '@eslint-community/regexpp': 4.12.2 - eslint: 9.39.2(jiti@2.6.1) - eslint-compat-utils: 0.5.1(eslint@9.39.2(jiti@2.6.1)) - - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): - dependencies: - '@typescript-eslint/types': 8.53.0 - comment-parser: 1.4.4 - debug: 4.4.3 - eslint: 9.39.2(jiti@2.6.1) - eslint-import-context: 0.1.9(unrs-resolver@1.11.1) - is-glob: 4.0.3 - minimatch: 10.1.1 - semver: 7.7.3 - stable-hash-x: 0.2.0 - unrs-resolver: 1.11.1 - optionalDependencies: - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - transitivePeerDependencies: - - supports-color - - eslint-plugin-n@17.23.2(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - enhanced-resolve: 5.18.4 - eslint: 9.39.2(jiti@2.6.1) - eslint-plugin-es-x: 7.8.0(eslint@9.39.2(jiti@2.6.1)) - get-tsconfig: 4.13.0 - globals: 15.15.0 - globrex: 0.1.2 - ignore: 5.3.2 - semver: 7.7.3 - ts-declaration-location: 1.0.7(typescript@5.9.3) - transitivePeerDependencies: - - typescript - - eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): - dependencies: - eslint: 9.39.2(jiti@2.6.1) - optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint-visitor-keys@5.0.0: {} - - eslint@9.39.2(jiti@2.6.1): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.1 - '@eslint/config-helpers': 0.4.2 - '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.3 - '@eslint/js': 9.39.2 - '@eslint/plugin-kit': 0.4.1 - '@humanfs/node': 0.16.7 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.7.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - optionalDependencies: - jiti: 2.6.1 - transitivePeerDependencies: - - supports-color - - esm-env@1.2.2: {} - - espree@10.4.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 4.2.1 - - espree@11.0.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 5.0.0 - - esprima@4.0.1: {} - - esquery@1.7.0: - dependencies: - estraverse: 5.3.0 - - esrap@2.2.1: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.8 - - esutils@2.0.3: {} - - expect-type@1.3.0: {} - - extendable-error@0.1.7: {} - - fast-deep-equal@3.1.3: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.20.1: - dependencies: - reusify: 1.1.0 - - fd-package-json@2.0.0: - dependencies: - walk-up-path: 4.0.0 - - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - figures@3.2.0: - dependencies: - escape-string-regexp: 1.0.5 - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@4.1.0: - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - - flat@5.0.2: {} - - flatted@3.3.3: {} - - follow-redirects@1.15.11: {} - - form-data@4.0.5: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.2 - mime-types: 2.1.35 - - formatly@0.3.0: - dependencies: - fd-package-json: 2.0.0 - - front-matter@4.0.2: - dependencies: - js-yaml: 3.14.2 - - fs-constants@1.0.0: {} - - fs-extra@7.0.1: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fs-extra@8.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - get-caller-file@2.0.5: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-tsconfig@4.13.0: - dependencies: - resolve-pkg-maps: 1.0.0 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - globals@14.0.0: {} - - globals@15.15.0: {} - - globals@16.5.0: {} - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - - globrex@0.1.2: {} - - gopd@1.2.0: {} - - graceful-fs@4.2.11: {} - - happy-dom@20.3.1: - dependencies: - '@types/node': 20.19.30 - '@types/whatwg-mimetype': 3.0.2 - '@types/ws': 8.18.1 - whatwg-mimetype: 3.0.0 - ws: 8.19.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - has-flag@4.0.0: {} - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - hookable@6.0.1: {} - - html-link-extractor@1.0.5: - dependencies: - cheerio: 1.1.2 - - htmlparser2@10.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.2.2 - entities: 6.0.1 - - human-id@4.1.3: {} - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - iconv-lite@0.7.2: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.2.1: {} - - ignore@5.3.2: {} - - ignore@7.0.5: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - import-without-cache@0.2.5: {} - - imurmurhash@0.1.4: {} - - inherits@2.0.4: {} - - is-docker@2.2.1: {} - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-interactive@1.0.0: {} - - is-number@7.0.0: {} - - is-reference@3.0.3: - dependencies: - '@types/estree': 1.0.8 - - is-subdir@1.2.0: - dependencies: - better-path-resolve: 1.0.0 - - is-unicode-supported@0.1.0: {} - - is-windows@1.0.2: {} - - is-wsl@2.2.0: - dependencies: - is-docker: 2.2.1 - - isexe@2.0.0: {} - - jest-diff@30.2.0: - dependencies: - '@jest/diff-sequences': 30.0.1 - '@jest/get-type': 30.1.0 - chalk: 4.1.2 - pretty-format: 30.2.0 - - jiti@2.6.1: {} - - js-yaml@3.14.2: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - js-yaml@4.1.1: - dependencies: - argparse: 2.0.1 - - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - json5@2.2.3: {} - - jsonc-parser@3.2.0: {} - - jsonfile@4.0.0: - optionalDependencies: - graceful-fs: 4.2.11 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - knip@5.81.0(@types/node@25.0.9)(typescript@5.9.3): - dependencies: - '@nodelib/fs.walk': 1.2.8 - '@types/node': 25.0.9 - fast-glob: 3.3.3 - formatly: 0.3.0 - jiti: 2.6.1 - js-yaml: 4.1.1 - minimist: 1.2.8 - oxc-resolver: 11.16.3 - picocolors: 1.1.1 - picomatch: 4.0.3 - smol-toml: 1.6.0 - strip-json-comments: 5.0.3 - typescript: 5.9.3 - zod: 4.3.5 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - lines-and-columns@2.0.3: {} - - linkify-it@5.0.0: - dependencies: - uc.micro: 2.1.0 - - locate-character@3.0.0: {} - - locate-path@5.0.0: - dependencies: - p-locate: 4.1.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - - lodash.startcase@4.4.0: {} - - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - - lunr@2.3.9: {} - - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - markdown-it@14.1.1: - dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.0 - mdurl: 2.0.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 - - markdown-link-extractor@4.0.3: - dependencies: - html-link-extractor: 1.0.5 - marked: 17.0.1 - - marked@17.0.1: {} - - math-intrinsics@1.1.0: {} - - mdurl@2.0.0: {} - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mimic-fn@2.1.0: {} - - minimatch@10.1.1: - dependencies: - '@isaacs/brace-expansion': 5.0.0 - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 - - minimatch@9.0.3: - dependencies: - brace-expansion: 2.0.2 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - minimist@1.2.8: {} - - mri@1.2.0: {} - - ms@2.1.3: {} - - nanoid@3.3.11: {} - - napi-postinstall@0.3.4: {} - - natural-compare@1.4.0: {} - - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - - node-machine-id@1.1.12: {} - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - nth-check@2.1.1: - dependencies: - boolbase: 1.0.0 - - nx@22.3.3: - dependencies: - '@napi-rs/wasm-runtime': 0.2.4 - '@yarnpkg/lockfile': 1.1.0 - '@yarnpkg/parsers': 3.0.2 - '@zkochan/js-yaml': 0.0.7 - axios: 1.13.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.6.1 - cliui: 8.0.1 - dotenv: 16.4.7 - dotenv-expand: 11.0.7 - enquirer: 2.3.6 - figures: 3.2.0 - flat: 5.0.2 - front-matter: 4.0.2 - ignore: 7.0.5 - jest-diff: 30.2.0 - jsonc-parser: 3.2.0 - lines-and-columns: 2.0.3 - minimatch: 9.0.3 - node-machine-id: 1.1.12 - npm-run-path: 4.0.1 - open: 8.4.2 - ora: 5.3.0 - resolve.exports: 2.0.3 - semver: 7.7.3 - string-width: 4.2.3 - tar-stream: 2.2.0 - tmp: 0.2.5 - tree-kill: 1.2.2 - tsconfig-paths: 4.2.0 - tslib: 2.8.1 - yaml: 2.8.2 - yargs: 17.7.2 - yargs-parser: 21.1.1 - optionalDependencies: - '@nx/nx-darwin-arm64': 22.3.3 - '@nx/nx-darwin-x64': 22.3.3 - '@nx/nx-freebsd-x64': 22.3.3 - '@nx/nx-linux-arm-gnueabihf': 22.3.3 - '@nx/nx-linux-arm64-gnu': 22.3.3 - '@nx/nx-linux-arm64-musl': 22.3.3 - '@nx/nx-linux-x64-gnu': 22.3.3 - '@nx/nx-linux-x64-musl': 22.3.3 - '@nx/nx-win32-arm64-msvc': 22.3.3 - '@nx/nx-win32-x64-msvc': 22.3.3 - transitivePeerDependencies: - - debug - - obug@2.1.1: {} - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - open@8.4.2: - dependencies: - define-lazy-prop: 2.0.0 - is-docker: 2.2.1 - is-wsl: 2.2.0 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - ora@5.3.0: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.6.1 - is-interactive: 1.0.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - outdent@0.5.0: {} - - oxc-resolver@11.16.3: - optionalDependencies: - '@oxc-resolver/binding-android-arm-eabi': 11.16.3 - '@oxc-resolver/binding-android-arm64': 11.16.3 - '@oxc-resolver/binding-darwin-arm64': 11.16.3 - '@oxc-resolver/binding-darwin-x64': 11.16.3 - '@oxc-resolver/binding-freebsd-x64': 11.16.3 - '@oxc-resolver/binding-linux-arm-gnueabihf': 11.16.3 - '@oxc-resolver/binding-linux-arm-musleabihf': 11.16.3 - '@oxc-resolver/binding-linux-arm64-gnu': 11.16.3 - '@oxc-resolver/binding-linux-arm64-musl': 11.16.3 - '@oxc-resolver/binding-linux-ppc64-gnu': 11.16.3 - '@oxc-resolver/binding-linux-riscv64-gnu': 11.16.3 - '@oxc-resolver/binding-linux-riscv64-musl': 11.16.3 - '@oxc-resolver/binding-linux-s390x-gnu': 11.16.3 - '@oxc-resolver/binding-linux-x64-gnu': 11.16.3 - '@oxc-resolver/binding-linux-x64-musl': 11.16.3 - '@oxc-resolver/binding-openharmony-arm64': 11.16.3 - '@oxc-resolver/binding-wasm32-wasi': 11.16.3 - '@oxc-resolver/binding-win32-arm64-msvc': 11.16.3 - '@oxc-resolver/binding-win32-ia32-msvc': 11.16.3 - '@oxc-resolver/binding-win32-x64-msvc': 11.16.3 - - p-filter@2.1.0: - dependencies: - p-map: 2.1.0 - - p-limit@2.3.0: - dependencies: - p-try: 2.2.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@4.1.0: - dependencies: - p-limit: 2.3.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - p-map@2.1.0: {} - - p-try@2.2.0: {} - - package-manager-detector@0.2.11: - dependencies: - quansync: 0.2.11 - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse5-htmlparser2-tree-adapter@7.1.0: - dependencies: - domhandler: 5.0.3 - parse5: 7.3.0 - - parse5-parser-stream@7.1.2: - dependencies: - parse5: 7.3.0 - - parse5@7.3.0: - dependencies: - entities: 6.0.1 - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - path-type@4.0.0: {} - - pathe@2.0.3: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.3: {} - - pify@4.0.1: {} - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - prelude-ls@1.2.1: {} - - prettier-plugin-svelte@3.4.1(prettier@3.8.0)(svelte@5.46.4): - dependencies: - prettier: 3.8.0 - svelte: 5.46.4 - - prettier@2.8.8: {} - - prettier@3.8.0: {} - - pretty-format@30.2.0: - dependencies: - '@jest/schemas': 30.0.5 - ansi-styles: 5.2.0 - react-is: 18.3.1 - - proxy-from-env@1.1.0: {} - - punycode.js@2.3.1: {} - - punycode@2.3.1: {} - - quansync@0.2.11: {} - - quansync@1.0.0: {} - - queue-microtask@1.2.3: {} - - react-is@18.3.1: {} - - read-yaml-file@1.1.0: - dependencies: - graceful-fs: 4.2.11 - js-yaml: 3.14.2 - pify: 4.0.1 - strip-bom: 3.0.0 - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - require-directory@2.1.1: {} - - resolve-from@4.0.0: {} - - resolve-from@5.0.0: {} - - resolve-pkg-maps@1.0.0: {} - - resolve.exports@2.0.3: {} - - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - - reusify@1.1.0: {} - - rolldown-plugin-dts@0.20.0(oxc-resolver@11.16.3)(rolldown@1.0.0-beta.59)(typescript@5.9.3): - dependencies: - '@babel/generator': 7.29.1 - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - ast-kit: 2.2.0 - birpc: 4.0.0 - dts-resolver: 2.1.3(oxc-resolver@11.16.3) - get-tsconfig: 4.13.0 - obug: 2.1.1 - rolldown: 1.0.0-beta.59 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - oxc-resolver - - rolldown@1.0.0-beta.59: - dependencies: - '@oxc-project/types': 0.107.0 - '@rolldown/pluginutils': 1.0.0-beta.59 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-beta.59 - '@rolldown/binding-darwin-arm64': 1.0.0-beta.59 - '@rolldown/binding-darwin-x64': 1.0.0-beta.59 - '@rolldown/binding-freebsd-x64': 1.0.0-beta.59 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.59 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.59 - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.59 - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.59 - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.59 - '@rolldown/binding-openharmony-arm64': 1.0.0-beta.59 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.59 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.59 - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.59 - - rolldown@1.0.0-rc.3: - dependencies: - '@oxc-project/types': 0.112.0 - '@rolldown/pluginutils': 1.0.0-rc.3 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.3 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.3 - '@rolldown/binding-darwin-x64': 1.0.0-rc.3 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.3 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.3 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.3 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.3 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.3 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.3 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.3 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.3 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.3 - - rollup@4.55.1: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.55.1 - '@rollup/rollup-android-arm64': 4.55.1 - '@rollup/rollup-darwin-arm64': 4.55.1 - '@rollup/rollup-darwin-x64': 4.55.1 - '@rollup/rollup-freebsd-arm64': 4.55.1 - '@rollup/rollup-freebsd-x64': 4.55.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.55.1 - '@rollup/rollup-linux-arm-musleabihf': 4.55.1 - '@rollup/rollup-linux-arm64-gnu': 4.55.1 - '@rollup/rollup-linux-arm64-musl': 4.55.1 - '@rollup/rollup-linux-loong64-gnu': 4.55.1 - '@rollup/rollup-linux-loong64-musl': 4.55.1 - '@rollup/rollup-linux-ppc64-gnu': 4.55.1 - '@rollup/rollup-linux-ppc64-musl': 4.55.1 - '@rollup/rollup-linux-riscv64-gnu': 4.55.1 - '@rollup/rollup-linux-riscv64-musl': 4.55.1 - '@rollup/rollup-linux-s390x-gnu': 4.55.1 - '@rollup/rollup-linux-x64-gnu': 4.55.1 - '@rollup/rollup-linux-x64-musl': 4.55.1 - '@rollup/rollup-openbsd-x64': 4.55.1 - '@rollup/rollup-openharmony-arm64': 4.55.1 - '@rollup/rollup-win32-arm64-msvc': 4.55.1 - '@rollup/rollup-win32-ia32-msvc': 4.55.1 - '@rollup/rollup-win32-x64-gnu': 4.55.1 - '@rollup/rollup-win32-x64-msvc': 4.55.1 - fsevents: 2.3.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} - - semver@7.7.3: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - sherif-darwin-arm64@1.10.0: - optional: true - - sherif-darwin-x64@1.10.0: - optional: true - - sherif-linux-arm64-musl@1.10.0: - optional: true - - sherif-linux-arm64@1.10.0: - optional: true - - sherif-linux-x64-musl@1.10.0: - optional: true - - sherif-linux-x64@1.10.0: - optional: true - - sherif-windows-arm64@1.10.0: - optional: true - - sherif-windows-x64@1.10.0: - optional: true - - sherif@1.10.0: - optionalDependencies: - sherif-darwin-arm64: 1.10.0 - sherif-darwin-x64: 1.10.0 - sherif-linux-arm64: 1.10.0 - sherif-linux-arm64-musl: 1.10.0 - sherif-linux-x64: 1.10.0 - sherif-linux-x64-musl: 1.10.0 - sherif-windows-arm64: 1.10.0 - sherif-windows-x64: 1.10.0 - - siginfo@2.0.0: {} - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} - - slash@3.0.0: {} - - smol-toml@1.6.0: {} - - source-map-js@1.2.1: {} - - spawndamnit@3.0.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - sprintf-js@1.0.3: {} - - stable-hash-x@0.2.0: {} - - stackback@0.0.2: {} - - std-env@3.10.0: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-bom@3.0.0: {} - - strip-json-comments@3.1.1: {} - - strip-json-comments@5.0.3: {} - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - svelte@5.46.4: - dependencies: - '@jridgewell/remapping': 2.3.5 - '@jridgewell/sourcemap-codec': 1.5.5 - '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) - '@types/estree': 1.0.8 - acorn: 8.15.0 - aria-query: 5.3.2 - axobject-query: 4.1.0 - clsx: 2.1.1 - devalue: 5.6.2 - esm-env: 1.2.2 - esrap: 2.2.1 - is-reference: 3.0.3 - locate-character: 3.0.0 - magic-string: 0.30.21 - zimmerframe: 1.1.4 - - tapable@2.3.0: {} - - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.5 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - - term-size@2.2.1: {} - - tinybench@2.9.0: {} - - tinyexec@1.0.2: {} - - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - tinyrainbow@3.0.3: {} - - tmp@0.2.5: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - tr46@0.0.3: {} - - tree-kill@1.2.2: {} - - ts-api-utils@2.4.0(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - - ts-declaration-location@1.0.7(typescript@5.9.3): - dependencies: - picomatch: 4.0.3 - typescript: 5.9.3 - - tsconfig-paths@4.2.0: - dependencies: - json5: 2.2.3 - minimist: 1.2.8 - strip-bom: 3.0.0 - - tsdown@0.19.0(oxc-resolver@11.16.3)(typescript@5.9.3): - dependencies: - ansis: 4.2.0 - cac: 6.7.14 - defu: 6.1.4 - empathic: 2.0.0 - hookable: 6.0.1 - import-without-cache: 0.2.5 - obug: 2.1.1 - picomatch: 4.0.3 - rolldown: 1.0.0-beta.59 - rolldown-plugin-dts: 0.20.0(oxc-resolver@11.16.3)(rolldown@1.0.0-beta.59)(typescript@5.9.3) - semver: 7.7.3 - tinyexec: 1.0.2 - tinyglobby: 0.2.15 - tree-kill: 1.2.2 - unconfig-core: 7.5.0 - unrun: 0.2.27 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - '@ts-macro/tsc' - - '@typescript/native-preview' - - oxc-resolver - - synckit - - vue-tsc - - tslib@2.8.1: {} - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - typedoc-plugin-frontmatter@1.3.0(typedoc-plugin-markdown@4.9.0(typedoc@0.28.14(typescript@5.9.3))): - dependencies: - typedoc-plugin-markdown: 4.9.0(typedoc@0.28.14(typescript@5.9.3)) - yaml: 2.8.2 - - typedoc-plugin-markdown@4.9.0(typedoc@0.28.14(typescript@5.9.3)): - dependencies: - typedoc: 0.28.14(typescript@5.9.3) - - typedoc@0.28.14(typescript@5.9.3): - dependencies: - '@gerrit0/mini-shiki': 3.23.0 - lunr: 2.3.9 - markdown-it: 14.1.1 - minimatch: 9.0.5 - typescript: 5.9.3 - yaml: 2.8.2 - - typescript-eslint@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): - dependencies: - '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.39.2(jiti@2.6.1) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - typescript@5.9.3: {} - - uc.micro@2.1.0: {} - - unconfig-core@7.5.0: - dependencies: - '@quansync/fs': 1.0.0 - quansync: 1.0.0 - - undici-types@6.21.0: {} - - undici-types@7.16.0: {} - - undici@7.18.2: {} - - universalify@0.1.2: {} - - unrs-resolver@1.11.1: - dependencies: - napi-postinstall: 0.3.4 - optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.11.1 - '@unrs/resolver-binding-android-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-x64': 1.11.1 - '@unrs/resolver-binding-freebsd-x64': 1.11.1 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 - '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-musl': 1.11.1 - '@unrs/resolver-binding-wasm32-wasi': 1.11.1 - '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 - '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 - '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - - unrun@0.2.27: - dependencies: - rolldown: 1.0.0-rc.3 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - util-deprecate@1.0.2: {} - - vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2): - dependencies: - esbuild: 0.27.2 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.55.1 - tinyglobby: 0.2.15 - optionalDependencies: - '@types/node': 25.0.9 - fsevents: 2.3.3 - jiti: 2.6.1 - yaml: 2.8.2 - - vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(yaml@2.8.2): - dependencies: - '@vitest/expect': 4.0.17 - '@vitest/mocker': 4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2)) - '@vitest/pretty-format': 4.0.17 - '@vitest/runner': 4.0.17 - '@vitest/snapshot': 4.0.17 - '@vitest/spy': 4.0.17 - '@vitest/utils': 4.0.17 - es-module-lexer: 1.7.0 - expect-type: 1.3.0 - magic-string: 0.30.21 - obug: 2.1.1 - pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.10.0 - tinybench: 2.9.0 - tinyexec: 1.0.2 - tinyglobby: 0.2.15 - tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 25.0.9 - happy-dom: 20.3.1 - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - yaml - - vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@2.6.1)): - dependencies: - debug: 4.4.3 - eslint: 9.39.2(jiti@2.6.1) - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.7.0 - semver: 7.7.3 - transitivePeerDependencies: - - supports-color - - walk-up-path@4.0.0: {} - - wcwidth@1.0.1: - dependencies: - defaults: 1.0.4 - - webidl-conversions@3.0.1: {} - - whatwg-encoding@3.1.1: - dependencies: - iconv-lite: 0.6.3 - - whatwg-mimetype@3.0.0: {} - - whatwg-mimetype@4.0.0: {} - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - - word-wrap@1.2.5: {} - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrappy@1.0.2: {} - - ws@8.19.0: {} - - y18n@5.0.8: {} - - yaml@2.8.2: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yocto-queue@0.1.0: {} - - zimmerframe@1.1.4: {} - - zod@4.3.5: {} +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@tanstack/typedoc-config': + specifier: ^0.3.3 + version: 0.3.3(typescript@5.9.3) + devDependencies: + '@changesets/cli': + specifier: ^2.29.8 + version: 2.29.8(@types/node@25.0.9) + '@faker-js/faker': + specifier: ^10.2.0 + version: 10.2.0 + '@svitejs/changesets-changelog-github-compact': + specifier: ^1.2.0 + version: 1.2.0 + '@tanstack/eslint-config': + specifier: 0.3.4 + version: 0.3.4(@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@types/node': + specifier: ^25.0.7 + version: 25.0.9 + eslint: + specifier: ^9.39.2 + version: 9.39.2(jiti@2.6.1) + eslint-plugin-unused-imports: + specifier: ^4.3.0 + version: 4.3.0(@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) + happy-dom: + specifier: ^20.1.0 + version: 20.3.1 + knip: + specifier: ^5.80.2 + version: 5.81.0(@types/node@25.0.9)(typescript@5.9.3) + markdown-link-extractor: + specifier: ^4.0.3 + version: 4.0.3 + nx: + specifier: ^22.3.3 + version: 22.3.3 + prettier: + specifier: ^3.7.4 + version: 3.8.0 + prettier-plugin-svelte: + specifier: ^3.4.1 + version: 3.4.1(prettier@3.8.0)(svelte@5.46.4) + sherif: + specifier: ^1.9.0 + version: 1.10.0 + tinyglobby: + specifier: ^0.2.15 + version: 0.2.15 + typescript: + specifier: 5.9.3 + version: 5.9.3 + vitest: + specifier: ^4.0.17 + version: 4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(yaml@2.8.2) + yaml: + specifier: ^2.7.0 + version: 2.8.2 + + packages/intent: + dependencies: + yaml: + specifier: ^2.7.0 + version: 2.8.2 + devDependencies: + tsdown: + specifier: ^0.19.0 + version: 0.19.0(oxc-resolver@11.16.3)(typescript@5.9.3) + +packages: + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/runtime@7.28.6': + resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@changesets/apply-release-plan@7.0.14': + resolution: {integrity: sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==} + + '@changesets/assemble-release-plan@6.0.9': + resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} + + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + + '@changesets/cli@2.29.8': + resolution: {integrity: sha512-1weuGZpP63YWUYjay/E84qqwcnt5yJMM0tep10Up7Q5cS/DGe2IZ0Uj3HNMxGhCINZuR7aO9WBMdKnPit5ZDPA==} + hasBin: true + + '@changesets/config@3.1.2': + resolution: {integrity: sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.3': + resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} + + '@changesets/get-github-info@0.6.0': + resolution: {integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==} + + '@changesets/get-release-plan@4.0.14': + resolution: {integrity: sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.2': + resolution: {integrity: sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==} + + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + + '@changesets/read@0.6.6': + resolution: {integrity: sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==} + + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + + '@emnapi/core@1.8.1': + resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} + + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.3': + resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.2': + resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@faker-js/faker@10.2.0': + resolution: {integrity: sha512-rTXwAsIxpCqzUnZvrxVh3L0QA0NzToqWBLAhV+zDV3MIIwiQhAZHMdPCIaj5n/yADu/tyk12wIPgL6YHGXJP+g==} + engines: {node: ^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0, npm: '>=10'} + + '@gerrit0/mini-shiki@3.23.0': + resolution: {integrity: sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + + '@jest/diff-sequences@30.0.1': + resolution: {integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/get-type@30.1.0': + resolution: {integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/schemas@30.0.5': + resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@napi-rs/wasm-runtime@0.2.4': + resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nx/nx-darwin-arm64@22.3.3': + resolution: {integrity: sha512-zBAGFGLal09CxhQkdMpOVwcwa9Y01aFm88jTTn35s/DdIWsfngmPzz0t4mG7u2D05q7TJfGQ31pIf5GkNUjo6g==} + cpu: [arm64] + os: [darwin] + + '@nx/nx-darwin-x64@22.3.3': + resolution: {integrity: sha512-6ZQ6rMqH8NY4Jz+Gc89D5bIH2NxZb5S/vaA4yJ9RrqAfl4QWchNFD5na+aRivSd+UdsYLPKKl6qohet5SE6vOg==} + cpu: [x64] + os: [darwin] + + '@nx/nx-freebsd-x64@22.3.3': + resolution: {integrity: sha512-J/PP5pIOQtR7ZzrFwP6d6h0yfY7r9EravG2m940GsgzGbtZGYIDqnh5Wdt+4uBWPH8VpdNOwFqH0afELtJA3MA==} + cpu: [x64] + os: [freebsd] + + '@nx/nx-linux-arm-gnueabihf@22.3.3': + resolution: {integrity: sha512-/zn0altzM15S7qAgXMaB41vHkEn18HyTVUvRrjmmwaVqk9WfmDmqOQlGWoJ6XCbpvKQ8bh14RyhR9LGw1JJkNA==} + cpu: [arm] + os: [linux] + + '@nx/nx-linux-arm64-gnu@22.3.3': + resolution: {integrity: sha512-NmPeCexWIZHW9RM3lDdFENN9C3WtlQ5L4RSNFESIjreS921rgePhulsszYdGnHdcnKPYlBBJnX/NxVsfioBbnQ==} + cpu: [arm64] + os: [linux] + + '@nx/nx-linux-arm64-musl@22.3.3': + resolution: {integrity: sha512-K02U88Q0dpvCfmSXXvY7KbYQSa1m+mkYeqDBRHp11yHk1GoIqaHp8oEWda7FV4gsriNExPSS5tX1/QGVoLZrCw==} + cpu: [arm64] + os: [linux] + + '@nx/nx-linux-x64-gnu@22.3.3': + resolution: {integrity: sha512-04TEbvgwRaB9ifr39YwJmWh3RuXb4Ry4m84SOJyjNXAfPrepcWgfIQn1VL2ul1Ybq+P023dLO9ME8uqFh6j1YQ==} + cpu: [x64] + os: [linux] + + '@nx/nx-linux-x64-musl@22.3.3': + resolution: {integrity: sha512-uxBXx5q+S5OGatbYDxnamsKXRKlYn+Eq1nrCAHaf8rIfRoHlDiRV2PqtWuF+O2pxR5FWKpvr+/sZtt9rAf7KMw==} + cpu: [x64] + os: [linux] + + '@nx/nx-win32-arm64-msvc@22.3.3': + resolution: {integrity: sha512-aOwlfD6ZA1K6hjZtbhBSp7s1yi3sHbMpLCa4stXzfhCCpKUv46HU/EdiWdE1N8AsyNFemPZFq81k1VTowcACdg==} + cpu: [arm64] + os: [win32] + + '@nx/nx-win32-x64-msvc@22.3.3': + resolution: {integrity: sha512-EDR8BtqeDvVNQ+kPwnfeSfmerYetitU3tDkxOMIybjKJDh69U2JwTB8n9ARwNaZQbNk7sCGNRUSZFTbAAUKvuQ==} + cpu: [x64] + os: [win32] + + '@oxc-project/types@0.107.0': + resolution: {integrity: sha512-QFDRbYfV2LVx8tyqtyiah3jQPUj1mK2+RYwxyFWyGoys6XJnwTdlzO6rdNNHOPorHAu5Uo34oWRKcvNpbJarmQ==} + + '@oxc-project/types@0.112.0': + resolution: {integrity: sha512-m6RebKHIRsax2iCwVpYW2ErQwa4ywHJrE4sCK3/8JK8ZZAWOKXaRJFl/uP51gaVyyXlaS4+chU1nSCdzYf6QqQ==} + + '@oxc-resolver/binding-android-arm-eabi@11.16.3': + resolution: {integrity: sha512-CVyWHu6ACDqDcJxR4nmGiG8vDF4TISJHqRNzac5z/gPQycs/QrP/1pDsJBy0MD7jSw8nVq2E5WqeHQKabBG/Jg==} + cpu: [arm] + os: [android] + + '@oxc-resolver/binding-android-arm64@11.16.3': + resolution: {integrity: sha512-tTIoB7plLeh2o6Ay7NnV5CJb6QUXdxI7Shnsp2ECrLSV81k+oVE3WXYrQSh4ltWL75i0OgU5Bj3bsuyg5SMepw==} + cpu: [arm64] + os: [android] + + '@oxc-resolver/binding-darwin-arm64@11.16.3': + resolution: {integrity: sha512-OXKVH7uwYd3Rbw1s2yJZd6/w+6b01iaokZubYhDAq4tOYArr+YCS+lr81q1hsTPPRZeIsWE+rJLulmf1qHdYZA==} + cpu: [arm64] + os: [darwin] + + '@oxc-resolver/binding-darwin-x64@11.16.3': + resolution: {integrity: sha512-WwjQ4WdnCxVYZYd3e3oY5XbV3JeLy9pPMK+eQQ2m8DtqUtbxnvPpAYC2Knv/2bS6q5JiktqOVJ2Hfia3OSo0/A==} + cpu: [x64] + os: [darwin] + + '@oxc-resolver/binding-freebsd-x64@11.16.3': + resolution: {integrity: sha512-4OHKFGJBBfOnuJnelbCS4eBorI6cj54FUxcZJwEXPeoLc8yzORBoJ2w+fQbwjlQcUUZLEg92uGhKCRiUoqznjg==} + cpu: [x64] + os: [freebsd] + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.3': + resolution: {integrity: sha512-OM3W0NLt9u7uKwG/yZbeXABansZC0oZeDF1nKgvcZoRw4/Yak6/l4S0onBfDFeYMY94eYeAt2bl60e30lgsb5A==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm-musleabihf@11.16.3': + resolution: {integrity: sha512-MRs7D7i1t7ACsAdTuP81gLZES918EpBmiUyEl8fu302yQB+4L7L7z0Ui8BWnthUTQd3nAU9dXvENLK/SqRVH8A==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm64-gnu@11.16.3': + resolution: {integrity: sha512-0eVYZxSceNqGADzhlV4ZRqkHF0fjWxRXQOB7Qwl5y1gN/XYUDvMfip+ngtzj4dM7zQT4U97hUhJ7PUKSy/JIGQ==} + cpu: [arm64] + os: [linux] + + '@oxc-resolver/binding-linux-arm64-musl@11.16.3': + resolution: {integrity: sha512-B1BvLeZbgDdVN0FvU40l5Q7lej8310WlabCBaouk8jY7H7xbI8phtomTtk3Efmevgfy5hImaQJu6++OmcFb2NQ==} + cpu: [arm64] + os: [linux] + + '@oxc-resolver/binding-linux-ppc64-gnu@11.16.3': + resolution: {integrity: sha512-q7khglic3Jqak7uDgA3MFnjDeI7krQT595GDZpvFq785fmFYSx8rlTkoHzmhQtUisYtl4XG7WUscwsoidFUI4w==} + cpu: [ppc64] + os: [linux] + + '@oxc-resolver/binding-linux-riscv64-gnu@11.16.3': + resolution: {integrity: sha512-aFRNmQNPzDgQEbw2s3c8yJYRimacSDI+u9df8rn5nSKzTVitHmbEpZqfxpwNLCKIuLSNmozHR1z1OT+oZVeYqg==} + cpu: [riscv64] + os: [linux] + + '@oxc-resolver/binding-linux-riscv64-musl@11.16.3': + resolution: {integrity: sha512-vZI85SvSMADcEL9G1TIrV0Rlkc1fY5Mup0DdlVC5EHPysZB4hXXHpr+h09pjlK5y+5om5foIzDRxE1baUCaWOA==} + cpu: [riscv64] + os: [linux] + + '@oxc-resolver/binding-linux-s390x-gnu@11.16.3': + resolution: {integrity: sha512-xiLBnaUlddFEzRHiHiSGEMbkg8EwZY6VD8F+3GfnFsiK3xg/4boaUV2bwXd+nUzl3UDQOMW1QcZJ4jJSb0qiJA==} + cpu: [s390x] + os: [linux] + + '@oxc-resolver/binding-linux-x64-gnu@11.16.3': + resolution: {integrity: sha512-6y0b05wIazJJgwu7yU/AYGFswzQQudYJBOb/otDhiDacp1+6ye8egoxx63iVo9lSpDbipL++54AJQFlcOHCB+g==} + cpu: [x64] + os: [linux] + + '@oxc-resolver/binding-linux-x64-musl@11.16.3': + resolution: {integrity: sha512-RmMgwuMa42c9logS7Pjprf5KCp8J1a1bFiuBFtG9/+yMu0BhY2t+0VR/um7pwtkNFvIQqAVh6gDOg/PnoKRcdQ==} + cpu: [x64] + os: [linux] + + '@oxc-resolver/binding-openharmony-arm64@11.16.3': + resolution: {integrity: sha512-/7AYRkjjW7xu1nrHgWUFy99Duj4/ydOBVaHtODie9/M6fFngo+8uQDFFnzmr4q//sd/cchIerISp/8CQ5TsqIA==} + cpu: [arm64] + os: [openharmony] + + '@oxc-resolver/binding-wasm32-wasi@11.16.3': + resolution: {integrity: sha512-urM6aIPbi5di4BSlnpd/TWtDJgG6RD06HvLBuNM+qOYuFtY1/xPbzQ2LanBI2ycpqIoIZwsChyplALwAMdyfCQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-resolver/binding-win32-arm64-msvc@11.16.3': + resolution: {integrity: sha512-QuvLqGKf7frxWHQ5TnrcY0C/hJpANsaez99Q4dAk1hen7lDTD4FBPtBzPnntLFXeaVG3PnSmnVjlv0vMILwU7Q==} + cpu: [arm64] + os: [win32] + + '@oxc-resolver/binding-win32-ia32-msvc@11.16.3': + resolution: {integrity: sha512-QR/witXK6BmYTlEP8CCjC5fxeG5U9A6a50pNpC1nLnhAcJjtzFG8KcQ5etVy/XvCLiDc7fReaAWRNWtCaIhM8Q==} + cpu: [ia32] + os: [win32] + + '@oxc-resolver/binding-win32-x64-msvc@11.16.3': + resolution: {integrity: sha512-bFuJRKOscsDAEZ/a8BezcTMAe2BQ/OBRfuMLFUuINfTR5qGVcm4a3xBIrQVepBaPxFj16SJdRjGe05vDiwZmFw==} + cpu: [x64] + os: [win32] + + '@quansync/fs@1.0.0': + resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} + + '@rolldown/binding-android-arm64@1.0.0-beta.59': + resolution: {integrity: sha512-6yLLgyswYwiCfls9+hoNFY9F8TQdwo15hpXDHzlAR0X/GojeKF+AuNcXjYNbOJ4zjl/5D6lliE8CbpB5t1OWIQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-android-arm64@1.0.0-rc.3': + resolution: {integrity: sha512-0T1k9FinuBZ/t7rZ8jN6OpUKPnUjNdYHoj/cESWrQ3ZraAJ4OMm6z7QjSfCxqj8mOp9kTKc1zHK3kGz5vMu+nQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-beta.59': + resolution: {integrity: sha512-hqGXRc162qCCIOAcHN2Cw4eXiVTwYsMFLOhAy1IG2CxY+dwc/l4Ga+dLPkLor3Ikqy5WDn+7kxHbbh6EmshEpQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-arm64@1.0.0-rc.3': + resolution: {integrity: sha512-JWWLzvcmc/3pe7qdJqPpuPk91SoE/N+f3PcWx/6ZwuyDVyungAEJPvKm/eEldiDdwTmaEzWfIR+HORxYWrCi1A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-beta.59': + resolution: {integrity: sha512-ezvvGuhteE15JmMhJW0wS7BaXmhwLy1YHeEwievYaPC1PgGD86wgBKfOpHr9tSKllAXbCe0BeeMvasscWLhKdA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-rc.3': + resolution: {integrity: sha512-MTakBxfx3tde5WSmbHxuqlDsIW0EzQym+PJYGF4P6lG2NmKzi128OGynoFUqoD5ryCySEY85dug4v+LWGBElIw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-beta.59': + resolution: {integrity: sha512-4fhKVJiEYVd5n6no/mrL3LZ9kByfCGwmONOrdtvx8DJGDQhehH/q3RfhG3V/4jGKhpXgbDjpIjkkFdybCTcgew==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-freebsd-x64@1.0.0-rc.3': + resolution: {integrity: sha512-jje3oopyOLs7IwfvXoS6Lxnmie5JJO7vW29fdGFu5YGY1EDbVDhD+P9vDihqS5X6fFiqL3ZQZCMBg6jyHkSVww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.59': + resolution: {integrity: sha512-T3Y52sW6JAhvIqArBw+wtjNU1Ieaz4g0NBxyjSJoW971nZJBZygNlSYx78G4cwkCmo1dYTciTPDOnQygLV23pA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3': + resolution: {integrity: sha512-A0n8P3hdLAaqzSFrQoA42p23ZKBYQOw+8EH5r15Sa9X1kD9/JXe0YT2gph2QTWvdr0CVK2BOXiK6ENfy6DXOag==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.59': + resolution: {integrity: sha512-NIW40jQDSQap2KDdmm9z3B/4OzWJ6trf8dwx3FD74kcQb3v34ThsBFTtzE5KjDuxnxgUlV+DkAu+XgSMKrgufw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3': + resolution: {integrity: sha512-kWXkoxxarYISBJ4bLNf5vFkEbb4JvccOwxWDxuK9yee8lg5XA7OpvlTptfRuwEvYcOZf+7VS69Uenpmpyo5Bjw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.59': + resolution: {integrity: sha512-CCKEk+H+8c0WGe/8n1E20n85Tq4Pv+HNAbjP1KfUXW+01aCWSMjU56ChNrM2tvHnXicfm7QRNoZyfY8cWh7jLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.3': + resolution: {integrity: sha512-Z03/wrqau9Bicfgb3Dbs6SYTHliELk2PM2LpG2nFd+cGupTMF5kanLEcj2vuuJLLhptNyS61rtk7SOZ+lPsTUA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.59': + resolution: {integrity: sha512-VlfwJ/HCskPmQi8R0JuAFndySKVFX7yPhE658o27cjSDWWbXVtGkSbwaxstii7Q+3Rz87ZXN+HLnb1kd4R9Img==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.3': + resolution: {integrity: sha512-iSXXZsQp08CSilff/DCTFZHSVEpEwdicV3W8idHyrByrcsRDVh9sGC3sev6d8BygSGj3vt8GvUKBPCoyMA4tgQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.59': + resolution: {integrity: sha512-kuO92hTRyGy0Ts3Nsqll0rfO8eFsEJe9dGQGktkQnZ2hrJrDVN0y419dMgKy/gB2S2o7F2dpWhpfQOBehZPwVA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.3': + resolution: {integrity: sha512-qaj+MFudtdCv9xZo9znFvkgoajLdc+vwf0Kz5N44g+LU5XMe+IsACgn3UG7uTRlCCvhMAGXm1XlpEA5bZBrOcw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.59': + resolution: {integrity: sha512-PXAebvNL4sYfCqi8LdY4qyFRacrRoiPZLo3NoUmiTxm7MPtYYR8CNtBGNokqDmMuZIQIecRaD/jbmFAIDz7DxQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.3': + resolution: {integrity: sha512-U662UnMETyjT65gFmG9ma+XziENrs7BBnENi/27swZPYagubfHRirXHG2oMl+pEax2WvO7Kb9gHZmMakpYqBHQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.59': + resolution: {integrity: sha512-yJoklQg7XIZq8nAg0bbkEXcDK6sfpjxQGxpg2Nd6ERNtvg+eOaEBRgPww0BVTrYFQzje1pB5qPwC2VnJHT3koQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.3': + resolution: {integrity: sha512-gekrQ3Q2HiC1T5njGyuUJoGpK/l6B/TNXKed3fZXNf9YRTJn3L5MOZsFBn4bN2+UX+8+7hgdlTcEsexX988G4g==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.59': + resolution: {integrity: sha512-ljZ4+McmCbIuZwEBaoGtiG8Rq2nJjaXEnLEIx+usWetXn1ECjXY0LAhkELxOV6ytv4ensEmoJJ8nXg47hRMjlw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3': + resolution: {integrity: sha512-85y5JifyMgs8m5K2XzR/VDsapKbiFiohl7s5lEj7nmNGO0pkTXE7q6TQScei96BNAsoK7JC3pA7ukA8WRHVJpg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.59': + resolution: {integrity: sha512-bMY4tTIwbdZljW+xe/ln1hvs0SRitahQSXfWtvgAtIzgSX9Ar7KqJzU7lRm33YTRFIHLULRi53yNjw9nJGd6uQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.3': + resolution: {integrity: sha512-a4VUQZH7LxGbUJ3qJ/TzQG8HxdHvf+jOnqf7B7oFx1TEBm+j2KNL2zr5SQ7wHkNAcaPevF6gf9tQnVBnC4mD+A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.59': + resolution: {integrity: sha512-aoh6LAJRyhtazs98ydgpNOYstxUlsOV1KJXcpf/0c0vFcUA8uyd/hwKRhqE/AAPNqAho9RliGsvitCoOzREoVA==} + + '@rolldown/pluginutils@1.0.0-rc.3': + resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} + + '@rollup/rollup-android-arm-eabi@4.55.1': + resolution: {integrity: sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.55.1': + resolution: {integrity: sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.55.1': + resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.55.1': + resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.55.1': + resolution: {integrity: sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.55.1': + resolution: {integrity: sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.55.1': + resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.55.1': + resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.55.1': + resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.55.1': + resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.55.1': + resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.55.1': + resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.55.1': + resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.55.1': + resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.55.1': + resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.55.1': + resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.55.1': + resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.55.1': + resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.55.1': + resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.55.1': + resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.55.1': + resolution: {integrity: sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.55.1': + resolution: {integrity: sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.55.1': + resolution: {integrity: sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.55.1': + resolution: {integrity: sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.55.1': + resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==} + cpu: [x64] + os: [win32] + + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} + + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} + + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} + + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@sinclair/typebox@0.34.47': + resolution: {integrity: sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@stylistic/eslint-plugin@5.7.0': + resolution: {integrity: sha512-PsSugIf9ip1H/mWKj4bi/BlEoerxXAda9ByRFsYuwsmr6af9NxJL0AaiNXs8Le7R21QR5KMiD/KdxZZ71LjAxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=9.0.0' + + '@sveltejs/acorn-typescript@1.0.8': + resolution: {integrity: sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA==} + peerDependencies: + acorn: ^8.9.0 + + '@svitejs/changesets-changelog-github-compact@1.2.0': + resolution: {integrity: sha512-08eKiDAjj4zLug1taXSIJ0kGL5cawjVCyJkBb6EWSg5fEPX6L+Wtr0CH2If4j5KYylz85iaZiFlUItvgJvll5g==} + engines: {node: ^14.13.1 || ^16.0.0 || >=18} + + '@tanstack/eslint-config@0.3.4': + resolution: {integrity: sha512-5Ou1XWJRCTx5G8WoCbT7+6nQ4iNdsISzBAc4lXpFy2fEOO7xioOSPvcPIv+r9V0drPPETou2tr6oLGZZ909FKg==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^8.0.0 || ^9.0.0 + + '@tanstack/typedoc-config@0.3.3': + resolution: {integrity: sha512-wVT2YfKDSpd+4f7fk6UaPIP3a2J7LSovlyVuFF1PH2yQb7gjqehod5zdFiwFyEXgvI9XGuFvvs1OehkKNYcr6A==} + engines: {node: '>=18'} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@20.19.30': + resolution: {integrity: sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==} + + '@types/node@25.0.9': + resolution: {integrity: sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@typescript-eslint/eslint-plugin@8.53.0': + resolution: {integrity: sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.53.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.53.0': + resolution: {integrity: sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.53.0': + resolution: {integrity: sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.53.0': + resolution: {integrity: sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.53.0': + resolution: {integrity: sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.53.0': + resolution: {integrity: sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.53.0': + resolution: {integrity: sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.53.0': + resolution: {integrity: sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.53.0': + resolution: {integrity: sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.53.0': + resolution: {integrity: sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + + '@vitest/expect@4.0.17': + resolution: {integrity: sha512-mEoqP3RqhKlbmUmntNDDCJeTDavDR+fVYkSOw8qRwJFaW/0/5zA9zFeTrHqNtcmwh6j26yMmwx2PqUDPzt5ZAQ==} + + '@vitest/mocker@4.0.17': + resolution: {integrity: sha512-+ZtQhLA3lDh1tI2wxe3yMsGzbp7uuJSWBM1iTIKCbppWTSBN09PUC+L+fyNlQApQoR+Ps8twt2pbSSXg2fQVEQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.0.17': + resolution: {integrity: sha512-Ah3VAYmjcEdHg6+MwFE17qyLqBHZ+ni2ScKCiW2XrlSBV4H3Z7vYfPfz7CWQ33gyu76oc0Ai36+kgLU3rfF4nw==} + + '@vitest/runner@4.0.17': + resolution: {integrity: sha512-JmuQyf8aMWoo/LmNFppdpkfRVHJcsgzkbCA+/Bk7VfNH7RE6Ut2qxegeyx2j3ojtJtKIbIGy3h+KxGfYfk28YQ==} + + '@vitest/snapshot@4.0.17': + resolution: {integrity: sha512-npPelD7oyL+YQM2gbIYvlavlMVWUfNNGZPcu0aEUQXt7FXTuqhmgiYupPnAanhKvyP6Srs2pIbWo30K0RbDtRQ==} + + '@vitest/spy@4.0.17': + resolution: {integrity: sha512-I1bQo8QaP6tZlTomQNWKJE6ym4SHf3oLS7ceNjozxxgzavRAgZDc06T7kD8gb9bXKEgcLNt00Z+kZO6KaJ62Ew==} + + '@vitest/utils@4.0.17': + resolution: {integrity: sha512-RG6iy+IzQpa9SB8HAFHJ9Y+pTzI+h8553MrciN9eC6TFBErqrQaTas4vG+MVj8S4uKk8uTT2p0vgZPnTdxd96w==} + + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + + '@yarnpkg/parsers@3.0.2': + resolution: {integrity: sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA==} + engines: {node: '>=18.12.0'} + + '@zkochan/js-yaml@0.0.7': + resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} + hasBin: true + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-kit@2.2.0: + resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} + engines: {node: '>=20.19.0'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.13.2: + resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + birpc@4.0.0: + resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.1.2: + resolution: {integrity: sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==} + engines: {node: '>=20.18.1'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-spinners@2.6.1: + resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} + engines: {node: '>=6'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + comment-parser@1.4.4: + resolution: {integrity: sha512-0D6qSQ5IkeRrGJFHRClzaMOenMeT0gErz3zIw3AprKMqhRN6LNU2jQOdkPG/FZ+8bCgXE1VidrgSzlBBDZRr8A==} + engines: {node: '>= 12.0.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + dataloader@1.4.0: + resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + devalue@5.6.2: + resolution: {integrity: sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dotenv-expand@11.0.7: + resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} + engines: {node: '>=12'} + + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dts-resolver@2.1.3: + resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==} + engines: {node: '>=20.19.0'} + peerDependencies: + oxc-resolver: '>=11.0.0' + peerDependenciesMeta: + oxc-resolver: + optional: true + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + enhanced-resolve@5.18.4: + resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + engines: {node: '>=10.13.0'} + + enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-compat-utils@0.5.1: + resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + + eslint-import-context@0.1.9: + resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + + eslint-plugin-es-x@7.8.0: + resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + + eslint-plugin-import-x@4.16.1: + resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/utils': ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + eslint-import-resolver-node: '*' + peerDependenciesMeta: + '@typescript-eslint/utils': + optional: true + eslint-import-resolver-node: + optional: true + + eslint-plugin-n@17.23.2: + resolution: {integrity: sha512-RhWBeb7YVPmNa2eggvJooiuehdL76/bbfj/OJewyoGT80qn5PXdz8zMOTO6YHOsI7byPt7+Ighh/i/4a5/v7hw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.23.0' + + eslint-plugin-unused-imports@4.3.0: + resolution: {integrity: sha512-ZFBmXMGBYfHttdRtOG9nFFpmUvMtbHSjsKrS20vdWdbfiVYsO3yA2SGYy9i9XmZJDfMGBflZGBCm70SEnFQtOA==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 + eslint: ^9.0.0 || ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.0: + resolution: {integrity: sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.2: + resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@11.0.0: + resolution: {integrity: sha512-+gMeWRrIh/NsG+3NaLeWHuyeyk70p2tbvZIWBYcqQ4/7Xvars6GYTZNhF1sIeLcc6Wb11He5ffz3hsHyXFrw5A==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrap@2.2.1: + resolution: {integrity: sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fd-package-json@2.0.0: + resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + formatly@0.3.0: + resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==} + engines: {node: '>=18.3.0'} + hasBin: true + + front-matter@4.0.2: + resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} + engines: {node: '>=18'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + happy-dom@20.3.1: + resolution: {integrity: sha512-tLvsizNno05Hij0PoB0QN/S8xf0YU2AGvO11/JlJDw5McA/gzyn0Ni1RwbTI1/zteUbOekJH0t6q8HFvjbxsGg==} + engines: {node: '>=20.0.0'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hookable@6.0.1: + resolution: {integrity: sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==} + + html-link-extractor@1.0.5: + resolution: {integrity: sha512-ADd49pudM157uWHwHQPUSX4ssMsvR/yHIswOR5CUfBdK9g9ZYGMhVSE6KZVHJ6kCkR0gH4htsfzU6zECDNVwyw==} + + htmlparser2@10.0.0: + resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} + + human-id@4.1.3: + resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} + hasBin: true + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-without-cache@0.2.5: + resolution: {integrity: sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A==} + engines: {node: '>=20.19.0'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jest-diff@30.2.0: + resolution: {integrity: sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + knip@5.81.0: + resolution: {integrity: sha512-EM9YdNg6zU2DWMJuc9zD8kPUpj0wvPspa63Qe9DPGygzL956uYThfoUQk5aNpPmMr9hs/k+Xm7FLuWFKERFkrQ==} + engines: {node: '>=18.18.0'} + hasBin: true + peerDependencies: + '@types/node': '>=18' + typescript: '>=5.0.4 <7' + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lines-and-columns@2.0.3: + resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + markdown-it@14.1.1: + resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} + hasBin: true + + markdown-link-extractor@4.0.3: + resolution: {integrity: sha512-aEltJiQ4/oC0h6Jbw/uuATGSHZPkcH8DIunNH1A0e+GSFkvZ6BbBkdvBTVfIV8r6HapCU3yTd0eFdi3ZeM1eAQ==} + + marked@17.0.1: + resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==} + engines: {node: '>= 20'} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-machine-id@1.1.12: + resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nx@22.3.3: + resolution: {integrity: sha512-pOxtKWUfvf0oD8Geqs8D89Q2xpstRTaSY+F6Ut/Wd0GnEjUjO32SS1ymAM6WggGPHDZN4qpNrd5cfIxQmAbRLg==} + hasBin: true + peerDependencies: + '@swc-node/register': ^1.8.0 + '@swc/core': ^1.3.85 + peerDependenciesMeta: + '@swc-node/register': + optional: true + '@swc/core': + optional: true + + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@5.3.0: + resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} + engines: {node: '>=10'} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + oxc-resolver@11.16.3: + resolution: {integrity: sha512-goLOJH3x69VouGWGp5CgCIHyksmOZzXr36lsRmQz1APg3SPFORrvV2q7nsUHMzLVa6ZJgNwkgUSJFsbCpAWkCA==} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-plugin-svelte@3.4.1: + resolution: {integrity: sha512-xL49LCloMoZRvSwa6IEdN2GV6cq2IqpYGstYtMT+5wmml1/dClEoI0MZR78MiVPpu6BdQFfN0/y73yO6+br5Pg==} + peerDependencies: + prettier: ^3.0.0 + svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@3.8.0: + resolution: {integrity: sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@30.2.0: + resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + quansync@1.0.0: + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rolldown-plugin-dts@0.20.0: + resolution: {integrity: sha512-cLAY1kN2ilTYMfZcFlGWbXnu6Nb+8uwUBsi+Mjbh4uIx7IN8uMOmJ7RxrrRgPsO4H7eSz3E+JwGoL1gyugiyUA==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@ts-macro/tsc': ^0.3.6 + '@typescript/native-preview': '>=7.0.0-dev.20250601.1' + rolldown: ^1.0.0-beta.57 + typescript: ^5.0.0 + vue-tsc: ~3.2.0 + peerDependenciesMeta: + '@ts-macro/tsc': + optional: true + '@typescript/native-preview': + optional: true + typescript: + optional: true + vue-tsc: + optional: true + + rolldown@1.0.0-beta.59: + resolution: {integrity: sha512-Slm000Gd8/AO9z4Kxl4r8mp/iakrbAuJ1L+7ddpkNxgQ+Vf37WPvY63l3oeyZcfuPD1DRrUYBsRPIXSOhvOsmw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rolldown@1.0.0-rc.3: + resolution: {integrity: sha512-Po/YZECDOqVXjIXrtC5h++a5NLvKAQNrd9ggrIG3sbDfGO5BqTUsrI6l8zdniKRp3r5Tp/2JTrXqx4GIguFCMw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rollup@4.55.1: + resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + sherif-darwin-arm64@1.10.0: + resolution: {integrity: sha512-fHRg/fgyxHebCH9vuGEhImyGqmwlBq67BVyI8Ugda8GM+W+Ofj1cQnzDX82cYuCHU+KJ7hQFq8iPHkRizXWOrA==} + cpu: [arm64] + os: [darwin] + + sherif-darwin-x64@1.10.0: + resolution: {integrity: sha512-7rhayQ+jlIj3SscnHMi6JVCYR9od/HiqIGIBgOQeux31YRzc/XvfKjE9X+FrCRU+72qz7sqw5ZY7jl7bRxbOUg==} + cpu: [x64] + os: [darwin] + + sherif-linux-arm64-musl@1.10.0: + resolution: {integrity: sha512-TsaQSefkaIJ+oFGGaaPm5BzrjVRnvcquh4q3/e5LB6JdhPTveNPo3o2Pzmq6sKry9dzk3p7sKtzJpLz4q5V/+Q==} + cpu: [arm64] + os: [linux] + + sherif-linux-arm64@1.10.0: + resolution: {integrity: sha512-QtEju3eLPpEb7hv9QRVdsi2J3bhIFEBbRk0vjdnAEKyRb3q9MjyqEhps69JgaCv8olEiBjGcU1hGP7vl5QVG4A==} + cpu: [arm64] + os: [linux] + + sherif-linux-x64-musl@1.10.0: + resolution: {integrity: sha512-iSYRYEFE0xfOJVwPjsUN4o8CoNSEyxJHsSliBDxfEZQubN0rmE9f1hs83HPPAkEozGestI7PxKFKcyTgTxEoXg==} + cpu: [x64] + os: [linux] + + sherif-linux-x64@1.10.0: + resolution: {integrity: sha512-/1ydjgJxXbqnGWViAENHxlX9lEDhATO99qtFcMseUFkPpEAxQ9qFctWf3OB2rciPlHLuPzhphkJAt7ZkX1R5eA==} + cpu: [x64] + os: [linux] + + sherif-windows-arm64@1.10.0: + resolution: {integrity: sha512-CBNys+m7TsWD/1/5WQRJCNjfm08VhmBP9JSmecoHCsfDF+o0vt52NDrzVOOeai/c/yYunCBvAAx9EIFXBmgpHw==} + cpu: [arm64] + os: [win32] + + sherif-windows-x64@1.10.0: + resolution: {integrity: sha512-XRN4SuZQud0X4UKZZxLe4IyVkbo9qa8rvmFhgCoULaRScucNdJJ4r6hnjZ7DR0spl7zSPJNZUNcgnnJmxWfs1Q==} + cpu: [x64] + os: [win32] + + sherif@1.10.0: + resolution: {integrity: sha512-DHg6+Pj7ORhYyC+CaSAr8DeRxqf9GXB90yqLmUILPtY7WhZuJatMir3id2MNjuF5I/1313SbrTTItIDu//G4jg==} + hasBin: true + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + smol-toml@1.6.0: + resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} + engines: {node: '>= 18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stable-hash-x@0.2.0: + resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} + engines: {node: '>=12.0.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + svelte@5.46.4: + resolution: {integrity: sha512-VJwdXrmv9L8L7ZasJeWcCjoIuMRVbhuxbss0fpVnR8yorMmjNDwcjIH08vS6wmSzzzgAG5CADQ1JuXPS2nwt9w==} + engines: {node: '>=18'} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-declaration-location@1.0.7: + resolution: {integrity: sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==} + peerDependencies: + typescript: '>=4.0.0' + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tsdown@0.19.0: + resolution: {integrity: sha512-uqg8yzlS7GemFWcM6aCp/sptF4bJiJbWUibuHTRLLCBEsGCgJxuqxPhuVTqyHXqoEkh9ohwAdlyDKli5MEWCyQ==} + engines: {node: '>=20.19.0'} + hasBin: true + peerDependencies: + '@arethetypeswrong/core': ^0.18.1 + '@vitejs/devtools': '*' + publint: ^0.3.0 + typescript: ^5.0.0 + unplugin-lightningcss: ^0.4.0 + unplugin-unused: ^0.5.0 + peerDependenciesMeta: + '@arethetypeswrong/core': + optional: true + '@vitejs/devtools': + optional: true + publint: + optional: true + typescript: + optional: true + unplugin-lightningcss: + optional: true + unplugin-unused: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typedoc-plugin-frontmatter@1.3.0: + resolution: {integrity: sha512-xYQFMAecMlsRUjmf9oM/Sq2FVz4zlgcbIeVFNLdO118CHTN06gIKJNSlyExh9+Xl8sK0YhIvoQwViUURxritWA==} + peerDependencies: + typedoc-plugin-markdown: '>=4.5.0' + + typedoc-plugin-markdown@4.9.0: + resolution: {integrity: sha512-9Uu4WR9L7ZBgAl60N/h+jqmPxxvnC9nQAlnnO/OujtG2ubjnKTVUFY1XDhcMY+pCqlX3N2HsQM2QTYZIU9tJuw==} + engines: {node: '>= 18'} + peerDependencies: + typedoc: 0.28.x + + typedoc@0.28.14: + resolution: {integrity: sha512-ftJYPvpVfQvFzpkoSfHLkJybdA/geDJ8BGQt/ZnkkhnBYoYW6lBgPQXu6vqLxO4X75dA55hX8Af847H5KXlEFA==} + engines: {node: '>= 18', pnpm: '>= 10'} + hasBin: true + peerDependencies: + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x + + typescript-eslint@8.53.0: + resolution: {integrity: sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + unconfig-core@7.5.0: + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + undici@7.18.2: + resolution: {integrity: sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==} + engines: {node: '>=20.18.1'} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + unrun@0.2.27: + resolution: {integrity: sha512-Mmur1UJpIbfxasLOhPRvox/QS4xBiDii71hMP7smfRthGcwFL2OAmYRgduLANOAU4LUkvVamuP+02U+c90jlrw==} + engines: {node: '>=20.19.0'} + hasBin: true + peerDependencies: + synckit: ^0.11.11 + peerDependenciesMeta: + synckit: + optional: true + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.0.17: + resolution: {integrity: sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.17 + '@vitest/browser-preview': 4.0.17 + '@vitest/browser-webdriverio': 4.0.17 + '@vitest/ui': 4.0.17 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vue-eslint-parser@10.2.0: + resolution: {integrity: sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + walk-up-path@4.0.0: + resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} + engines: {node: 20 || >=22} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + + zod@4.3.5: + resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} + +snapshots: + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.29.0': + dependencies: + '@babel/types': 7.29.0 + + '@babel/runtime@7.28.6': {} + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@changesets/apply-release-plan@7.0.14': + dependencies: + '@changesets/config': 3.1.2 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.3 + + '@changesets/assemble-release-plan@6.0.9': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.3 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/cli@2.29.8(@types/node@25.0.9)': + dependencies: + '@changesets/apply-release-plan': 7.0.14 + '@changesets/assemble-release-plan': 6.0.9 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.2 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/get-release-plan': 4.0.14 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.6 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3(@types/node@25.0.9) + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + ci-info: 3.9.0 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + p-limit: 2.3.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.7.3 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' + + '@changesets/config@3.1.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/logger': 0.1.1 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.3': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.7.3 + + '@changesets/get-github-info@0.6.0': + dependencies: + dataloader: 1.4.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + '@changesets/get-release-plan@4.0.14': + dependencies: + '@changesets/assemble-release-plan': 6.0.9 + '@changesets/config': 3.1.2 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.6 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.2': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 4.1.1 + + '@changesets/pre@2.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.6': + dependencies: + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.2 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.1.0': {} + + '@changesets/write@0.4.0': + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.1.3 + prettier: 2.8.8 + + '@emnapi/core@1.8.1': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + + '@emnapi/runtime@1.8.1': + dependencies: + tslib: 2.8.1 + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + + '@esbuild/aix-ppc64@0.27.2': + optional: true + + '@esbuild/android-arm64@0.27.2': + optional: true + + '@esbuild/android-arm@0.27.2': + optional: true + + '@esbuild/android-x64@0.27.2': + optional: true + + '@esbuild/darwin-arm64@0.27.2': + optional: true + + '@esbuild/darwin-x64@0.27.2': + optional: true + + '@esbuild/freebsd-arm64@0.27.2': + optional: true + + '@esbuild/freebsd-x64@0.27.2': + optional: true + + '@esbuild/linux-arm64@0.27.2': + optional: true + + '@esbuild/linux-arm@0.27.2': + optional: true + + '@esbuild/linux-ia32@0.27.2': + optional: true + + '@esbuild/linux-loong64@0.27.2': + optional: true + + '@esbuild/linux-mips64el@0.27.2': + optional: true + + '@esbuild/linux-ppc64@0.27.2': + optional: true + + '@esbuild/linux-riscv64@0.27.2': + optional: true + + '@esbuild/linux-s390x@0.27.2': + optional: true + + '@esbuild/linux-x64@0.27.2': + optional: true + + '@esbuild/netbsd-arm64@0.27.2': + optional: true + + '@esbuild/netbsd-x64@0.27.2': + optional: true + + '@esbuild/openbsd-arm64@0.27.2': + optional: true + + '@esbuild/openbsd-x64@0.27.2': + optional: true + + '@esbuild/openharmony-arm64@0.27.2': + optional: true + + '@esbuild/sunos-x64@0.27.2': + optional: true + + '@esbuild/win32-arm64@0.27.2': + optional: true + + '@esbuild/win32-ia32@0.27.2': + optional: true + + '@esbuild/win32-x64@0.27.2': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2(jiti@2.6.1))': + dependencies: + eslint: 9.39.2(jiti@2.6.1) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.1': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.3': + dependencies: + ajv: 6.12.6 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.2': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@faker-js/faker@10.2.0': {} + + '@gerrit0/mini-shiki@3.23.0': + dependencies: + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@inquirer/external-editor@1.0.3(@types/node@25.0.9)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 25.0.9 + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + + '@jest/diff-sequences@30.0.1': {} + + '@jest/get-type@30.1.0': {} + + '@jest/schemas@30.0.5': + dependencies: + '@sinclair/typebox': 0.34.47 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.28.6 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.28.6 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@napi-rs/wasm-runtime@0.2.4': + dependencies: + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.9.0 + + '@napi-rs/wasm-runtime@1.1.1': + dependencies: + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nx/nx-darwin-arm64@22.3.3': + optional: true + + '@nx/nx-darwin-x64@22.3.3': + optional: true + + '@nx/nx-freebsd-x64@22.3.3': + optional: true + + '@nx/nx-linux-arm-gnueabihf@22.3.3': + optional: true + + '@nx/nx-linux-arm64-gnu@22.3.3': + optional: true + + '@nx/nx-linux-arm64-musl@22.3.3': + optional: true + + '@nx/nx-linux-x64-gnu@22.3.3': + optional: true + + '@nx/nx-linux-x64-musl@22.3.3': + optional: true + + '@nx/nx-win32-arm64-msvc@22.3.3': + optional: true + + '@nx/nx-win32-x64-msvc@22.3.3': + optional: true + + '@oxc-project/types@0.107.0': {} + + '@oxc-project/types@0.112.0': {} + + '@oxc-resolver/binding-android-arm-eabi@11.16.3': + optional: true + + '@oxc-resolver/binding-android-arm64@11.16.3': + optional: true + + '@oxc-resolver/binding-darwin-arm64@11.16.3': + optional: true + + '@oxc-resolver/binding-darwin-x64@11.16.3': + optional: true + + '@oxc-resolver/binding-freebsd-x64@11.16.3': + optional: true + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.3': + optional: true + + '@oxc-resolver/binding-linux-arm-musleabihf@11.16.3': + optional: true + + '@oxc-resolver/binding-linux-arm64-gnu@11.16.3': + optional: true + + '@oxc-resolver/binding-linux-arm64-musl@11.16.3': + optional: true + + '@oxc-resolver/binding-linux-ppc64-gnu@11.16.3': + optional: true + + '@oxc-resolver/binding-linux-riscv64-gnu@11.16.3': + optional: true + + '@oxc-resolver/binding-linux-riscv64-musl@11.16.3': + optional: true + + '@oxc-resolver/binding-linux-s390x-gnu@11.16.3': + optional: true + + '@oxc-resolver/binding-linux-x64-gnu@11.16.3': + optional: true + + '@oxc-resolver/binding-linux-x64-musl@11.16.3': + optional: true + + '@oxc-resolver/binding-openharmony-arm64@11.16.3': + optional: true + + '@oxc-resolver/binding-wasm32-wasi@11.16.3': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@oxc-resolver/binding-win32-arm64-msvc@11.16.3': + optional: true + + '@oxc-resolver/binding-win32-ia32-msvc@11.16.3': + optional: true + + '@oxc-resolver/binding-win32-x64-msvc@11.16.3': + optional: true + + '@quansync/fs@1.0.0': + dependencies: + quansync: 1.0.0 + + '@rolldown/binding-android-arm64@1.0.0-beta.59': + optional: true + + '@rolldown/binding-android-arm64@1.0.0-rc.3': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-beta.59': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.3': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-beta.59': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.3': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-beta.59': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.3': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.59': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.59': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.59': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.3': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.59': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.3': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.59': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.3': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.59': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.3': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.59': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.3': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.59': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.59': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.3': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.59': {} + + '@rolldown/pluginutils@1.0.0-rc.3': {} + + '@rollup/rollup-android-arm-eabi@4.55.1': + optional: true + + '@rollup/rollup-android-arm64@4.55.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.55.1': + optional: true + + '@rollup/rollup-darwin-x64@4.55.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.55.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.55.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.55.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.55.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.55.1': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.55.1': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.55.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.55.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.55.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.55.1': + optional: true + + '@rollup/rollup-openbsd-x64@4.55.1': + optional: true + + '@rollup/rollup-openharmony-arm64@4.55.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.55.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.55.1': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.55.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.55.1': + optional: true + + '@shikijs/engine-oniguruma@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/themes@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/types@3.23.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@sinclair/typebox@0.34.47': {} + + '@standard-schema/spec@1.1.0': {} + + '@stylistic/eslint-plugin@5.7.0(eslint@9.39.2(jiti@2.6.1))': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) + '@typescript-eslint/types': 8.53.0 + eslint: 9.39.2(jiti@2.6.1) + eslint-visitor-keys: 5.0.0 + espree: 11.0.0 + estraverse: 5.3.0 + picomatch: 4.0.3 + + '@sveltejs/acorn-typescript@1.0.8(acorn@8.15.0)': + dependencies: + acorn: 8.15.0 + + '@svitejs/changesets-changelog-github-compact@1.2.0': + dependencies: + '@changesets/get-github-info': 0.6.0 + dotenv: 16.6.1 + transitivePeerDependencies: + - encoding + + '@tanstack/eslint-config@0.3.4(@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint/js': 9.39.2 + '@stylistic/eslint-plugin': 5.7.0(eslint@9.39.2(jiti@2.6.1)) + eslint: 9.39.2(jiti@2.6.1) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-n: 17.23.2(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + globals: 16.5.0 + typescript-eslint: 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + vue-eslint-parser: 10.2.0(eslint@9.39.2(jiti@2.6.1)) + transitivePeerDependencies: + - '@typescript-eslint/utils' + - eslint-import-resolver-node + - supports-color + - typescript + + '@tanstack/typedoc-config@0.3.3(typescript@5.9.3)': + dependencies: + typedoc: 0.28.14(typescript@5.9.3) + typedoc-plugin-frontmatter: 1.3.0(typedoc-plugin-markdown@4.9.0(typedoc@0.28.14(typescript@5.9.3))) + typedoc-plugin-markdown: 4.9.0(typedoc@0.28.14(typescript@5.9.3)) + transitivePeerDependencies: + - typescript + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@tybys/wasm-util@0.9.0': + dependencies: + tslib: 2.8.1 + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.8': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/node@12.20.55': {} + + '@types/node@20.19.30': + dependencies: + undici-types: 6.21.0 + + '@types/node@25.0.9': + dependencies: + undici-types: 7.16.0 + + '@types/unist@3.0.3': {} + + '@types/whatwg-mimetype@3.0.2': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 25.0.9 + + '@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.53.0 + '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.53.0 + eslint: 9.39.2(jiti@2.6.1) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.53.0 + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.53.0 + debug: 4.4.3 + eslint: 9.39.2(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.53.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3) + '@typescript-eslint/types': 8.53.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.53.0': + dependencies: + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/visitor-keys': 8.53.0 + + '@typescript-eslint/tsconfig-utils@8.53.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.2(jiti@2.6.1) + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.53.0': {} + + '@typescript-eslint/typescript-estree@8.53.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.53.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3) + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/visitor-keys': 8.53.0 + debug: 4.4.3 + minimatch: 9.0.5 + semver: 7.7.3 + tinyglobby: 0.2.15 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.53.0 + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + eslint: 9.39.2(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.53.0': + dependencies: + '@typescript-eslint/types': 8.53.0 + eslint-visitor-keys: 4.2.1 + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + '@vitest/expect@4.0.17': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.17 + '@vitest/utils': 4.0.17 + chai: 6.2.2 + tinyrainbow: 3.0.3 + + '@vitest/mocker@4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2))': + dependencies: + '@vitest/spy': 4.0.17 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2) + + '@vitest/pretty-format@4.0.17': + dependencies: + tinyrainbow: 3.0.3 + + '@vitest/runner@4.0.17': + dependencies: + '@vitest/utils': 4.0.17 + pathe: 2.0.3 + + '@vitest/snapshot@4.0.17': + dependencies: + '@vitest/pretty-format': 4.0.17 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.0.17': {} + + '@vitest/utils@4.0.17': + dependencies: + '@vitest/pretty-format': 4.0.17 + tinyrainbow: 3.0.3 + + '@yarnpkg/lockfile@1.1.0': {} + + '@yarnpkg/parsers@3.0.2': + dependencies: + js-yaml: 3.14.2 + tslib: 2.8.1 + + '@zkochan/js-yaml@0.0.7': + dependencies: + argparse: 2.0.1 + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansis@4.2.0: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + array-union@2.1.0: {} + + assertion-error@2.0.1: {} + + ast-kit@2.2.0: + dependencies: + '@babel/parser': 7.29.0 + pathe: 2.0.3 + + asynckit@0.4.0: {} + + axios@1.13.2: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + birpc@4.0.0: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + boolbase@1.0.0: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + callsites@3.1.0: {} + + chai@6.2.2: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chardet@2.1.1: {} + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.1.2: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + encoding-sniffer: 0.2.1 + htmlparser2: 10.0.0 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 7.18.2 + whatwg-mimetype: 4.0.0 + + ci-info@3.9.0: {} + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-spinners@2.6.1: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: {} + + clsx@2.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + comment-parser@1.4.4: {} + + concat-map@0.0.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-what@6.2.2: {} + + dataloader@1.4.0: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-lazy-prop@2.0.0: {} + + defu@6.1.4: {} + + delayed-stream@1.0.0: {} + + detect-indent@6.1.0: {} + + devalue@5.6.2: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dotenv-expand@11.0.7: + dependencies: + dotenv: 16.4.7 + + dotenv@16.4.7: {} + + dotenv@16.6.1: {} + + dts-resolver@2.1.3(oxc-resolver@11.16.3): + optionalDependencies: + oxc-resolver: 11.16.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + emoji-regex@8.0.0: {} + + empathic@2.0.0: {} + + encoding-sniffer@0.2.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + enhanced-resolve@5.18.4: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + + enquirer@2.3.6: + dependencies: + ansi-colors: 4.1.3 + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + entities@4.5.0: {} + + entities@6.0.1: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esbuild@0.27.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 + + escalade@3.2.0: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-compat-utils@0.5.1(eslint@9.39.2(jiti@2.6.1)): + dependencies: + eslint: 9.39.2(jiti@2.6.1) + semver: 7.7.3 + + eslint-import-context@0.1.9(unrs-resolver@1.11.1): + dependencies: + get-tsconfig: 4.13.0 + stable-hash-x: 0.2.0 + optionalDependencies: + unrs-resolver: 1.11.1 + + eslint-plugin-es-x@7.8.0(eslint@9.39.2(jiti@2.6.1)): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + eslint: 9.39.2(jiti@2.6.1) + eslint-compat-utils: 0.5.1(eslint@9.39.2(jiti@2.6.1)) + + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): + dependencies: + '@typescript-eslint/types': 8.53.0 + comment-parser: 1.4.4 + debug: 4.4.3 + eslint: 9.39.2(jiti@2.6.1) + eslint-import-context: 0.1.9(unrs-resolver@1.11.1) + is-glob: 4.0.3 + minimatch: 10.1.1 + semver: 7.7.3 + stable-hash-x: 0.2.0 + unrs-resolver: 1.11.1 + optionalDependencies: + '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + + eslint-plugin-n@17.23.2(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) + enhanced-resolve: 5.18.4 + eslint: 9.39.2(jiti@2.6.1) + eslint-plugin-es-x: 7.8.0(eslint@9.39.2(jiti@2.6.1)) + get-tsconfig: 4.13.0 + globals: 15.15.0 + globrex: 0.1.2 + ignore: 5.3.2 + semver: 7.7.3 + ts-declaration-location: 1.0.7(typescript@5.9.3) + transitivePeerDependencies: + - typescript + + eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): + dependencies: + eslint: 9.39.2(jiti@2.6.1) + optionalDependencies: + '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.0: {} + + eslint@9.39.2(jiti@2.6.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.3 + '@eslint/js': 9.39.2 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + + esm-env@1.2.2: {} + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + espree@11.0.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 5.0.0 + + esprima@4.0.1: {} + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrap@2.2.1: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + expect-type@1.3.0: {} + + extendable-error@0.1.7: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fd-package-json@2.0.0: + dependencies: + walk-up-path: 4.0.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flat@5.0.2: {} + + flatted@3.3.3: {} + + follow-redirects@1.15.11: {} + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + formatly@0.3.0: + dependencies: + fd-package-json: 2.0.0 + + front-matter@4.0.2: + dependencies: + js-yaml: 3.14.2 + + fs-constants@1.0.0: {} + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@15.15.0: {} + + globals@16.5.0: {} + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globrex@0.1.2: {} + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + happy-dom@20.3.1: + dependencies: + '@types/node': 20.19.30 + '@types/whatwg-mimetype': 3.0.2 + '@types/ws': 8.18.1 + whatwg-mimetype: 3.0.0 + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hookable@6.0.1: {} + + html-link-extractor@1.0.5: + dependencies: + cheerio: 1.1.2 + + htmlparser2@10.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 6.0.1 + + human-id@4.1.3: {} + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-without-cache@0.2.5: {} + + imurmurhash@0.1.4: {} + + inherits@2.0.4: {} + + is-docker@2.2.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-interactive@1.0.0: {} + + is-number@7.0.0: {} + + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-unicode-supported@0.1.0: {} + + is-windows@1.0.2: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + isexe@2.0.0: {} + + jest-diff@30.2.0: + dependencies: + '@jest/diff-sequences': 30.0.1 + '@jest/get-type': 30.1.0 + chalk: 4.1.2 + pretty-format: 30.2.0 + + jiti@2.6.1: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jsonc-parser@3.2.0: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + knip@5.81.0(@types/node@25.0.9)(typescript@5.9.3): + dependencies: + '@nodelib/fs.walk': 1.2.8 + '@types/node': 25.0.9 + fast-glob: 3.3.3 + formatly: 0.3.0 + jiti: 2.6.1 + js-yaml: 4.1.1 + minimist: 1.2.8 + oxc-resolver: 11.16.3 + picocolors: 1.1.1 + picomatch: 4.0.3 + smol-toml: 1.6.0 + strip-json-comments: 5.0.3 + typescript: 5.9.3 + zod: 4.3.5 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lines-and-columns@2.0.3: {} + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + locate-character@3.0.0: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash.startcase@4.4.0: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + lunr@2.3.9: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + markdown-it@14.1.1: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + markdown-link-extractor@4.0.3: + dependencies: + html-link-extractor: 1.0.5 + marked: 17.0.1 + + marked@17.0.1: {} + + math-intrinsics@1.1.0: {} + + mdurl@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@2.1.0: {} + + minimatch@10.1.1: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.3: + dependencies: + brace-expansion: 2.0.2 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + minimist@1.2.8: {} + + mri@1.2.0: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + napi-postinstall@0.3.4: {} + + natural-compare@1.4.0: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-machine-id@1.1.12: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nx@22.3.3: + dependencies: + '@napi-rs/wasm-runtime': 0.2.4 + '@yarnpkg/lockfile': 1.1.0 + '@yarnpkg/parsers': 3.0.2 + '@zkochan/js-yaml': 0.0.7 + axios: 1.13.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.6.1 + cliui: 8.0.1 + dotenv: 16.4.7 + dotenv-expand: 11.0.7 + enquirer: 2.3.6 + figures: 3.2.0 + flat: 5.0.2 + front-matter: 4.0.2 + ignore: 7.0.5 + jest-diff: 30.2.0 + jsonc-parser: 3.2.0 + lines-and-columns: 2.0.3 + minimatch: 9.0.3 + node-machine-id: 1.1.12 + npm-run-path: 4.0.1 + open: 8.4.2 + ora: 5.3.0 + resolve.exports: 2.0.3 + semver: 7.7.3 + string-width: 4.2.3 + tar-stream: 2.2.0 + tmp: 0.2.5 + tree-kill: 1.2.2 + tsconfig-paths: 4.2.0 + tslib: 2.8.1 + yaml: 2.8.2 + yargs: 17.7.2 + yargs-parser: 21.1.1 + optionalDependencies: + '@nx/nx-darwin-arm64': 22.3.3 + '@nx/nx-darwin-x64': 22.3.3 + '@nx/nx-freebsd-x64': 22.3.3 + '@nx/nx-linux-arm-gnueabihf': 22.3.3 + '@nx/nx-linux-arm64-gnu': 22.3.3 + '@nx/nx-linux-arm64-musl': 22.3.3 + '@nx/nx-linux-x64-gnu': 22.3.3 + '@nx/nx-linux-x64-musl': 22.3.3 + '@nx/nx-win32-arm64-msvc': 22.3.3 + '@nx/nx-win32-x64-msvc': 22.3.3 + transitivePeerDependencies: + - debug + + obug@2.1.1: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@5.3.0: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.6.1 + is-interactive: 1.0.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + outdent@0.5.0: {} + + oxc-resolver@11.16.3: + optionalDependencies: + '@oxc-resolver/binding-android-arm-eabi': 11.16.3 + '@oxc-resolver/binding-android-arm64': 11.16.3 + '@oxc-resolver/binding-darwin-arm64': 11.16.3 + '@oxc-resolver/binding-darwin-x64': 11.16.3 + '@oxc-resolver/binding-freebsd-x64': 11.16.3 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.16.3 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.16.3 + '@oxc-resolver/binding-linux-arm64-gnu': 11.16.3 + '@oxc-resolver/binding-linux-arm64-musl': 11.16.3 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.16.3 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.16.3 + '@oxc-resolver/binding-linux-riscv64-musl': 11.16.3 + '@oxc-resolver/binding-linux-s390x-gnu': 11.16.3 + '@oxc-resolver/binding-linux-x64-gnu': 11.16.3 + '@oxc-resolver/binding-linux-x64-musl': 11.16.3 + '@oxc-resolver/binding-openharmony-arm64': 11.16.3 + '@oxc-resolver/binding-wasm32-wasi': 11.16.3 + '@oxc-resolver/binding-win32-arm64-msvc': 11.16.3 + '@oxc-resolver/binding-win32-ia32-msvc': 11.16.3 + '@oxc-resolver/binding-win32-x64-msvc': 11.16.3 + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@2.1.0: {} + + p-try@2.2.0: {} + + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.3.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-type@4.0.0: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pify@4.0.1: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-plugin-svelte@3.4.1(prettier@3.8.0)(svelte@5.46.4): + dependencies: + prettier: 3.8.0 + svelte: 5.46.4 + + prettier@2.8.8: {} + + prettier@3.8.0: {} + + pretty-format@30.2.0: + dependencies: + '@jest/schemas': 30.0.5 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + proxy-from-env@1.1.0: {} + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + quansync@0.2.11: {} + + quansync@1.0.0: {} + + queue-microtask@1.2.3: {} + + react-is@18.3.1: {} + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.2 + pify: 4.0.1 + strip-bom: 3.0.0 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + require-directory@2.1.1: {} + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve.exports@2.0.3: {} + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + reusify@1.1.0: {} + + rolldown-plugin-dts@0.20.0(oxc-resolver@11.16.3)(rolldown@1.0.0-beta.59)(typescript@5.9.3): + dependencies: + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + ast-kit: 2.2.0 + birpc: 4.0.0 + dts-resolver: 2.1.3(oxc-resolver@11.16.3) + get-tsconfig: 4.13.0 + obug: 2.1.1 + rolldown: 1.0.0-beta.59 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - oxc-resolver + + rolldown@1.0.0-beta.59: + dependencies: + '@oxc-project/types': 0.107.0 + '@rolldown/pluginutils': 1.0.0-beta.59 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-beta.59 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.59 + '@rolldown/binding-darwin-x64': 1.0.0-beta.59 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.59 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.59 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.59 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.59 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.59 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.59 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.59 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.59 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.59 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.59 + + rolldown@1.0.0-rc.3: + dependencies: + '@oxc-project/types': 0.112.0 + '@rolldown/pluginutils': 1.0.0-rc.3 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.3 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.3 + '@rolldown/binding-darwin-x64': 1.0.0-rc.3 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.3 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.3 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.3 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.3 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.3 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.3 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.3 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.3 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.3 + + rollup@4.55.1: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.55.1 + '@rollup/rollup-android-arm64': 4.55.1 + '@rollup/rollup-darwin-arm64': 4.55.1 + '@rollup/rollup-darwin-x64': 4.55.1 + '@rollup/rollup-freebsd-arm64': 4.55.1 + '@rollup/rollup-freebsd-x64': 4.55.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.55.1 + '@rollup/rollup-linux-arm-musleabihf': 4.55.1 + '@rollup/rollup-linux-arm64-gnu': 4.55.1 + '@rollup/rollup-linux-arm64-musl': 4.55.1 + '@rollup/rollup-linux-loong64-gnu': 4.55.1 + '@rollup/rollup-linux-loong64-musl': 4.55.1 + '@rollup/rollup-linux-ppc64-gnu': 4.55.1 + '@rollup/rollup-linux-ppc64-musl': 4.55.1 + '@rollup/rollup-linux-riscv64-gnu': 4.55.1 + '@rollup/rollup-linux-riscv64-musl': 4.55.1 + '@rollup/rollup-linux-s390x-gnu': 4.55.1 + '@rollup/rollup-linux-x64-gnu': 4.55.1 + '@rollup/rollup-linux-x64-musl': 4.55.1 + '@rollup/rollup-openbsd-x64': 4.55.1 + '@rollup/rollup-openharmony-arm64': 4.55.1 + '@rollup/rollup-win32-arm64-msvc': 4.55.1 + '@rollup/rollup-win32-ia32-msvc': 4.55.1 + '@rollup/rollup-win32-x64-gnu': 4.55.1 + '@rollup/rollup-win32-x64-msvc': 4.55.1 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + semver@7.7.3: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + sherif-darwin-arm64@1.10.0: + optional: true + + sherif-darwin-x64@1.10.0: + optional: true + + sherif-linux-arm64-musl@1.10.0: + optional: true + + sherif-linux-arm64@1.10.0: + optional: true + + sherif-linux-x64-musl@1.10.0: + optional: true + + sherif-linux-x64@1.10.0: + optional: true + + sherif-windows-arm64@1.10.0: + optional: true + + sherif-windows-x64@1.10.0: + optional: true + + sherif@1.10.0: + optionalDependencies: + sherif-darwin-arm64: 1.10.0 + sherif-darwin-x64: 1.10.0 + sherif-linux-arm64: 1.10.0 + sherif-linux-arm64-musl: 1.10.0 + sherif-linux-x64: 1.10.0 + sherif-linux-x64-musl: 1.10.0 + sherif-windows-arm64: 1.10.0 + sherif-windows-x64: 1.10.0 + + siginfo@2.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + slash@3.0.0: {} + + smol-toml@1.6.0: {} + + source-map-js@1.2.1: {} + + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + sprintf-js@1.0.3: {} + + stable-hash-x@0.2.0: {} + + stackback@0.0.2: {} + + std-env@3.10.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + strip-json-comments@5.0.3: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + svelte@5.46.4: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) + '@types/estree': 1.0.8 + acorn: 8.15.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.6.2 + esm-env: 1.2.2 + esrap: 2.2.1 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + zimmerframe: 1.1.4 + + tapable@2.3.0: {} + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + term-size@2.2.1: {} + + tinybench@2.9.0: {} + + tinyexec@1.0.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinyrainbow@3.0.3: {} + + tmp@0.2.5: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tr46@0.0.3: {} + + tree-kill@1.2.2: {} + + ts-api-utils@2.4.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-declaration-location@1.0.7(typescript@5.9.3): + dependencies: + picomatch: 4.0.3 + typescript: 5.9.3 + + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tsdown@0.19.0(oxc-resolver@11.16.3)(typescript@5.9.3): + dependencies: + ansis: 4.2.0 + cac: 6.7.14 + defu: 6.1.4 + empathic: 2.0.0 + hookable: 6.0.1 + import-without-cache: 0.2.5 + obug: 2.1.1 + picomatch: 4.0.3 + rolldown: 1.0.0-beta.59 + rolldown-plugin-dts: 0.20.0(oxc-resolver@11.16.3)(rolldown@1.0.0-beta.59)(typescript@5.9.3) + semver: 7.7.3 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + unconfig-core: 7.5.0 + unrun: 0.2.27 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@ts-macro/tsc' + - '@typescript/native-preview' + - oxc-resolver + - synckit + - vue-tsc + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typedoc-plugin-frontmatter@1.3.0(typedoc-plugin-markdown@4.9.0(typedoc@0.28.14(typescript@5.9.3))): + dependencies: + typedoc-plugin-markdown: 4.9.0(typedoc@0.28.14(typescript@5.9.3)) + yaml: 2.8.2 + + typedoc-plugin-markdown@4.9.0(typedoc@0.28.14(typescript@5.9.3)): + dependencies: + typedoc: 0.28.14(typescript@5.9.3) + + typedoc@0.28.14(typescript@5.9.3): + dependencies: + '@gerrit0/mini-shiki': 3.23.0 + lunr: 2.3.9 + markdown-it: 14.1.1 + minimatch: 9.0.5 + typescript: 5.9.3 + yaml: 2.8.2 + + typescript-eslint@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.2(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + uc.micro@2.1.0: {} + + unconfig-core@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + quansync: 1.0.0 + + undici-types@6.21.0: {} + + undici-types@7.16.0: {} + + undici@7.18.2: {} + + universalify@0.1.2: {} + + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + unrun@0.2.27: + dependencies: + rolldown: 1.0.0-rc.3 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2): + dependencies: + esbuild: 0.27.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.55.1 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 25.0.9 + fsevents: 2.3.3 + jiti: 2.6.1 + yaml: 2.8.2 + + vitest@4.0.17(@types/node@25.0.9)(happy-dom@20.3.1)(jiti@2.6.1)(yaml@2.8.2): + dependencies: + '@vitest/expect': 4.0.17 + '@vitest/mocker': 4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2)) + '@vitest/pretty-format': 4.0.17 + '@vitest/runner': 4.0.17 + '@vitest/snapshot': 4.0.17 + '@vitest/spy': 4.0.17 + '@vitest/utils': 4.0.17 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(yaml@2.8.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.0.9 + happy-dom: 20.3.1 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@2.6.1)): + dependencies: + debug: 4.4.3 + eslint: 9.39.2(jiti@2.6.1) + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + semver: 7.7.3 + transitivePeerDependencies: + - supports-color + + walk-up-path@4.0.0: {} + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + webidl-conversions@3.0.1: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@3.0.0: {} + + whatwg-mimetype@4.0.0: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@8.19.0: {} + + y18n@5.0.8: {} + + yaml@2.8.2: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} + + zimmerframe@1.1.4: {} + + zod@4.3.5: {} diff --git a/scripts/generate-docs.ts b/scripts/generate-docs.ts index 91670a6c..8d9ccdae 100644 --- a/scripts/generate-docs.ts +++ b/scripts/generate-docs.ts @@ -1,20 +1,20 @@ -import { resolve } from 'node:path' -import { fileURLToPath } from 'node:url' -import { generateReferenceDocs } from '@tanstack/typedoc-config' - -const __dirname = fileURLToPath(new URL('.', import.meta.url)) - -await generateReferenceDocs({ - packages: [ - { - name: 'intent', - entryPoints: [resolve(__dirname, '../packages/intent/src/index.ts')], - tsconfig: resolve(__dirname, '../packages/intent/tsconfig.docs.json'), - outputDir: resolve(__dirname, '../docs/intent'), - }, - ], -}) - -console.log('\n✅ All markdown files have been processed!') - -process.exit(0) +import { resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import { generateReferenceDocs } from '@tanstack/typedoc-config' + +const __dirname = fileURLToPath(new URL('.', import.meta.url)) + +await generateReferenceDocs({ + packages: [ + { + name: 'intent', + entryPoints: [resolve(__dirname, '../packages/intent/src/index.ts')], + tsconfig: resolve(__dirname, '../packages/intent/tsconfig.docs.json'), + outputDir: resolve(__dirname, '../docs/intent'), + }, + ], +}) + +console.log('\n✅ All markdown files have been processed!') + +process.exit(0) diff --git a/scripts/validate-skills.ts b/scripts/validate-skills.ts index b90bd7c2..a4941c48 100644 --- a/scripts/validate-skills.ts +++ b/scripts/validate-skills.ts @@ -1,203 +1,203 @@ -import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs' -import { join, relative, sep } from 'node:path' -import { parse as parseYaml } from 'yaml' - -// ── Types ── - -interface SkillFrontmatter { - name: string - description: string - type?: string - library?: string - framework?: string - library_version?: string - requires?: Array - sources?: Array -} - -interface ValidationError { - file: string - message: string -} - -// ── Constants ── - -const skillsArg = process.argv[2] -const SKILLS_DIR = skillsArg - ? join(process.cwd(), skillsArg) - : join(process.cwd(), 'skills') -const MAX_LINES = 500 - -const PROHIBITED_PATTERNS: Array<{ pattern: RegExp; description: string }> = [ - { - pattern: /(?:npm|yarn|pnpm|bun)\s+(?:install|add|i)\s/i, - description: 'Install instructions', - }, - { - pattern: /(?:curl|wget|fetch)\s+https?:\/\//i, - description: 'Instructions to fetch external URLs at runtime', - }, -] - -const ALLOWED_SHELL_COMMANDS = [ - 'intent list', - 'intent feedback', - 'npm install @tanstack/', - 'npx intent', -] - -// ── Helpers ── - -function findSkillFiles(dir: string): Array { - const files: Array = [] - if (!existsSync(dir)) return files - - for (const entry of readdirSync(dir)) { - const fullPath = join(dir, entry) - const stat = statSync(fullPath) - if (stat.isDirectory()) { - files.push(...findSkillFiles(fullPath)) - } else if (entry === 'SKILL.md') { - files.push(fullPath) - } - } - return files -} - -function extractFrontmatter( - content: string, -): { frontmatter: SkillFrontmatter; body: string } | null { - const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)/) - if (!match?.[1]) return null - - try { - const frontmatter = parseYaml(match[1]) as SkillFrontmatter - return { frontmatter, body: match[2] ?? '' } - } catch { - return null - } -} - -function skillPathFromFile(filePath: string): string { - const rel = relative(SKILLS_DIR, filePath) - return rel - .replace(/[/\\]SKILL\.md$/, '') - .split(sep) - .join('/') -} - -// ── Validators ── - -function validateFrontmatter( - filePath: string, - frontmatter: SkillFrontmatter, -): Array { - const errors: Array = [] - const rel = relative(process.cwd(), filePath) - - if (!frontmatter.name) { - errors.push({ file: rel, message: 'Missing required field: name' }) - } - - if (!frontmatter.description) { - errors.push({ file: rel, message: 'Missing required field: description' }) - } - - if (frontmatter.name) { - const expectedPath = skillPathFromFile(filePath) - if (frontmatter.name !== expectedPath) { - errors.push({ - file: rel, - message: `name "${frontmatter.name}" does not match directory path "${expectedPath}"`, - }) - } - } - - if (frontmatter.type === 'framework' && !frontmatter.requires?.length) { - errors.push({ - file: rel, - message: 'Framework skills must have a "requires" field', - }) - } - - return errors -} - -function validateContent( - filePath: string, - content: string, - body: string, -): Array { - const errors: Array = [] - const rel = relative(process.cwd(), filePath) - - const lineCount = content.split(/\r?\n/).length - if (lineCount > MAX_LINES) { - errors.push({ - file: rel, - message: `Exceeds ${MAX_LINES} line limit (${lineCount} lines)`, - }) - } - - for (const { pattern, description } of PROHIBITED_PATTERNS) { - for (const line of body.split(/\r?\n/)) { - if (pattern.test(line)) { - const isAllowed = ALLOWED_SHELL_COMMANDS.some((cmd) => - line.includes(cmd), - ) - if (!isAllowed) { - errors.push({ - file: rel, - message: `Prohibited content: ${description} — "${line.trim().slice(0, 80)}"`, - }) - break - } - } - } - } - - return errors -} - -// ── Main ── - -function main(): void { - const errors: Array = [] - - console.log(`Validating skills in: ${SKILLS_DIR}`) - - const skillFiles = findSkillFiles(SKILLS_DIR) - - if (skillFiles.length === 0) { - console.log('No SKILL.md files found — nothing to validate') - process.exit(0) - } - - for (const filePath of skillFiles) { - const content = readFileSync(filePath, 'utf-8') - const parsed = extractFrontmatter(content) - - const rel = relative(process.cwd(), filePath) - - if (!parsed) { - errors.push({ file: rel, message: 'Missing or invalid frontmatter' }) - continue - } - - errors.push(...validateFrontmatter(filePath, parsed.frontmatter)) - errors.push(...validateContent(filePath, content, parsed.body)) - } - - if (errors.length > 0) { - console.error(`\n❌ Validation failed with ${errors.length} error(s):\n`) - for (const { file, message } of errors) { - console.error(` ${file}: ${message}`) - } - console.error('') - process.exit(1) - } - - console.log(`✅ Validated ${skillFiles.length} skill files — all passed`) -} - -main() +import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs' +import { join, relative, sep } from 'node:path' +import { parse as parseYaml } from 'yaml' + +// ── Types ── + +interface SkillFrontmatter { + name: string + description: string + type?: string + library?: string + framework?: string + library_version?: string + requires?: Array + sources?: Array +} + +interface ValidationError { + file: string + message: string +} + +// ── Constants ── + +const skillsArg = process.argv[2] +const SKILLS_DIR = skillsArg + ? join(process.cwd(), skillsArg) + : join(process.cwd(), 'skills') +const MAX_LINES = 500 + +const PROHIBITED_PATTERNS: Array<{ pattern: RegExp; description: string }> = [ + { + pattern: /(?:npm|yarn|pnpm|bun)\s+(?:install|add|i)\s/i, + description: 'Install instructions', + }, + { + pattern: /(?:curl|wget|fetch)\s+https?:\/\//i, + description: 'Instructions to fetch external URLs at runtime', + }, +] + +const ALLOWED_SHELL_COMMANDS = [ + 'intent list', + 'intent feedback', + 'npm install @tanstack/', + 'npx intent', +] + +// ── Helpers ── + +function findSkillFiles(dir: string): Array { + const files: Array = [] + if (!existsSync(dir)) return files + + for (const entry of readdirSync(dir)) { + const fullPath = join(dir, entry) + const stat = statSync(fullPath) + if (stat.isDirectory()) { + files.push(...findSkillFiles(fullPath)) + } else if (entry === 'SKILL.md') { + files.push(fullPath) + } + } + return files +} + +function extractFrontmatter( + content: string, +): { frontmatter: SkillFrontmatter; body: string } | null { + const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)/) + if (!match?.[1]) return null + + try { + const frontmatter = parseYaml(match[1]) as SkillFrontmatter + return { frontmatter, body: match[2] ?? '' } + } catch { + return null + } +} + +function skillPathFromFile(filePath: string): string { + const rel = relative(SKILLS_DIR, filePath) + return rel + .replace(/[/\\]SKILL\.md$/, '') + .split(sep) + .join('/') +} + +// ── Validators ── + +function validateFrontmatter( + filePath: string, + frontmatter: SkillFrontmatter, +): Array { + const errors: Array = [] + const rel = relative(process.cwd(), filePath) + + if (!frontmatter.name) { + errors.push({ file: rel, message: 'Missing required field: name' }) + } + + if (!frontmatter.description) { + errors.push({ file: rel, message: 'Missing required field: description' }) + } + + if (frontmatter.name) { + const expectedPath = skillPathFromFile(filePath) + if (frontmatter.name !== expectedPath) { + errors.push({ + file: rel, + message: `name "${frontmatter.name}" does not match directory path "${expectedPath}"`, + }) + } + } + + if (frontmatter.type === 'framework' && !frontmatter.requires?.length) { + errors.push({ + file: rel, + message: 'Framework skills must have a "requires" field', + }) + } + + return errors +} + +function validateContent( + filePath: string, + content: string, + body: string, +): Array { + const errors: Array = [] + const rel = relative(process.cwd(), filePath) + + const lineCount = content.split(/\r?\n/).length + if (lineCount > MAX_LINES) { + errors.push({ + file: rel, + message: `Exceeds ${MAX_LINES} line limit (${lineCount} lines)`, + }) + } + + for (const { pattern, description } of PROHIBITED_PATTERNS) { + for (const line of body.split(/\r?\n/)) { + if (pattern.test(line)) { + const isAllowed = ALLOWED_SHELL_COMMANDS.some((cmd) => + line.includes(cmd), + ) + if (!isAllowed) { + errors.push({ + file: rel, + message: `Prohibited content: ${description} — "${line.trim().slice(0, 80)}"`, + }) + break + } + } + } + } + + return errors +} + +// ── Main ── + +function main(): void { + const errors: Array = [] + + console.log(`Validating skills in: ${SKILLS_DIR}`) + + const skillFiles = findSkillFiles(SKILLS_DIR) + + if (skillFiles.length === 0) { + console.log('No SKILL.md files found — nothing to validate') + process.exit(0) + } + + for (const filePath of skillFiles) { + const content = readFileSync(filePath, 'utf-8') + const parsed = extractFrontmatter(content) + + const rel = relative(process.cwd(), filePath) + + if (!parsed) { + errors.push({ file: rel, message: 'Missing or invalid frontmatter' }) + continue + } + + errors.push(...validateFrontmatter(filePath, parsed.frontmatter)) + errors.push(...validateContent(filePath, content, parsed.body)) + } + + if (errors.length > 0) { + console.error(`\n❌ Validation failed with ${errors.length} error(s):\n`) + for (const { file, message } of errors) { + console.error(` ${file}: ${message}`) + } + console.error('') + process.exit(1) + } + + console.log(`✅ Validated ${skillFiles.length} skill files — all passed`) +} + +main() diff --git a/tsconfig.json b/tsconfig.json index c62fbb91..9c64a438 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,29 +1,29 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "compilerOptions": { - "allowJs": true, - "allowSyntheticDefaultImports": true, - "allowUnreachableCode": false, - "allowUnusedLabels": false, - "checkJs": true, - "declaration": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "isolatedModules": true, - "lib": ["DOM", "DOM.Iterable", "ES2022"], - "module": "ESNext", - "moduleResolution": "Bundler", - "noEmit": true, - "noImplicitReturns": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "strict": true, - "target": "ES2020", - "noErrorTruncation": true - }, - "include": ["scripts", "*.config.*", "vitest.workspace.js"], - "exclude": ["eslint.config.js"] -} +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "allowJs": true, + "allowSyntheticDefaultImports": true, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "checkJs": true, + "declaration": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "lib": ["DOM", "DOM.Iterable", "ES2022"], + "module": "ESNext", + "moduleResolution": "Bundler", + "noEmit": true, + "noImplicitReturns": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2020", + "noErrorTruncation": true + }, + "include": ["scripts", "*.config.*", "vitest.workspace.js"], + "exclude": ["eslint.config.js"] +} diff --git a/vitest.workspace.js b/vitest.workspace.js index 70deda66..a861a380 100644 --- a/vitest.workspace.js +++ b/vitest.workspace.js @@ -1,7 +1,7 @@ -import { defineConfig } from 'vitest/config' - -export default defineConfig({ - test: { - projects: ['./packages/intent/vitest.config.ts'], - }, -}) +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + projects: ['./packages/intent/vitest.config.ts'], + }, +})