From f9ba79c50bf1aae3fe169385b997f55e5e9649b5 Mon Sep 17 00:00:00 2001 From: Te-Shu Wang Date: Sat, 15 Aug 2026 11:37:11 +0800 Subject: [PATCH 1/3] feat: establish evidence-bounded readiness baseline --- .claude-plugin/marketplace.json | 8 +- .claude-plugin/plugin.json | 6 +- .github/workflows/ci.yml | 11 +- CHANGELOG.md | 24 + CONTRIBUTING.md | 37 + README.md | 204 +- ROADMAP.md | 29 + SECURITY.md | 15 + action.yml | 71 + action/action.yml | 64 +- agents/aeo-ai-scorer.md | 49 +- agents/aeo-analyzer.md | 64 +- docs/methodology.md | 78 + .../2026-04-07-framework-plugins-design.md | 2 + package-lock.json | 2466 ++++++----------- package.json | 27 +- skills/aeo-generate/SKILL.md | 60 +- skills/aeo-scan/SKILL.md | 81 +- skills/aeo-transform/SKILL.md | 92 +- src/cli/index.ts | 34 +- .../__tests__/evidence-boundaries.test.ts | 77 + src/core/__tests__/fixtures/good-page.html | 78 +- src/core/__tests__/fixtures/good-page.md | 55 +- src/core/__tests__/generator.test.ts | 37 +- src/core/__tests__/rules.test.ts | 12 +- src/core/__tests__/scanner.test.ts | 35 +- src/core/ai-prompt.ts | 14 +- src/core/generator.ts | 66 +- src/core/merger.ts | 4 +- src/core/rules.ts | 248 +- src/core/scanner.ts | 23 +- src/plugins/next.ts | 4 +- src/plugins/vite.ts | 4 +- 33 files changed, 1636 insertions(+), 2443 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 ROADMAP.md create mode 100644 SECURITY.md create mode 100644 action.yml create mode 100644 docs/methodology.md create mode 100644 src/core/__tests__/evidence-boundaries.test.ts diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index ee7497f..56913b1 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -4,18 +4,18 @@ "name": "Te-Shu Wang" }, "metadata": { - "description": "AI search optimization: scan, generate, and transform website content for AI readability", + "description": "Content-readiness lint with evidence-bounded AI discovery experiments", "version": "0.5.3" }, "plugins": [ { "name": "aeoptimize", "source": "./", - "description": "CLI toolkit + Claude Code skills for transforming SEO-optimized websites into AI-search-ready content", + "description": "CLI and Claude Code skills for reproducible content-readiness checks", "category": "seo", "tags": ["aeo", "seo", "ai-search", "llms-txt", "structured-data"], - "homepage": "https://github.com/dexuwang627-cloud/aeoptimize", - "repository": "https://github.com/dexuwang627-cloud/aeoptimize" + "homepage": "https://github.com/cucuwang/aeoptimize", + "repository": "https://github.com/cucuwang/aeoptimize" } ] } diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index cbf1227..fa718c7 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,12 +1,12 @@ { "name": "aeoptimize", - "description": "AI search optimization toolkit: scan, generate, and transform website content for AI readability", + "description": "Content-readiness lint and evidence-bounded discovery experiments", "version": "0.5.3", "author": { "name": "Te-Shu Wang" }, - "homepage": "https://github.com/dexuwang627-cloud/aeoptimize", - "repository": "https://github.com/dexuwang627-cloud/aeoptimize", + "homepage": "https://github.com/cucuwang/aeoptimize", + "repository": "https://github.com/cucuwang/aeoptimize", "license": "MIT", "keywords": ["aeo", "seo", "ai-search", "llms-txt", "structured-data", "claude-code-skill"], "commands": [ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f00305..091cbad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,8 +10,9 @@ jobs: test-and-build: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - node-version: [18, 20, 22] + node-version: [22, 24] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -20,6 +21,8 @@ jobs: - run: npm ci - run: npm test - run: npm run build + - run: npm pack --dry-run + - run: npm audit --audit-level=high lint-readme-commands: runs-on: ubuntu-latest @@ -27,8 +30,10 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 - run: npm ci - run: npm run build - name: Verify CLI is callable as aeoptimize - run: node dist/cli/index.js --version \ No newline at end of file + run: node dist/cli/index.js --version + - name: Verify public metadata uses the current repository owner + run: npm test -- --run src/core/__tests__/evidence-boundaries.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..cbc15a8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable user-visible changes will be documented here. The project follows Semantic Versioning after the v0.6 evidence baseline is released. + +## Unreleased + +### Changed + +- Reframed the score as deterministic content readiness rather than a prediction of ranking or AI citation. +- Classified FAQ and `llms.txt` as optional, zero-point signals. +- Removed the exact-one-H1 and fixed meta-description-length assumptions. +- Changed quantitative-content guidance to flag unsourced claims instead of rewarding more numbers. +- Stopped inferring `FAQPage` structured data from question headings. +- Limited CI support to maintained Node.js LTS lines and refreshed dependencies. +- Added methodology, contribution, security, roadmap, and root GitHub Action files. + +### Security + +- Updated runtime and development dependencies to remove known npm audit findings present in the previous lockfile. + +## 0.5.3 — 2026-04-15 + +- Added the `aeoptimize` executable alias. +- Synchronized CLI, Action, and plugin version metadata. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..3d2318e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,37 @@ +# Contributing + +Contributions that make `aeoptimize` more reproducible, explainable, or easier to adopt are welcome. + +## Development setup + +Use Node.js 22.12 or newer. Node 24 LTS is the recommended development version. + +```bash +npm ci +npm run check +npm pack --dry-run +npm audit --audit-level=high +``` + +Do not commit `node_modules`, `dist`, package tarballs, credentials, or reports containing private URLs. + +## Pull requests + +Keep each pull request focused. Include: + +- the problem and user workflow; +- tests or fixtures that fail before the change and pass after it; +- JSON/output compatibility notes; +- documentation updates for user-visible behavior; +- the source and evidence class for any scoring-rule change. + +Rule proposals must follow [docs/methodology.md](docs/methodology.md). Unsupported ranking, citation, adoption, or performance claims will not be accepted. Do not add fabricated statistics to examples or fixtures. + +## Commit and review expectations + +- Run `npm run check`, `npm pack --dry-run`, and `npm audit --audit-level=high`. +- Preserve deterministic output unless the pull request explicitly versions the methodology change. +- Treat generated JSON-LD and crawler policy as reviewable candidates, never universal defaults. +- Add a changelog entry for behavior, compatibility, security, or methodology changes. + +Opening an issue before a large change is recommended so scope and compatibility can be agreed first. diff --git a/README.md b/README.md index 78b228d..97b4a08 100644 --- a/README.md +++ b/README.md @@ -1,204 +1,140 @@ # aeoptimize [![npm version](https://img.shields.io/npm/v/aeoptimize.svg)](https://www.npmjs.com/package/aeoptimize) -[![CI](https://github.com/dexuwang627-cloud/aeoptimize/actions/workflows/ci.yml/badge.svg)](https://github.com/dexuwang627-cloud/aeoptimize/actions/workflows/ci.yml) -[![license](https://img.shields.io/npm/l/aeoptimize.svg)](https://github.com/dexuwang627-cloud/aeoptimize/blob/main/LICENSE) +[![CI](https://github.com/cucuwang/aeoptimize/actions/workflows/ci.yml/badge.svg)](https://github.com/cucuwang/aeoptimize/actions/workflows/ci.yml) +[![license](https://img.shields.io/npm/l/aeoptimize.svg)](https://github.com/cucuwang/aeoptimize/blob/main/LICENSE) -**CLI toolkit + Claude Code skills that transform SEO-optimized websites into AI-search-ready content.** +Deterministic content-readiness lint for static websites and documentation. -## Why AEO? +`aeoptimize` checks reproducible properties such as document structure, sourced quantitative claims, structured-data hygiene, indexing controls, metadata quality, and repetitive wording. It is intended for local development and CI regression checks. -| | SEO | AEO | -|---|---|---| -| **Goal** | Rank higher | Get cited | -| **Audience** | Search crawler | Language model | -| **Key metric** | Position | Citation accuracy | -| **Content style** | Keyword-rich | Self-contained, structured | -| **Structured data** | Nice to have | Essential | +It does **not** predict ranking, indexing, rich results, Google AI Overviews, or citation by ChatGPT, Perplexity, or another AI system. Google states that its AI search features need no special AI text file or schema, and valid structured data does not guarantee a search feature. See [methodology and limitations](docs/methodology.md). -67% of users now get their first answer from AI. If your content can't be extracted and cited, it's invisible. +## Quick start -AI search engines (ChatGPT, Perplexity, Google AI Overview) don't rank pages — they **cite** content. `aeoptimize` helps you make your content citable. - -## Quick Start +Requires Node.js 22.12 or newer. ```bash -npx aeoptimize scan your-site.com +npx aeoptimize scan https://example.com +npx aeoptimize scan ./dist --dir +npx aeoptimize scan ./dist --dir --json ``` -``` -AEO Readability Report -Score: 61/100 AI Readability: Good - - Structure ██████████████░░░░░░ 18/25 - Citability ████████████░░░░░░░░ 16/25 - Schema ███████░░░░░░░░░░░░░ 7/20 - AI Metadata ███████░░░░░░░░░░░░░ 8/15 - Content Density ███████████████░░░░░ 12/15 - -Top Suggestions: - → Add FAQ section with question-format headings - → Add AI-relevant schema types - → Create and link an llms.txt file -``` +Example output: -## Features +```text +Content Readiness Report +Score: 71/100 -### Scan — AI Readability Audit +Structure 20/25 +Citability 18/25 +Schema 16/20 +AI Metadata 10/15 +Content Density 7/15 +``` -17 rules across 5 dimensions, 0-100 score. Zero cost, offline capable, deterministic. +The score is a versioned heuristic for catching regressions within the same project. Do not treat it as a percentage chance of search or AI visibility, and do not compare unrelated sites as if it were an outcome metric. -```bash -npx aeoptimize scan https://example.com # Remote URL -npx aeoptimize scan ./dist --dir # Local directory -npx aeoptimize scan ./dist --dir --json # Machine-readable -``` +## What is scored -| Dimension | Max | What it measures | -|-----------|-----|------------------| -| **Structure** | 25 | Heading hierarchy, paragraph length, FAQ presence | -| **Citability** | 25 | Self-contained statements, data/stats, definitions | -| **Schema** | 20 | JSON-LD presence, completeness, AI-relevant types | -| **AI Metadata** | 15 | llms.txt, robots.txt AI config, meta description | -| **Content Density** | 15 | Content vs boilerplate, keyword stuffing detection | +| Dimension | Max | Scope | +| --- | ---: | --- | +| Structure | 25 | Document outline and readability heuristics | +| Citability | 25 | Claim specificity, source signals, definitions, attribution | +| Schema | 20 | JSON-LD structural hygiene when present; absence is not penalized | +| AI Metadata | 15 | Page-level indexing control and description quality | +| Content Density | 15 | Content/boilerplate and repetition heuristics | -### Multi-AI Scoring +Two often-promoted AEO signals are deliberately excluded from the score: -Score with multiple AI engines simultaneously. Detects `gemini` and `copilot` CLIs, dispatches parallel scoring, merges with rule engine. +- FAQ content and `FAQPage` schema are optional. The generator does not infer FAQ schema from question headings. +- `llms.txt` is an experimental proposal. Generating or publishing it does not add points. -```bash -npx aeoptimize scan https://example.com --multi-ai -``` +Every rule, its evidence class, and known false-positive boundary is documented in [docs/methodology.md](docs/methodology.md). -``` -Score: 72/100 (Rule Engine: 61 | AI Consensus: 83) +## CI contract - Rule Engine ████████████░░░░░░░░ 61/100 - Claude ████████████████░░░░ 85/100 - Gemini ████████████████░░░░ 81/100 +`--json` is the stable automation surface. A non-zero threshold is useful only after your team reviews the baseline and accepts the current methodology version. -AI Insights: - Claude: "FAQ section lacks schema markup" - Gemini: "Missing llms.txt reduces discoverability" +```bash +npx aeoptimize scan ./dist --dir --json > aeoptimize-report.json +node -e "const r=require('./aeoptimize-report.json'); process.exit(r.overall.total < 60 ? 1 : 0)" ``` -| Scenario | Weighting | -|----------|-----------| -| Rule engine + 2+ AIs | 50% rules + 50% AI average | -| Rule engine + 1 AI | 60% rules + 40% AI | -| Rule engine only | 100% rules | +The repository also contains root GitHub Action metadata for the v0.6 release line. Until a v0.6 tag is published, use the CLI directly rather than pinning an unreleased Action reference. -### Generate — AI Infrastructure Files +## Optional generators ```bash -npx aeoptimize generate ./dist --dry-run # Preview -npx aeoptimize generate ./dist # Write files +npx aeoptimize generate ./dist --dry-run +npx aeoptimize generate ./dist ``` -Generates: -- **llms.txt** — Machine-readable site summary ([llmstxt.org](https://llmstxt.org) standard) -- **llms-full.txt** — Full content for deep AI consumption -- **JSON-LD schemas** — Article, FAQPage, BreadcrumbList -- **robots.txt suggestions** — AI crawler allow/deny rules +The generator can create: -### Transform — AI Content Restructuring (Claude Code Skill) +- `llms.txt` and `llms-full.txt` as experimental outputs based on the [llms.txt proposal](https://llmstxt.org/); +- candidate `Article` and `BreadcrumbList` JSON-LD for manual review; +- crawler-specific `robots.txt` suggestions, printed but never applied automatically. -Uses your existing Claude subscription — zero extra cost: +Generated structured data must be reviewed against visible content and the applicable search-engine documentation. The generator intentionally does not create `FAQPage` from headings alone. -- Split long paragraphs into citable statements -- Extract implicit Q&A into FAQ schema -- Remove keyword stuffing -- Fix dangling references ("This...", "It...", "They...") -- Inject structured data - -## Framework Plugins +## Framework integrations ### Vite ```ts -// vite.config.ts +import { defineConfig } from 'vite'; import { aeoPlugin } from 'aeoptimize/vite'; export default defineConfig({ - plugins: [aeoPlugin()] + plugins: [aeoPlugin()], }); ``` ### Next.js -```ts -// next.config.mjs +```js import { withAeo } from 'aeoptimize/next'; export default withAeo({}); ``` -Build 時自動生成 `llms.txt`、`llms-full.txt`、`_aeo/generated-schemas.json` 並印出 AEO 分數。 - -Options: `{ silent?: boolean; outDir?: string }` +Both integrations scan the build output and generate the same optional artifacts as the CLI. Options: `{ silent?: boolean; outDir?: string }`. -## Guardrails - -### Pre-commit Hook +## Experimental AI review ```bash -npx aeoptimize hook install # Default: min score 60 -npx aeoptimize hook install --min-score 80 # Custom threshold -npx aeoptimize hook uninstall # Remove hook -``` - -Automatically checks AEO score of staged `.html` and `.md` files before each commit. Blocks commit if any file scores below the threshold. - -Works with husky too — add to your `.husky/pre-commit`: -```bash -npx aeoptimize scan ./dist --dir --json | node -e "const j=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); if(j.overall.total<60){console.error('AEO score too low:',j.overall.total);process.exit(1)}" +npx aeoptimize scan https://example.com --multi-ai ``` -### GitHub Action - -```yaml -# .github/workflows/aeo.yml -name: AEO Check -on: [pull_request] -jobs: - aeo: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dexuwang627-cloud/aeoptimize/action@v0.5.3 - with: - path: dist - min-score: 60 -``` +When supported local AI CLIs are available, this adds a subjective review and reports an experimental blend. Model output can vary and is not ground truth. The deterministic rule score remains visible separately. -## Claude Code Skills +## Pre-commit hook ```bash -claude plugin marketplace add dexuwang627-cloud/aeoptimize +npx aeoptimize hook install +npx aeoptimize hook install --min-score 60 +npx aeoptimize hook uninstall ``` -- `/aeo-scan` — Interactive audit with multi-AI scoring -- `/aeo-generate` — Guided file generation with preview -- `/aeo-transform` — AI-powered content restructuring +The hook checks staged `.html`, `.htm`, `.md`, and `.mdx` content. Review the baseline before using a threshold to block commits; `git commit --no-verify` remains an explicit escape hatch. -## Help +## Claude Code skills ```bash -npx aeoptimize --help # All commands -npx aeoptimize scan --help # Scan options -npx aeoptimize generate --help # Generate options +claude plugin marketplace add cucuwang/aeoptimize ``` -## Contributing +- `/aeo-scan` — deterministic readiness audit with optional experimental review +- `/aeo-generate` — preview optional discovery artifacts +- `/aeo-transform` — propose content edits without inventing claims + +## Project status -Contributions are welcome! Feel free to open issues or pull requests. +The next evidence release focuses on methodology, reproducible fixtures, CI compatibility, packaging, and external adoption—not more scoring rules. See [ROADMAP.md](ROADMAP.md). -1. Fork the repository -2. Create your feature branch (`git checkout -b feature/amazing`) -3. Run tests (`npm test`) -4. Commit your changes -5. Open a Pull Request +Contributions are welcome. Rule changes require an evidence note and positive/negative fixtures; see [CONTRIBUTING.md](CONTRIBUTING.md). Report vulnerabilities through the process in [SECURITY.md](SECURITY.md). ## License -MIT \ No newline at end of file +MIT diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..aceaecd --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,29 @@ +# Roadmap + +## v0.6 — Evidence Release + +The release goal is a trustworthy CI lint contract, not additional AEO claims. + +Release gates: + +- current repository identity across npm, README, Action, and Claude plugin metadata; +- green CI on supported Node.js LTS releases; +- zero high or critical npm audit findings at release time; +- versioned methodology with evidence classes and explicit non-goals; +- public positive, negative, and false-positive fixtures for every scored rule; +- root GitHub Action metadata and an end-to-end sample repository; +- stable JSON output, changelog, release notes, and rollback instructions. + +## Product validation after v0.6 + +- Validate one core workflow: static site or documentation CI content-readiness lint. +- Obtain three independently controlled public adoption examples. +- Triage external issues and document support boundaries before adding framework breadth. +- Measure technical outcomes such as a caught `noindex` regression or schema/content mismatch. Keep ranking and citation outcomes separate. + +## Not planned without new evidence + +- claiming that a readiness score predicts search position or AI citation; +- awarding points for `llms.txt`, FAQ count, schema count, or a fixed meta-description length; +- automatic deployment of generated JSON-LD or crawler policy; +- adding more AI scorers and calling their average consensus. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..43a9b42 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,15 @@ +# Security policy + +## Supported versions + +Security fixes are applied to the latest published minor release. Older releases may be asked to upgrade when a backport is not practical. + +## Reporting a vulnerability + +Use GitHub's private vulnerability reporting for `cucuwang/aeoptimize` when available. If the repository does not show a private reporting option, open a minimal issue asking for a private contact channel; do not include exploit details, credentials, private URLs, or user data in a public issue. + +Include the affected version, environment, reproduction preconditions, impact, and the smallest safe proof of concept. You should receive an acknowledgement within seven days. A remediation timeline depends on severity and reproducibility. + +## Scope notes + +`aeoptimize` can fetch remote pages, invoke a local browser, read build output, and install a Git hook. Reports may contain URLs and excerpts from scanned content. Review artifacts before publishing them and never scan private systems without authorization. diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..a8bf8a7 --- /dev/null +++ b/action.yml @@ -0,0 +1,71 @@ +name: aeoptimize Content Readiness Check +description: Run the deterministic aeoptimize readiness lint against a build directory +branding: + icon: search + color: blue + +inputs: + path: + description: Build output directory to scan + required: true + default: dist + min-score: + description: Project-specific readiness threshold from 0 to 100 + required: false + default: '60' + fail-on-low-score: + description: Fail when the readiness score is below min-score + required: false + default: 'true' + +outputs: + score: + description: Deterministic readiness score from 0 to 100 + value: ${{ steps.scan.outputs.score }} + report: + description: JSON readiness report + value: ${{ steps.scan.outputs.report }} + +runs: + using: composite + steps: + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + + - name: Install aeoptimize + shell: bash + run: npm install --global aeoptimize@0.5.3 + + - name: Run readiness scan + id: scan + shell: bash + env: + INPUT_PATH: ${{ inputs.path }} + MIN_SCORE: ${{ inputs.min-score }} + FAIL_ON_LOW_SCORE: ${{ inputs.fail-on-low-score }} + run: | + case "$MIN_SCORE" in + ''|*[!0-9]*) echo "::error::min-score must be an integer from 0 to 100"; exit 2 ;; + esac + if [ "$MIN_SCORE" -lt 0 ] || [ "$MIN_SCORE" -gt 100 ]; then + echo "::error::min-score must be an integer from 0 to 100" + exit 2 + fi + + REPORT=$(aeoptimize scan "$INPUT_PATH" --dir --json 2>/dev/null) + SCORE=$(printf '%s' "$REPORT" | node -e "const fs=require('node:fs');const r=JSON.parse(fs.readFileSync(0,'utf8'));console.log(r.overall.total)") + + echo "score=$SCORE" >> "$GITHUB_OUTPUT" + { + echo 'report<> "$GITHUB_OUTPUT" + + echo "::notice::aeoptimize readiness score: $SCORE/100 (project threshold: $MIN_SCORE)" + if [ "$FAIL_ON_LOW_SCORE" = 'true' ] && [ "$SCORE" -lt "$MIN_SCORE" ]; then + echo "::error::Readiness score $SCORE is below the project threshold $MIN_SCORE" + exit 1 + fi diff --git a/action/action.yml b/action/action.yml index a2e68a8..a05b858 100644 --- a/action/action.yml +++ b/action/action.yml @@ -1,55 +1,71 @@ -name: 'AEO Score Check' -description: 'Check AI readability score of your website build output using aeoptimize' +name: aeoptimize Content Readiness Check +description: Compatibility path for the root aeoptimize readiness Action branding: - icon: 'search' - color: 'blue' + icon: search + color: blue inputs: path: - description: 'Path to scan (build output directory)' + description: Build output directory to scan required: true - default: 'dist' + default: dist min-score: - description: 'Minimum AEO score to pass (0-100)' + description: Project-specific readiness threshold from 0 to 100 required: false default: '60' fail-on-low-score: - description: 'Fail the action if score is below min-score' + description: Fail when the readiness score is below min-score required: false default: 'true' outputs: score: - description: 'Overall AEO score (0-100)' + description: Deterministic readiness score from 0 to 100 + value: ${{ steps.scan.outputs.score }} report: - description: 'Full JSON report' + description: JSON readiness report + value: ${{ steps.scan.outputs.report }} runs: - using: 'composite' + using: composite steps: - - name: Setup Node + - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '24' - name: Install aeoptimize shell: bash - run: npm install -g aeoptimize@0.5.3 + run: npm install --global aeoptimize@0.5.3 - - name: Run AEO scan + - name: Run readiness scan + id: scan shell: bash + env: + INPUT_PATH: ${{ inputs.path }} + MIN_SCORE: ${{ inputs.min-score }} + FAIL_ON_LOW_SCORE: ${{ inputs.fail-on-low-score }} run: | - REPORT=$(aeoptimize scan "${{ inputs.path }}" --dir --json 2>/dev/null) - SCORE=$(echo "$REPORT" | node -e "const j=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(j.overall.total)") + case "$MIN_SCORE" in + ''|*[!0-9]*) echo "::error::min-score must be an integer from 0 to 100"; exit 2 ;; + esac + if [ "$MIN_SCORE" -lt 0 ] || [ "$MIN_SCORE" -gt 100 ]; then + echo "::error::min-score must be an integer from 0 to 100" + exit 2 + fi - echo "score=$SCORE" >> $GITHUB_OUTPUT - echo "report<> $GITHUB_OUTPUT - echo "$REPORT" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT + REPORT=$(aeoptimize scan "$INPUT_PATH" --dir --json 2>/dev/null) + SCORE=$(printf '%s' "$REPORT" | node -e "const fs=require('node:fs');const r=JSON.parse(fs.readFileSync(0,'utf8'));console.log(r.overall.total)") - echo "::notice::AEO Score: $SCORE/100 (minimum: ${{ inputs.min-score }})" + echo "score=$SCORE" >> "$GITHUB_OUTPUT" + { + echo 'report<> "$GITHUB_OUTPUT" - if [ "${{ inputs.fail-on-low-score }}" = "true" ] && [ "$SCORE" -lt "${{ inputs.min-score }}" ]; then - echo "::error::AEO score $SCORE is below minimum ${{ inputs.min-score }}" + echo "::notice::aeoptimize readiness score: $SCORE/100 (project threshold: $MIN_SCORE)" + if [ "$FAIL_ON_LOW_SCORE" = 'true' ] && [ "$SCORE" -lt "$MIN_SCORE" ]; then + echo "::error::Readiness score $SCORE is below the project threshold $MIN_SCORE" exit 1 fi diff --git a/agents/aeo-ai-scorer.md b/agents/aeo-ai-scorer.md index f16de51..4c8310d 100644 --- a/agents/aeo-ai-scorer.md +++ b/agents/aeo-ai-scorer.md @@ -1,48 +1,19 @@ --- name: aeo-ai-scorer -description: Use when scoring a webpage's AI readability using Claude's language understanding, as part of the multi-AI scoring workflow in aeo-scan +description: Use only for an explicitly requested experimental content-quality review alongside the deterministic aeoptimize report model: inherit --- -You are an AEO (Answer Engine Optimization) scoring engine. Your job is to evaluate a webpage's AI search readiness and return a structured score. +You are an experimental content-quality reviewer. Your output is subjective and must not be presented as a prediction of ranking, indexing, rich results, visibility, or citation. -## Input +Review the supplied content for: -You will receive: -1. The page's HTML content (or text extract) -2. The rule engine's scan report (JSON) +- descriptive hierarchy, readability, and semantically appropriate lists; +- self-contained statements, sourced quantitative claims, definitions, and attribution; +- structured data that matches visible content; +- intentional indexing controls and page-specific descriptions; +- boilerplate and repetitive wording. -## Scoring Dimensions +FAQ content is optional. `llms.txt` is an unscored proposal. Do not impose a fixed meta-description length, exact H1 count, keyword-density threshold, or schema count. -Score each dimension on its scale: -- **structure** (0-25): Heading hierarchy quality, paragraph length (ideal: 40-80 words), FAQ sections, list usage -- **citability** (0-25): Self-contained statements (no dangling "This...", "It..."), data/statistics, clear definitions ("X is Y"), source attribution -- **schema** (0-20): JSON-LD presence and completeness, AI-relevant types (Article, FAQPage, HowTo, Product) -- **aiMetadata** (0-15): llms.txt reference, robots.txt AI crawler configuration, meta description quality (50-160 chars) -- **contentDensity** (0-15): Content vs boilerplate ratio, keyword stuffing (>3% = bad), content uniqueness signals - -## Output Format - -Respond with ONLY valid JSON: - -```json -{ - "score": , - "structure": <0-25>, - "citability": <0-25>, - "schema": <0-20>, - "aiMetadata": <0-15>, - "contentDensity": <0-15>, - "insight": "" -} -``` - -## Guidelines - -- Be objective and consistent — same content should get same score -- Compare against an ideal AEO-optimized page, not against average websites -- The rule engine already checks structural patterns; focus on semantic quality that rules can't measure: - - Can you actually extract a citable quote from each paragraph? - - Does the content answer a specific question or just ramble? - - Would you cite this page when answering a user's question? -- Do NOT inflate scores to be nice — a typical unoptimized page should score 30-50 +Return only the JSON shape requested by the caller. State the most important evidence-backed issue in `insight`. Repeated model runs may differ; the deterministic report remains the CI source of truth. diff --git a/agents/aeo-analyzer.md b/agents/aeo-analyzer.md index cb0bc67..0d5285f 100644 --- a/agents/aeo-analyzer.md +++ b/agents/aeo-analyzer.md @@ -1,63 +1,17 @@ --- name: aeo-analyzer -description: Use when deep-analyzing a specific page for AI optimization opportunities, dispatched by aeo-scan for detailed per-page analysis +description: Use when an explicit qualitative review is needed for a page after the deterministic readiness scan model: inherit --- -You are an AEO (Answer Engine Optimization) specialist. Your job is to analyze a single web page and produce a detailed, actionable report on how to improve its AI search readability. +You are a content-readiness reviewer. Separate deterministic findings, heuristics, and experiments; do not predict ranking or citation. -## Your Analysis Should Cover +For each proposed change: -1. **Issue-by-Issue Breakdown** - - For each issue found by the scanner, explain WHY it matters for AI citation - - Reference specific content in the page (quote the problematic text) - - Rate fix difficulty: easy (5 min), medium (30 min), hard (1+ hour) +1. quote the smallest relevant source passage; +2. name the evidence class and false-positive boundary; +3. provide a focused before/after diff; +4. preserve meaning, voice, and factual provenance; +5. state a deterministic score change only when the same scan reproduces it. -2. **Prioritized Fix Recommendations** - - Order by: (impact on score) × (ease of implementation) - - Group related fixes together - - Estimate score improvement per fix - -3. **Before/After Examples** - - For the top 3 improvements, show exactly how the content should change - - Use diff format: what to remove vs what to add - - Explain why the "after" version is more AI-friendly - -4. **Content Strategy Notes** - - What type of AI queries would this page answer? - - What's missing that would make it the definitive source? - - Are there FAQ opportunities hidden in the content? - -## Output Format - -Structure your analysis as: - -``` -## Page: [title] -Current Score: [X]/100 - -### Priority Fixes - -#### 1. [Fix Name] — Expected improvement: +N points -**Issue:** [what's wrong] -**Why it matters:** [AI search impact] -**Fix:** -- Before: [quoted original] -- After: [suggested replacement] - -[repeat for each fix] - -### Quick Wins (under 5 minutes each) -- [list of easy fixes] - -### Summary -- Current: X/100 → Estimated after fixes: Y/100 -- Most impactful change: [one sentence] -``` - -## Guidelines - -- Be specific — quote actual content, don't speak in generalities -- Focus on what AI engines actually care about, not traditional SEO metrics -- If the page is already well-optimized (>80), say so and suggest only minor refinements -- Never suggest adding false claims or misleading structured data +Prioritize unsupported quantitative claims, unintended indexing controls, structured data that conflicts with visible content, and clear readability regressions. Never invent claims, sources, authors, dates, FAQ content, or benefits. Use primary documentation for technical assertions. diff --git a/docs/methodology.md b/docs/methodology.md new file mode 100644 index 0000000..d24b014 --- /dev/null +++ b/docs/methodology.md @@ -0,0 +1,78 @@ +# Methodology and limitations + +This document describes the v0.6 draft scoring contract. `aeoptimize` is a deterministic content-readiness linter. Its score is not a forecast of ranking, indexing, rich-result eligibility, AI visibility, or citation. + +## Evidence classes + +Every rule belongs to one of four classes: + +| Class | Meaning | Allowed use | +| --- | --- | --- | +| A — official requirement | A current first-party specification or product document defines the behavior. | A rule may report a technical error within the documented scope. | +| B — deterministic implementation check | The tool can reproduce the property, but the property may be optional or context-dependent. | A rule may guard regressions and must state when it does not apply. | +| C — content heuristic | A configurable proxy for readability or maintainability with known false positives. | A rule may suggest review; it must not claim search or citation effects. | +| D — experiment | Adoption or effect is not established by an authoritative source. | Informational output only; no readiness points. | + +## Score contract + +The total remains 0–100 for backward-compatible CI output. Compare scores only for the same project, aeoptimize version, configuration, and fixture set. A higher score means fewer findings under this rule set; it does not mean a higher probability of an external outcome. + +| Rule | Points | Class | What is actually checked | +| --- | ---: | --- | --- | +| `heading-hierarchy` | 10 | C | Presence of headings, skipped levels, and a review hint when no H1 is exposed. Multiple H1 elements are not an automatic error. | +| `paragraph-length` | 8 | C | Paragraphs above a 150-word review threshold. The threshold is not a ranking factor. | +| `faq-presence` | 0 | D | Optional question-and-answer structure; no score impact. | +| `list-usage` | 7 | C | Long pages without list markup receive a review suggestion. Lists should be used only for genuine sets or sequences. | +| `self-contained-statements` | 8 | C | Paragraphs beginning with selected pronouns or transition words. Context can make these starts correct. | +| `data-stats-presence` | 7 | B/C | Quantitative claims are not rewarded for existing. Claims without a detectable source signal are flagged. | +| `clear-definitions` | 5 | C | Simple definition-language patterns. This cannot judge factual accuracy. | +| `attribution` | 5 | C | Author, date, and source signals. These fields are not applicable to every page type. | +| `json-ld-presence` | 8 | B | Presence of JSON-LD. Absence is informational and receives no penalty because structured data is optional. | +| `json-ld-completeness` | 12 | B | Universal `@context` and `@type` structure plus article-specific review hints. Feature-specific validation remains manual. | +| `ai-relevant-schema-types` | 0 | D | Schema type count has no score impact. More types are not inherently better. | +| `llms-txt-presence` | 0 | D | Presence of the llms.txt proposal; no score impact. | +| `robots-txt-ai-config` | 8 | A/B | Page-level `noindex`. Site robots rules, CDN controls, and crawler identities require separate verification. | +| `meta-description-quality` | 7 | B/C | Missing, generic, or keyword-list descriptions. There is no fixed 50–160 character rule. | +| `content-boilerplate-ratio` | 5 | C | Ratio of extracted paragraph text to total text. Templates and non-article pages can be false positives. | +| `keyword-stuffing-detection` | 5 | C | Vocabulary diversity plus repeated terms across adjacent sentences. Language and domain terminology affect results. | +| `content-uniqueness-signals` | 5 | C | Presence of selected original-data language or code examples. Absence is not proof of low quality. | + +## Explicit exclusions + +- Google says its AI search features require no special AI text file, special markup, or additional schema beyond established Search requirements. `llms.txt` therefore carries zero points. +- llmstxt.org describes `llms.txt` as a proposal and does not define how clients must process it. +- Structured data can make a page eligible for a supported search feature; valid markup does not guarantee display. +- Google does not specify a meta-description length limit. Snippets may come from page content and can vary by query. +- The tool does not treat exactly one H1, FAQ count, a fixed keyword density, or the number of schema types as outcome factors. +- AI CLI reviews are subjective experiments. The legacy `consensusScore` field remains for compatibility but is presented as an experimental blend, not consensus or ground truth. + +## Generator safety + +Generated output is a candidate for review, not deployment-ready truth. + +- `FAQPage` is never inferred from question headings. +- Candidate JSON-LD must agree with visible content and the applicable feature documentation. +- `llms.txt` and `llms-full.txt` are experimental adapters. +- Crawler suggestions distinguish search, user-initiated browsing, and model-training controls. Allowing a bot does not guarantee crawling, indexing, or citation. + +## Validation policy + +A scoring-rule change must include: + +1. the evidence class and primary source or explicit heuristic rationale; +2. at least one positive fixture, one negative fixture, and one false-positive boundary; +3. the expected JSON change and migration impact; +4. no claim that the rule improves ranking or citation without a preregistered outcome study and public data. + +The v0.6 evidence release will version a public fixture corpus and publish rule-level change notes. Outcome research, if added later, will be reported separately from the readiness score. + +## Primary sources + +- [Google Search: AI features and your website](https://developers.google.com/search/docs/appearance/ai-features) +- [Google Search: structured data general guidelines](https://developers.google.com/search/docs/appearance/structured-data/sd-policies) +- [Google Search: snippets and meta descriptions](https://developers.google.com/search/docs/appearance/snippet) +- [Google Search: title links](https://developers.google.com/search/docs/appearance/title-link) +- [Google Search: robots meta tag](https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag) +- [llms.txt proposal](https://llmstxt.org/) + +Last reviewed: 2026-08-15. diff --git a/docs/superpowers/specs/2026-04-07-framework-plugins-design.md b/docs/superpowers/specs/2026-04-07-framework-plugins-design.md index 880e7e4..50e4db5 100644 --- a/docs/superpowers/specs/2026-04-07-framework-plugins-design.md +++ b/docs/superpowers/specs/2026-04-07-framework-plugins-design.md @@ -1,5 +1,7 @@ # Framework Plugins Design — Vite + Next.js +> Historical design note. The v0.6 methodology supersedes AEO outcome language in this document; current behavior and limitations are defined in `docs/methodology.md`. + ## Goal Add build-time AEO optimization to Vite and Next.js projects. On build, automatically scan output, generate llms.txt + JSON-LD, and print AEO score. Zero config required. diff --git a/package-lock.json b/package-lock.json index 98922e5..f9da6b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,422 +1,32 @@ { "name": "aeoptimize", - "version": "0.4.1", + "version": "0.5.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "aeoptimize", - "version": "0.4.1", + "version": "0.5.3", "license": "MIT", "dependencies": { "chalk": "^5.3.0", - "cheerio": "^1.0.0", + "cheerio": "^1.2.0", "commander": "^12.0.0", "gray-matter": "^4.0.3", - "puppeteer-core": "^24.0.0" + "puppeteer-core": "^25.7.0" }, "bin": { "aeo": "dist/cli/index.js", - "aeo-cli": "dist/cli/index.js" + "aeo-cli": "dist/cli/index.js", + "aeoptimize": "dist/cli/index.js" }, "devDependencies": { - "@types/node": "^20.0.0", + "@types/node": "^24.0.0", "typescript": "^5.4.0", - "vitest": "^2.0.0" + "vitest": "^4.1.10" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" + "node": ">=22.12.0" } }, "node_modules/@jridgewell/sourcemap-codec": { @@ -426,45 +36,48 @@ "dev": true, "license": "MIT" }, + "node_modules/@oxc-project/types": { + "version": "0.144.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.144.0.tgz", + "integrity": "sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, "node_modules/@puppeteer/browsers": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.0.tgz", - "integrity": "sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.2.0.tgz", + "integrity": "sha512-LlBrE8oqGfU7b1Nk2d5Q1SbuPhZxTj0cJEMDPEws28OjNMELlflekmPPuf4FnK03x0ZRjKaYwJElUcKK4kyqJA==", "license": "Apache-2.0", "dependencies": { - "debug": "^4.4.3", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.5.0", - "semver": "^7.7.4", - "tar-fs": "^3.1.1", - "yargs": "^17.7.2" + "modern-tar": "^0.8.0", + "yargs": "^18.0.0" }, "bin": { - "browsers": "lib/cjs/main-cli.js" + "browsers": "lib/main-cli.js" }, "engines": { - "node": ">=18" + "node": ">=22.12.0" + }, + "peerDependencies": { + "proxy-agent": ">=8.0.1", + "yauzl": "^2.10.0 || ^3.4.0" + }, + "peerDependenciesMeta": { + "proxy-agent": { + "optional": true + }, + "yauzl": { + "optional": true + } } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", - "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", - "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.4.tgz", + "integrity": "sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA==", "cpu": [ "arm64" ], @@ -473,12 +86,15 @@ "optional": true, "os": [ "android" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", - "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-Dc5mPD8F5F/FS8i01syd7FTF6yB2fVthH/TRkjwJkzUK6EpoxHtqvZQP5Zwq80/5z19TWYHIg1KOHboCgVx/aQ==", "cpu": [ "arm64" ], @@ -487,12 +103,15 @@ "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", - "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.4.tgz", + "integrity": "sha512-fpDm4oBo6SqLvWUYCmFhdde3U9KH2fRNNMeAnAPAIwxRL345xutL0EtEUcuoxsoazdJGv/MuDBQHlCDrtbvqOg==", "cpu": [ "x64" ], @@ -501,26 +120,15 @@ "optional": true, "os": [ "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", - "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", - "cpu": [ - "arm64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", - "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.4.tgz", + "integrity": "sha512-rSJoreDE/HoIzoaib6MTp5jQtCTdMHKIvItAKT/ImS6Y6Ww76oUaeMyp4Vc/fAgd/ehji068IxetHXAnqUwN9A==", "cpu": [ "x64" ], @@ -529,84 +137,36 @@ "optional": true, "os": [ "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", - "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", - "cpu": [ - "arm" ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", - "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.4.tgz", + "integrity": "sha512-/jm8OGHgn7oGaJu3i/qZI9spUGcJ+y/lk43ttQ/iO1tOd9NissG6o97bighBCiL+BKRngmcDuR6ikfwYdJmVuQ==", "cpu": [ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", - "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", - "cpu": [ - "arm64" ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", - "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.4.tgz", + "integrity": "sha512-tIP06BeD9EqvECBrPZ+sqdPlYrT+aYaAiu1wYziVx5elRK/ftm33JxVDy2bXGbr6J0CrtirCkR87/X5a2euEng==", "cpu": [ "arm64" ], "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", - "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", - "cpu": [ - "loong64" - ], - "dev": true, "libc": [ "glibc" ], @@ -614,14 +174,17 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", - "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.4.tgz", + "integrity": "sha512-Ql1Q0EQqVThvn9VAVlwNzsUvbSFtCMGjLpRRi4pk5i7NZZ4n5ISiLMjHYtus4VQ2PvkSw24zyaCVsiS+sXPj1w==", "cpu": [ - "loong64" + "arm64" ], "dev": true, "libc": [ @@ -631,50 +194,19 @@ "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", - "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", - "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.4.tgz", + "integrity": "sha512-GjbjXD4XXfN19D0LZNbmiCBUoDiRACsYHr0yaIbbn8aFsXjHZifcYqu/W5Er5X2X990WjHXFrxarn5chzItorQ==", "cpu": [ "ppc64" ], "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", - "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", - "cpu": [ - "riscv64" - ], - "dev": true, "libc": [ "glibc" ], @@ -682,29 +214,15 @@ "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", - "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", - "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.4.tgz", + "integrity": "sha512-p5WR0NOwaRmJ/B1b6IjEFLLivwEsf3PrdBIhRbhTCQisbo2SvHHpG4ELB/+FgQNnB88LTOF86upmJmbvZdQ2lw==", "cpu": [ "s390x" ], @@ -716,12 +234,15 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz", - "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.4.tgz", + "integrity": "sha512-4/GyVjmhR+Tc6HLJvwc1sOhPqAZtySiSMesOZyX6JQ5XBxoTDEMKQzvo07NIK6nTon/SivlZqvhzvuVBNQhObQ==", "cpu": [ "x64" ], @@ -733,12 +254,15 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", - "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.4.tgz", + "integrity": "sha512-l9eeLsCNvPpmSXUej0etw/J1eqV0Jj1D5G/xG6YTijmE6dkv6E2QezgWbTfQk63v952DPqrjOCoiqxq7Bw0YUQ==", "cpu": [ "x64" ], @@ -750,26 +274,15 @@ "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", - "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", - "cpu": [ - "x64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", - "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.4.tgz", + "integrity": "sha512-e0F355MSTMm3+UOqtV3L24gFUp2N5m1f8L/7d56deik6va+AXdrt9F8LbzGpeWGWRbZEDq4m8NVnJDeBtf9DZg==", "cpu": [ "arm64" ], @@ -778,12 +291,15 @@ "optional": true, "os": [ "openharmony" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", - "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.4.tgz", + "integrity": "sha512-AWLi0uBRYh6QlE7OKhiz+phZC0qwtij2QZmhmOdsLdFn64m7oMpooE9ICE3lhm9xMb4SpDo2WbHcxX1iFLFtqw==", "cpu": [ "arm64" ], @@ -792,26 +308,15 @@ "optional": true, "os": [ "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", - "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", - "cpu": [ - "ia32" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", - "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.4.tgz", + "integrity": "sha512-UwSDJOg3dqCAejWdxclJjCsh3Qq4vLYMDxmyHqo1btz3stK2VqgwNd3mm5tuIwzSlGIQ/1H9Hr+Zn09mrezNqQ==", "cpu": [ "x64" ], @@ -820,88 +325,95 @@ "optional": true, "os": [ "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", - "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", - "cpu": [ - "x64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, "license": "MIT" }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, - "node_modules/@types/node": { - "version": "20.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz", - "integrity": "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==", - "devOptional": true, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", + "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@types/node": "*" + "undici-types": "~7.18.0" } }, "node_modules/@vitest/expect": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", - "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.1.9", - "@vitest/utils": "2.1.9", - "chai": "^5.1.2", - "tinyrainbow": "^1.2.0" + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/mocker": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", - "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.1.9", + "@vitest/spy": "4.1.10", "estree-walker": "^3.0.3", - "magic-string": "^0.30.12" + "magic-string": "^0.30.21" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { @@ -913,103 +425,92 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", - "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^1.2.0" + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", - "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "2.1.9", - "pathe": "^1.1.2" + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", - "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.9", - "magic-string": "^0.30.12", - "pathe": "^1.1.2" + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", - "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", "dev": true, "license": "MIT", - "dependencies": { - "tinyspy": "^3.0.2" - }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", - "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.9", - "loupe": "^3.1.2", - "tinyrainbow": "^1.2.0" + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" @@ -1034,170 +535,18 @@ "node": ">=12" } }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/b4a": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", - "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", - "license": "Apache-2.0", - "peerDependencies": { - "react-native-b4a": "*" - }, - "peerDependenciesMeta": { - "react-native-b4a": { - "optional": true - } - } - }, - "node_modules/bare-events": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", - "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", - "license": "Apache-2.0", - "peerDependencies": { - "bare-abort-controller": "*" - }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - } - } - }, - "node_modules/bare-fs": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.6.0.tgz", - "integrity": "sha512-2YkS7NuiJceSEbyEOdSNLE9tsGd+f4+f7C+Nik/MCk27SYdwIMPT/yRKvg++FZhQXgk0KWJKJyXX9RhVV0RGqA==", - "license": "Apache-2.0", - "dependencies": { - "bare-events": "^2.5.4", - "bare-path": "^3.0.0", - "bare-stream": "^2.6.4", - "bare-url": "^2.2.2", - "fast-fifo": "^1.3.2" - }, - "engines": { - "bare": ">=1.16.0" - }, - "peerDependencies": { - "bare-buffer": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - } - } - }, - "node_modules/bare-os": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.8.7.tgz", - "integrity": "sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w==", - "license": "Apache-2.0", - "engines": { - "bare": ">=1.14.0" - } - }, - "node_modules/bare-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", - "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", - "license": "Apache-2.0", - "dependencies": { - "bare-os": "^3.0.1" - } - }, - "node_modules/bare-stream": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.12.0.tgz", - "integrity": "sha512-w28i8lkBgREV3rPXGbgK+BO66q+ZpKqRWrZLiCdmmUlLPrQ45CzkvRhN+7lnv00Gpi2zy5naRxnUFAxCECDm9g==", - "license": "Apache-2.0", - "dependencies": { - "streamx": "^2.25.0", - "teex": "^1.0.1" - }, - "peerDependencies": { - "bare-abort-controller": "*", - "bare-buffer": "*", - "bare-events": "*" - }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - }, - "bare-buffer": { - "optional": true - }, - "bare-events": { - "optional": true - } - } - }, - "node_modules/bare-url": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.0.tgz", - "integrity": "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==", - "license": "Apache-2.0", - "dependencies": { - "bare-path": "^3.0.0" - } - }, - "node_modules/basic-ftp": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", - "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "license": "ISC" }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, "engines": { "node": ">=18" } @@ -1214,16 +563,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, "node_modules/cheerio": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", @@ -1267,50 +606,52 @@ } }, "node_modules/chromium-bidi": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-14.0.0.tgz", - "integrity": "sha512-9gYlLtS6tStdRWzrtXaTMnqcM4dudNegMXJxkR0I/CXObHalYeYcAMPrL19eroNZHtJ8DQmu1E+ZNOYu/IXMXw==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-17.0.2.tgz", + "integrity": "sha512-5v9GQFhTktFvotn/OFNJBmKLKRAb6n9r0bVCwf7sHgWc3/JryK0bj1nn93L3pHFrfgcsu6Be6EWsDi+1XHTGDg==", "license": "Apache-2.0", "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1" }, + "engines": { + "node": ">=20.19.0 <22.0.0 || >=22.12.0" + }, "peerDependencies": { "devtools-protocol": "*" } }, "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", "license": "ISC", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=12" + "node": ">=20" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -1320,6 +661,13 @@ "node": ">=18" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/css-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", @@ -1348,60 +696,20 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "license": "MIT", - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">= 14" + "node": ">=8" } }, "node_modules/devtools-protocol": { - "version": "0.0.1581282", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1581282.tgz", - "integrity": "sha512-nv7iKtNZQshSW2hKzYNr46nM/Cfh5SEvE2oV0/SEGgc9XupIY5ggf84Cz8eJIkBce7S3bmTAauFD6aysMpnqsQ==", + "version": "0.0.1666840", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1666840.tgz", + "integrity": "sha512-gCcO42XCHKEs7Ag0S7aGYsnJ7hlgrO3qderYqeiY0Eqk+0GFfuvT13IA0hHreJTa2KCdDVyGMeOhdMNmrrTjVg==", "license": "BSD-3-Clause" }, "node_modules/dom-serializer": { @@ -1460,9 +768,9 @@ } }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "license": "MIT" }, "node_modules/encoding-sniffer": { @@ -1478,15 +786,6 @@ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" } }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -1500,51 +799,12 @@ } }, "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", "dev": true, "license": "MIT" }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -1554,27 +814,6 @@ "node": ">=6" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -1588,15 +827,6 @@ "node": ">=4" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", @@ -1607,24 +837,6 @@ "@types/estree": "^1.0.0" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/events-universal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", - "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", - "license": "Apache-2.0", - "dependencies": { - "bare-events": "^2.7.0" - } - }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -1647,39 +859,22 @@ "node": ">=0.10.0" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 10.17.0" + "node": ">=12.0.0" }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "license": "MIT" - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, "node_modules/fsevents": { @@ -1706,35 +901,18 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-uri": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", - "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", - "license": "MIT", - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/gray-matter": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", @@ -1781,32 +959,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -1819,15 +971,6 @@ "node": ">=0.10.0" } }, - "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -1837,51 +980,299 @@ "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", + "integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "license": "MIT", + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "license": "ISC", + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=12" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/magic-string": { @@ -1900,16 +1291,19 @@ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "license": "MIT" }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" + "node_modules/modern-tar": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.8.4.tgz", + "integrity": "sha512-gN54ddmyzEg10orwZ2u4OOv+bjpMWdIl5jIkodK97bMq8QBSL5c0D7YX0lT1Ooz+99S7+PvFbnxzdjgHo1r41g==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "dev": true, "funding": [ { @@ -1925,15 +1319,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/netmask": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.0.tgz", - "integrity": "sha512-z9sZrk6wyf8/NDKKqe+Tyl58XtgkYrV4kgt1O8xrzYvpl1LvPacPo0imMLHfpStk3kgCIq1ksJ2bmJn9hue2lQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -1946,45 +1331,18 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/pac-proxy-agent": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", - "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", - "license": "MIT", - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.6", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "node_modules/obug": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], "license": "MIT", - "dependencies": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - }, "engines": { - "node": ">= 14" + "node": ">=12.20.0" } }, "node_modules/parse5": { @@ -2037,26 +1395,10 @@ } }, "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, "node_modules/picocolors": { @@ -2066,10 +1408,23 @@ "dev": true, "license": "ISC" }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", "dev": true, "funding": [ { @@ -2087,7 +1442,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.17", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -2095,120 +1450,54 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proxy-agent": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", - "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.6", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.1.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/puppeteer-core": { - "version": "24.40.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.40.0.tgz", - "integrity": "sha512-MWL3XbUCfVgGR0gRsidzT6oKJT2QydPLhMITU6HoVWiiv4gkb6gJi3pcdAa8q4HwjBTbqISOWVP4aJiiyUJvag==", + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-25.7.0.tgz", + "integrity": "sha512-wgBBj7dU5ceGyoT2PCrJpkYOhxPY8mDOmcSKZP92Cj5GgqQ3kv/UxzawnOLxiYuupe4bDf/yiQm3bzs/1nI0rQ==", "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.13.0", - "chromium-bidi": "14.0.0", - "debug": "^4.4.3", - "devtools-protocol": "0.0.1581282", - "typed-query-selector": "^2.12.1", - "webdriver-bidi-protocol": "0.4.1", - "ws": "^8.19.0" + "@puppeteer/browsers": "3.2.0", + "chromium-bidi": "17.0.2", + "devtools-protocol": "0.0.1666840", + "typed-query-selector": "^2.12.2", + "webdriver-bidi-protocol": "0.4.2", + "ws": "^8.21.1" }, "engines": { - "node": ">=18" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "node": ">=22.12.0" } }, - "node_modules/rollup": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", - "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", + "node_modules/rolldown": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.4.tgz", + "integrity": "sha512-rSr7irW0K7QRWzjdJXqZowkcRdDtjRduh43rBltnVKd0VFq839l1lJoDvGJb6gl7+4rTTCrPWu+YfujUL8Ug7w==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.8" + "@oxc-project/types": "=0.144.0", + "@rolldown/pluginutils": "^1.0.0" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.60.1", - "@rollup/rollup-android-arm64": "4.60.1", - "@rollup/rollup-darwin-arm64": "4.60.1", - "@rollup/rollup-darwin-x64": "4.60.1", - "@rollup/rollup-freebsd-arm64": "4.60.1", - "@rollup/rollup-freebsd-x64": "4.60.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", - "@rollup/rollup-linux-arm-musleabihf": "4.60.1", - "@rollup/rollup-linux-arm64-gnu": "4.60.1", - "@rollup/rollup-linux-arm64-musl": "4.60.1", - "@rollup/rollup-linux-loong64-gnu": "4.60.1", - "@rollup/rollup-linux-loong64-musl": "4.60.1", - "@rollup/rollup-linux-ppc64-gnu": "4.60.1", - "@rollup/rollup-linux-ppc64-musl": "4.60.1", - "@rollup/rollup-linux-riscv64-gnu": "4.60.1", - "@rollup/rollup-linux-riscv64-musl": "4.60.1", - "@rollup/rollup-linux-s390x-gnu": "4.60.1", - "@rollup/rollup-linux-x64-gnu": "4.60.1", - "@rollup/rollup-linux-x64-musl": "4.60.1", - "@rollup/rollup-openbsd-x64": "4.60.1", - "@rollup/rollup-openharmony-arm64": "4.60.1", - "@rollup/rollup-win32-arm64-msvc": "4.60.1", - "@rollup/rollup-win32-ia32-msvc": "4.60.1", - "@rollup/rollup-win32-x64-gnu": "4.60.1", - "@rollup/rollup-win32-x64-msvc": "4.60.1", - "fsevents": "~2.3.2" + "@rolldown/binding-android-arm64": "1.2.4", + "@rolldown/binding-darwin-arm64": "1.2.4", + "@rolldown/binding-darwin-x64": "1.2.4", + "@rolldown/binding-freebsd-x64": "1.2.4", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.4", + "@rolldown/binding-linux-arm64-gnu": "1.2.4", + "@rolldown/binding-linux-arm64-musl": "1.2.4", + "@rolldown/binding-linux-ppc64-gnu": "1.2.4", + "@rolldown/binding-linux-s390x-gnu": "1.2.4", + "@rolldown/binding-linux-x64-gnu": "1.2.4", + "@rolldown/binding-linux-x64-musl": "1.2.4", + "@rolldown/binding-openharmony-arm64": "1.2.4", + "@rolldown/binding-win32-arm64-msvc": "1.2.4", + "@rolldown/binding-win32-x64-msvc": "1.2.4" } }, "node_modules/safer-buffer": { @@ -2230,18 +1519,6 @@ "node": ">=4" } }, - "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -2249,54 +1526,6 @@ "dev": true, "license": "ISC" }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", - "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", - "license": "MIT", - "dependencies": { - "ip-address": "^10.0.1", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -2321,47 +1550,41 @@ "license": "MIT" }, "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", "dev": true, "license": "MIT" }, - "node_modules/streamx": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.25.0.tgz", - "integrity": "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==", - "license": "MIT", - "dependencies": { - "events-universal": "^1.0.0", - "fast-fifo": "^1.3.2", - "text-decoder": "^1.1.0" - } - }, "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" }, "engines": { - "node": ">=8" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/strip-bom-string": { @@ -2373,50 +1596,6 @@ "node": ">=0.10.0" } }, - "node_modules/tar-fs": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.2.tgz", - "integrity": "sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0" - } - }, - "node_modules/tar-stream": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.8.tgz", - "integrity": "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==", - "license": "MIT", - "dependencies": { - "b4a": "^1.6.4", - "bare-fs": "^4.5.5", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "node_modules/teex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", - "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", - "license": "MIT", - "dependencies": { - "streamx": "^2.12.5" - } - }, - "node_modules/text-decoder": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", - "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", - "license": "Apache-2.0", - "dependencies": { - "b4a": "^1.6.4" - } - }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -2425,52 +1604,46 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.0.tgz", + "integrity": "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==", "dev": true, "license": "MIT", "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": ">=18" } }, - "node_modules/tinyrainbow": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", - "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "dev": true, "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, "engines": { - "node": ">=14.0.0" + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinyspy": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", - "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "node_modules/tinyrainbow": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", + "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", "dev": true, "license": "MIT", "engines": { "node": ">=14.0.0" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, "node_modules/typed-query-selector": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.1.tgz", - "integrity": "sha512-uzR+FzI8qrUEIu96oaeBJmd9E7CFEiQ3goA5qCVgc4s5llSubcfGHq9yUstZx/k4s9dXHVKsE35YWoFyvEqEHA==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.2.tgz", + "integrity": "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==", "license": "MIT" }, "node_modules/typescript": { @@ -2488,37 +1661,39 @@ } }, "node_modules/undici": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.7.tgz", - "integrity": "sha512-H/nlJ/h0ggGC+uRL3ovD+G0i4bqhvsDOpbDv7At5eFLlj2b41L8QliGbnl2H7SnDiYhENphh1tQFJZf+MyfLsQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz", + "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==", "license": "MIT", "engines": { "node": ">=20.18.1" } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "devOptional": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, "license": "MIT" }, "node_modules/vite": { - "version": "5.4.21", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", - "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.1.tgz", + "integrity": "sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "lightningcss": "^1.33.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.25", + "rolldown": "~1.2.1", + "tinyglobby": "^0.2.17" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -2527,23 +1702,33 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.4.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.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 }, - "less": { + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { "optional": true }, - "lightningcss": { + "less": { "optional": true }, "sass": { @@ -2560,85 +1745,89 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, - "node_modules/vite-node": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", - "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.7", - "es-module-lexer": "^1.5.4", - "pathe": "^1.1.2", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/vitest": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", - "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "2.1.9", - "@vitest/mocker": "2.1.9", - "@vitest/pretty-format": "^2.1.9", - "@vitest/runner": "2.1.9", - "@vitest/snapshot": "2.1.9", - "@vitest/spy": "2.1.9", - "@vitest/utils": "2.1.9", - "chai": "^5.1.2", - "debug": "^4.3.7", - "expect-type": "^1.1.0", - "magic-string": "^0.30.12", - "pathe": "^1.1.2", - "std-env": "^3.8.0", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.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": "^4.0.0-rc.1", "tinybench": "^2.9.0", - "tinyexec": "^0.3.1", - "tinypool": "^1.0.1", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0", - "vite-node": "2.1.9", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.1.9", - "@vitest/ui": "2.1.9", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, + "@opentelemetry/api": { + "optional": true + }, "@types/node": { "optional": true }, - "@vitest/browser": { + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { "optional": true }, "@vitest/ui": { @@ -2649,13 +1838,16 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, "node_modules/webdriver-bidi-protocol": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.1.tgz", - "integrity": "sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.2.tgz", + "integrity": "sha512-VSV+fzfChirL3e7jay2yUC7B4HQCGtEWEg/MSSQbK+qWbqeGlRLlXTzPpYr3XGUvbpDHumWZBJxgesg4N7dbtA==", "license": "Apache-2.0" }, "node_modules/whatwg-encoding": { @@ -2698,32 +1890,43 @@ } }, "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/ws": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", - "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -2751,40 +1954,29 @@ } }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz", + "integrity": "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==", "license": "MIT", "dependencies": { - "cliui": "^8.0.1", + "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^8.2.1", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^22.0.0" }, "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", "license": "ISC", "engines": { - "node": ">=12" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/zod": { diff --git a/package.json b/package.json index 25bdbff..5c402b0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "aeoptimize", "version": "0.5.3", - "description": "CLI toolkit that transforms SEO-optimized websites into AI-search-ready content", + "description": "Deterministic content-readiness lint for static websites and documentation", "type": "module", "main": "./dist/core/index.js", "bin": { @@ -19,15 +19,21 @@ "skills/", "agents/", ".claude-plugin/", + "docs/methodology.md", + "CHANGELOG.md", + "CONTRIBUTING.md", + "ROADMAP.md", + "SECURITY.md", "README.md", "LICENSE" ], "scripts": { "build": "tsc", + "check": "npm test && npm run build", "dev": "tsc --watch", "test": "vitest run", "test:watch": "vitest", - "prepublishOnly": "npm test && npm run build" + "prepublishOnly": "npm run check" }, "keywords": [ "aeo", @@ -41,25 +47,28 @@ "vite-plugin", "nextjs-plugin" ], - "homepage": "https://github.com/dexuwang627-cloud/aeoptimize", + "homepage": "https://github.com/cucuwang/aeoptimize", "repository": { "type": "git", - "url": "https://github.com/dexuwang627-cloud/aeoptimize.git" + "url": "https://github.com/cucuwang/aeoptimize.git" + }, + "bugs": { + "url": "https://github.com/cucuwang/aeoptimize/issues" }, "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=22.12.0" }, "dependencies": { "chalk": "^5.3.0", - "puppeteer-core": "^24.0.0", - "cheerio": "^1.0.0", + "puppeteer-core": "^25.7.0", + "cheerio": "^1.2.0", "commander": "^12.0.0", "gray-matter": "^4.0.3" }, "devDependencies": { - "@types/node": "^20.0.0", + "@types/node": "^24.0.0", "typescript": "^5.4.0", - "vitest": "^2.0.0" + "vitest": "^4.1.10" } } diff --git a/skills/aeo-generate/SKILL.md b/skills/aeo-generate/SKILL.md index 087d265..48d333f 100644 --- a/skills/aeo-generate/SKILL.md +++ b/skills/aeo-generate/SKILL.md @@ -1,53 +1,35 @@ --- name: aeo-generate -description: Use when creating llms.txt, JSON-LD structured data, or robots.txt AI crawler configuration for a website or project build output +description: Use when previewing optional llms.txt proposal files, candidate JSON-LD, or crawler-control suggestions for a website build --- -# AEO Generate — AI Infrastructure Files +# AEO Generate — Optional Discovery Artifacts -Generate AI infrastructure files from existing website content to make it discoverable by AI search engines. - -## What Gets Generated - -| File | Purpose | -|------|---------| -| `llms.txt` | Machine-readable site summary for LLMs (llmstxt.org standard) | -| `llms-full.txt` | Full content version for deep AI consumption | -| `_aeo/generated-schemas.json` | JSON-LD schemas (Article, FAQPage, BreadcrumbList) | -| robots.txt suggestions | AI crawler allow/deny rules (printed, not auto-applied) | +Generate reviewable candidate artifacts. These files do not guarantee crawling, indexing, search features, visibility, or citation. ## Workflow -1. **Identify build output.** Ask the user for the directory containing their built site (e.g., `dist/`, `out/`, `build/`). Check for common framework patterns: - - Next.js: `.next/` or `out/` - - Vite/Astro: `dist/` - - Hugo/Jekyll: `public/` +1. Identify an authorized static build directory. +2. Preview without writing: -2. **Preview first.** Run: + ```bash + npx aeoptimize generate --dry-run ``` - npx aeoptimize generate --dry-run - ``` - Show the user what will be generated and explain each file's purpose. -3. **Confirm and generate.** On approval: - ``` - npx aeoptimize generate - ``` - -4. **Review generated files.** Read each generated file and suggest manual refinements: - - `llms.txt`: Verify site name, description, and page listing are accurate - - JSON-LD: Check that generated schemas match the actual content - - robots.txt: Explain each AI crawler and let user decide allow/deny +3. Review every output: + - `llms.txt` and `llms-full.txt` are experiments based on a proposal. + - Candidate `Article` or `BreadcrumbList` JSON-LD must match visible content. + - Crawler rules have service-specific meanings; an allow rule is not an outcome guarantee. +4. Write only after the user approves the exact directory: -5. **Integration guidance.** Explain how to deploy: - - Place `llms.txt` at site root (alongside `robots.txt`) - - Add `` to HTML `` - - Inject generated JSON-LD into page `` sections - - Merge robots.txt suggestions with existing rules + ```bash + npx aeoptimize generate + ``` -## Important +## Boundaries -- Always preview with `--dry-run` before writing -- Never overwrite existing files without user confirmation -- Suggest running `/aeo-scan` first to understand current state -- The robots.txt suggestions are printed only — never auto-modify robots.txt +- Never overwrite an existing artifact without confirmation and a recoverable copy. +- Never infer `FAQPage` from question headings. +- Never add `` as if it were a standardized discovery mechanism. +- Never auto-apply `robots.txt` suggestions. +- Validate structured data against current primary documentation before deployment. diff --git a/skills/aeo-scan/SKILL.md b/skills/aeo-scan/SKILL.md index f33d6a5..66af37c 100644 --- a/skills/aeo-scan/SKILL.md +++ b/skills/aeo-scan/SKILL.md @@ -1,78 +1,31 @@ --- name: aeo-scan -description: Use when auditing a website or build output for AI search readiness, checking AI readability scores, or diagnosing why content isn't being cited by AI assistants like ChatGPT, Perplexity, or Google AI Overview +description: Use when auditing a website or build output for deterministic content-readiness regressions and evidence-bounded discovery checks --- -# AEO Scan — AI Readability Audit +# AEO Scan — Content Readiness Audit -Scan a website or build directory and produce an interactive AI readability report. Supports multi-AI scoring with gemini and copilot CLIs. - -## Scoring Dimensions (0-100) - -| Dimension | Max | What it measures | -|-----------|-----|------------------| -| Structure | 25 | Heading hierarchy, paragraph length, FAQ presence, list usage | -| Citability | 25 | Self-contained statements, data/stats, definitions, attribution | -| Schema | 20 | JSON-LD presence, completeness, AI-relevant types | -| AI Metadata | 15 | llms.txt, robots.txt AI config, meta description | -| Content Density | 15 | Content vs boilerplate, keyword stuffing, uniqueness | +Run aeoptimize against a URL or build directory. The deterministic report is suitable for regression checks; optional Gemini, Copilot, or Claude reviews are experimental and do not predict ranking, indexing, rich results, visibility, or citation. ## Workflow -1. **Identify target.** Ask the user for a URL or directory path. If in a project with a build output (e.g., `dist/`, `out/`, `.next/`, `build/`), suggest scanning that. - -2. **Detect AI CLIs.** Check which AI tools are available: - ``` - which gemini && which copilot - ``` - Report which are found. If both are available, offer multi-AI scoring. - -3. **Run scan.** Choose based on available CLIs: +1. Identify the URL, file, or build directory. +2. Run the deterministic scan with machine-readable output: - **If external AI CLIs available:** - ``` - npx aeoptimize scan --multi-ai --json - ``` - This runs the rule engine + dispatches gemini/copilot for parallel scoring. - - **If no external CLIs:** - ``` + ```bash npx aeoptimize scan --json + npx aeoptimize scan --dir --json ``` - Then use the `aeo-ai-scorer` agent to add Claude's AI-level analysis on top of the rule engine score. - -4. **Present results.** Show: - - **Consensus score** (rule engine + AI weighted average) - - **Per-scorer breakdown** (Rule Engine, Claude, Gemini, Copilot — whichever are available) - - Dimensions scoring below 60% of their max - - All critical issues - - **AI insights** — each AI's one-sentence summary of the biggest issue - -5. **Discuss improvements.** For each weak dimension, explain: - - Why it matters for AI search visibility - - Concrete steps to improve - - Expected score impact - - Cross-reference insights from different AI scorers if they agree/disagree - -6. **Deep analysis (optional).** If the user wants detailed per-page analysis, dispatch the `aeo-analyzer` agent with the page HTML and scan report. It provides issue-by-issue breakdown with before/after examples. - -7. **Offer next steps:** - - Score below 50? Suggest running `/aeo-transform` on the worst pages - - Missing llms.txt or schema? Suggest `/aeo-generate` - - Score above 80? Congratulate and suggest monitoring over time - -## Multi-AI Scoring Methodology -| Scenario | Weighting | -|----------|-----------| -| Rule engine + 2+ AIs | 50% rule engine + 50% AI average | -| Rule engine + 1 AI | 60% rule engine + 40% AI | -| Rule engine only | 100% rule engine | +3. Report the deterministic score, methodology version, critical findings, and heuristic limitations. +4. Use `--multi-ai` only when the user explicitly asks for a subjective review. Label the result an experimental blend and keep the deterministic score separate. +5. Prioritize sourced quantitative claims, unintentional `noindex`, malformed or misleading structured data, and reproducible content regressions. +6. Suggest `/aeo-generate` only for an optional artifact preview. State that `llms.txt` is an unscored proposal. -## Important +## Boundaries -- Always run the CLI with `--json` for machine-readable output -- Present scores visually with context, not just numbers -- Focus discussion on high-impact fixes first -- If scanning a URL fails (CORS, timeout), suggest scanning the local build output instead -- When using Claude as AI scorer (no external CLIs), dispatch the `aeo-ai-scorer` agent +- FAQ content and `llms.txt` have no score impact. +- A score increase is not evidence of a ranking or citation increase. +- Generated schema must match visible content and current feature documentation. +- If a URL scan fails, use an authorized local build instead of bypassing access controls. +- Always use `--json` when another tool will consume the result. diff --git a/skills/aeo-transform/SKILL.md b/skills/aeo-transform/SKILL.md index fabf300..ff03faf 100644 --- a/skills/aeo-transform/SKILL.md +++ b/skills/aeo-transform/SKILL.md @@ -1,84 +1,32 @@ --- name: aeo-transform -description: Use when restructuring website content for better AI citation — splitting long paragraphs, adding FAQ schema, removing keyword stuffing, improving heading structure, or injecting structured data into HTML or Markdown files +description: Use when proposing evidence-bounded readability and structure edits without inventing content, ranking claims, or structured data --- -# AEO Transform — AI-Friendly Content Restructuring +# AEO Transform — Evidence-Bounded Content Restructuring -Transform SEO-optimized content into AI-search-ready format using language understanding. This skill uses your Claude subscription — no additional API costs. - -## Transformation Strategies - -| Strategy | What it does | Impact | -|----------|-------------|--------| -| **Split paragraphs** | Break long paragraphs (>150 words) into self-contained statements | High | -| **Extract FAQ** | Find implicit Q&A content and convert to explicit FAQ with schema | High | -| **Remove keyword stuffing** | Replace repeated keywords with natural synonyms | High | -| **Improve headings** | Rewrite vague headings as specific, question-format headings | Medium | -| **Add structured data** | Inject JSON-LD based on content analysis | Medium | -| **Fix dangling references** | Rewrite paragraphs starting with "This", "It", "They" to be self-contained | Medium | +Propose focused edits while preserving meaning, voice, provenance, and recoverability. ## Workflow -1. **Identify targets.** Ask the user which files to transform. If unsure, suggest running `/aeo-scan` first to find the lowest-scoring pages. - -2. **Read and analyze.** For each file: - - Read the full content - - Run `npx aeoptimize scan --json` to get the current score - - Identify which strategies apply based on the issues found - -3. **Transform incrementally.** Apply one strategy at a time: - - Show the proposed change as a diff - - Explain why this change improves AI readability - - Wait for user approval before applying - - Move to the next strategy - -4. **Preserve voice.** Critical rules: - - Never invent new content or add claims not in the original - - Preserve the author's writing style and tone - - Only restructure — do not rewrite meaning - - Keep all existing data, quotes, and references intact - -5. **Verify improvement.** After all transforms: - - Re-run `npx aeoptimize scan --json` - - Show before/after score comparison - - Highlight which dimensions improved - -## Strategy Details - -### Split Paragraphs -For each paragraph over 150 words: -- Identify distinct ideas within the paragraph -- Split at natural boundaries (topic shifts, "Additionally", "However") -- Ensure each new paragraph is self-contained (has its own subject, not just "It..." or "This...") - -### Extract FAQ -Look for patterns like: -- Heading followed by a short answer paragraph -- "What is X?" / "How does X work?" patterns in body text -- Implicit questions answered in the content - -Convert to: -- Explicit `

` question headings -- Concise answer paragraphs -- FAQPage JSON-LD schema +1. Read one authorized file and run the deterministic scan. +2. Classify each finding as an official requirement, deterministic check, heuristic, or experiment. +3. Show a focused diff before changing the file. +4. Change only what improves readability, factual provenance, or a documented technical requirement. +5. Rerun the same scan and report the reproducible output change separately from any external outcome. -### Remove Keyword Stuffing -When a word appears >3% of content (excluding stop words): -- Replace some occurrences with synonyms or related terms -- Remove redundant mentions that don't add meaning -- Ensure remaining usage feels natural +## Allowed transformations -### Fix Dangling References -For paragraphs starting with pronouns/conjunctions: -- Replace "This feature" with "[Product name]'s feature" -- Replace "It provides" with "[Subject] provides" -- Replace "However," with a self-contained restatement +- Split a long paragraph where comprehension improves. +- Repair a genuinely confusing document outline; multiple H1 elements are not automatically wrong. +- Cite or remove unsupported quantitative claims. +- Reduce repetitive wording without changing meaning. +- Propose structured data only when it matches visible content and current documentation. +- Clarify genuine reader questions without auto-generating FAQ schema. -## Important +## Boundaries -- Always show diffs before applying changes -- Transform one file at a time, one strategy at a time -- Score comparison before/after is mandatory -- This skill is interactive — never batch-transform without review -- Supports `.html` and `.md` files +- Never invent facts, statistics, sources, quotes, authors, dates, or benefits. +- Never describe a score increase as evidence of ranking, indexing, rich results, or citation. +- Never batch-transform files without explicit scope. +- Preserve a reviewable diff and the user's original voice. diff --git a/src/cli/index.ts b/src/cli/index.ts index 0fe9b14..8c6eb50 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -17,17 +17,17 @@ const program = new Command(); program .name('aeoptimize') - .description('CLI toolkit that transforms SEO-optimized websites into AI-search-ready content') + .description('Deterministic content-readiness lint for websites and documentation') .version('0.5.3'); // ── scan command ─────────────────────────────────────────────────── program .command('scan ') - .description('Scan a URL or directory for AI readability') + .description('Scan a URL or directory for content-readiness regressions') .option('--json', 'Output raw JSON report') .option('--dir', 'Treat target as a local directory instead of a URL') - .option('--multi-ai', 'Score with multiple AI engines (gemini, copilot) if available') + .option('--multi-ai', 'Add experimental reviews from available AI CLIs (gemini, copilot)') .action(async (target: string, options: { json?: boolean; dir?: boolean; multiAi?: boolean }) => { try { if (!target || target.trim().length === 0) { @@ -65,7 +65,7 @@ program program .command('generate ') - .description('Generate AI infrastructure files (llms.txt, JSON-LD, robots.txt suggestions)') + .description('Generate optional discovery artifacts (llms.txt proposal, JSON-LD, robots suggestions)') .option('--out ', 'Output directory (defaults to input directory)') .option('--json', 'Output raw JSON') .option('--dry-run', 'Preview without writing files') @@ -159,9 +159,9 @@ program await writeFile(join(jsonLdDir, 'generated-schemas.json'), JSON.stringify(output.jsonLd, null, 2), 'utf-8'); } - console.log(chalk.green.bold('\n✅ Generated AI infrastructure files:\n')); - console.log(` ${chalk.white('llms.txt')} — AI-readable site summary`); - console.log(` ${chalk.white('llms-full.txt')} — Full content for AI consumption`); + console.log(chalk.green.bold('\n✅ Generated optional discovery artifacts:\n')); + console.log(` ${chalk.white('llms.txt')} — Experimental site summary (llmstxt.org proposal)`); + console.log(` ${chalk.white('llms-full.txt')} — Experimental full-content companion`); if (output.jsonLd.length > 0) { console.log(` ${chalk.white('_aeo/generated-schemas.json')} — ${output.jsonLd.length} JSON-LD schemas`); } @@ -183,8 +183,8 @@ const hookCmd = program hookCmd .command('install') - .description('Install pre-commit hook that checks AEO score') - .option('--min-score ', 'Minimum AEO score to pass (default: 60)', '60') + .description('Install pre-commit hook that checks the readiness score') + .option('--min-score ', 'Minimum project readiness score (default: 60)', '60') .action(async (options: { minScore: string }) => { const minScore = parseInt(options.minScore, 10); if (isNaN(minScore) || minScore < 0 || minScore > 100) { @@ -193,7 +193,7 @@ hookCmd } const hookScript = `${HOOK_BEGIN_MARKER} -# aeoptimize pre-commit hook — checks AEO score of staged HTML/MD files +# aeoptimize pre-commit hook — checks readiness of staged HTML/MD files MIN_SCORE=${minScore} # Find staged HTML and MD files @@ -202,7 +202,7 @@ if [ -z "$FILES" ]; then exit 0 fi -echo "[aeoptimize] Checking AEO score of staged files..." +echo "[aeoptimize] Checking content readiness of staged files..." FAILED=0 OLD_IFS=$IFS @@ -374,7 +374,7 @@ function printReport(report: ScanReport): void { const { overall } = report; console.log(''); - console.log(chalk.bold(' AEO Readability Report')); + console.log(chalk.bold(' Content Readiness Report')); console.log(chalk.dim(` ${report.timestamp}`)); console.log(chalk.dim(` ${report.pages.length} page${report.pages.length > 1 ? 's' : ''} scanned`)); console.log(''); @@ -496,19 +496,19 @@ function printMultiAiReport(report: MultiAiReport): void { const { overall } = report; console.log(''); - console.log(chalk.bold(' AEO Readability Report (Multi-AI)')); + console.log(chalk.bold(' Content Readiness Report (Experimental AI Review)')); console.log(chalk.dim(` ${report.timestamp}`)); console.log(chalk.dim(` ${report.pages.length} page${report.pages.length > 1 ? 's' : ''} scanned`)); console.log(chalk.dim(` ${report.methodology}`)); console.log(''); - // Consensus score + // Blended review score. AI reviewers are experimental and do not establish ground truth. const scoreColor = report.consensusScore >= 70 ? chalk.green : report.consensusScore >= 40 ? chalk.yellow : chalk.red; const availableScores = report.aiScores.filter((s) => s.available); - const aiConsensus = availableScores.length > 0 + const aiReviewMean = availableScores.length > 0 ? String(Math.round(availableScores.reduce((sum, s) => sum + s.score, 0) / availableScores.length)) : 'N/A'; - console.log(` ${chalk.bold('Score:')} ${scoreColor.bold(String(report.consensusScore))}${chalk.dim('/100')} (Rule Engine: ${report.ruleScore} | AI Consensus: ${aiConsensus})`); + console.log(` ${chalk.bold('Experimental blend:')} ${scoreColor.bold(String(report.consensusScore))}${chalk.dim('/100')} (Rules: ${report.ruleScore} | AI review mean: ${aiReviewMean})`); console.log(''); // Source breakdown @@ -586,7 +586,7 @@ function printScoreBar(label: string, score: number, max: number): void { function printSkillCta(): void { console.log(chalk.dim(' ─────────────────────────────────────────')); console.log(chalk.dim(' Want AI-powered fixes? Install as Claude Code skill:')); - console.log(chalk.white(' claude plugin marketplace add dexuwang627-cloud/aeoptimize')); + console.log(chalk.white(' claude plugin marketplace add cucuwang/aeoptimize')); console.log(chalk.dim(' Then use: /aeo-scan, /aeo-generate, /aeo-transform')); console.log(''); } diff --git a/src/core/__tests__/evidence-boundaries.test.ts b/src/core/__tests__/evidence-boundaries.test.ts new file mode 100644 index 0000000..16c138b --- /dev/null +++ b/src/core/__tests__/evidence-boundaries.test.ts @@ -0,0 +1,77 @@ +import { describe, expect, it } from 'vitest'; +import { readFile } from 'node:fs/promises'; +import { fileURLToPath } from 'node:url'; +import { join } from 'node:path'; +import { allRules } from '../rules.js'; +import type { ParsedDocument } from '../types.js'; + +const root = fileURLToPath(new URL('../../../', import.meta.url)); + +function makeDoc(overrides: Partial = {}): ParsedDocument { + return { + url: 'fixture', + title: 'Fixture', + headings: [], + paragraphs: [], + jsonLd: [], + metaTags: {}, + links: [], + rawText: '', + ...overrides, + }; +} + +describe('evidence boundaries', () => { + it('does not score FAQ or llms.txt presence', () => { + const faq = allRules.find((rule) => rule.id === 'faq-presence')!; + const llms = allRules.find((rule) => rule.id === 'llms-txt-presence')!; + + expect(faq.weight).toBe(0); + expect(faq.evaluate(makeDoc())).toMatchObject({ maxScore: 0, suggestions: [] }); + expect(llms.weight).toBe(0); + expect(llms.evaluate(makeDoc())).toMatchObject({ maxScore: 0, suggestions: [] }); + }); + + it('does not penalize multiple H1 elements as an automatic error', () => { + const rule = allRules.find((candidate) => candidate.id === 'heading-hierarchy')!; + const result = rule.evaluate(makeDoc({ + headings: [ + { level: 1, text: 'Primary' }, + { level: 1, text: 'Secondary region' }, + { level: 2, text: 'Details' }, + ], + rawText: 'Readable content.', + })); + + expect(result.score).toBe(result.maxScore); + expect(result.issues.join(' ')).not.toContain('exactly one H1'); + }); + + it('does not impose a fixed meta-description length', () => { + const rule = allRules.find((candidate) => candidate.id === 'meta-description-quality')!; + const result = rule.evaluate(makeDoc({ + metaTags: { description: `A page-specific summary ${'with useful context '.repeat(20)}` }, + })); + + expect(result.score).toBe(result.maxScore); + expect(result.suggestions).toHaveLength(0); + }); +}); + +describe('public metadata', () => { + it('uses the current repository owner and exposes root Action metadata', async () => { + const paths = [ + 'README.md', + 'package.json', + '.claude-plugin/plugin.json', + '.claude-plugin/marketplace.json', + 'src/cli/index.ts', + 'action.yml', + ]; + const contents = await Promise.all(paths.map((path) => readFile(join(root, path), 'utf8'))); + const publicSurface = contents.join('\n'); + + expect(publicSurface).not.toContain('dexuwang627-cloud'); + expect(publicSurface).toContain('cucuwang/aeoptimize'); + }); +}); diff --git a/src/core/__tests__/fixtures/good-page.html b/src/core/__tests__/fixtures/good-page.html index f538ab0..dccb692 100644 --- a/src/core/__tests__/fixtures/good-page.html +++ b/src/core/__tests__/fixtures/good-page.html @@ -2,46 +2,28 @@ - What is Answer Engine Optimization (AEO)? A Complete Guide - - - + What is Answer Engine Optimization (AEO)? An Evidence Guide + + + -