diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3b84f5cb5..615b5854f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -17,6 +17,11 @@ updates: schedule: interval: weekly + - package-ecosystem: npm + directory: /tests/evals + schedule: + interval: weekly + - package-ecosystem: cargo directory: /app/src-tauri schedule: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c51136aa7..6a18378c2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -8,6 +8,7 @@ on: - "docs/user-guide/**" - "docs/.vitepress/**" - "docs/package.json" + - "docs/package-lock.json" workflow_dispatch: permissions: @@ -32,9 +33,12 @@ jobs: cache-dependency-path: docs/package-lock.json - name: Install dependencies - run: npm install + run: npm ci working-directory: docs + - name: Check help documentation links + run: node scripts/check-help-docs.mjs + - name: Build run: npm run build working-directory: docs diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index ae208d00a..ae55e542a 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -8,12 +8,6 @@ on: paths-ignore: - '**/*.md' - 'LICENSE' - pull_request: - branches: - - main - paths-ignore: - - '**/*.md' - - 'LICENSE' permissions: contents: read diff --git a/.github/workflows/pr-policy.yml b/.github/workflows/pr-policy.yml index 2f7d4f2f5..c8b0fa196 100644 --- a/.github/workflows/pr-policy.yml +++ b/.github/workflows/pr-policy.yml @@ -17,7 +17,21 @@ jobs: - name: Checkout uses: actions/checkout@v6 + - name: Detect relevant changes + id: changes + uses: dorny/paths-filter@v4 + with: + filters: | + docs: + - 'docs/user-guide/**' + - 'docs/.vitepress/**' + - 'docs/package.json' + - 'docs/package-lock.json' + - 'scripts/check-help-docs.mjs' + - 'app/src/lib/help-urls.ts' + - name: Setup Node.js + if: steps.changes.outputs.docs == 'true' uses: actions/setup-node@v6 with: node-version: "20" @@ -25,13 +39,23 @@ jobs: cache-dependency-path: docs/package-lock.json - name: Install docs dependencies + if: steps.changes.outputs.docs == 'true' working-directory: docs - run: npm install + run: npm ci + + - name: Check help documentation links + if: steps.changes.outputs.docs == 'true' + run: node scripts/check-help-docs.mjs - name: Build user-guide site + if: steps.changes.outputs.docs == 'true' working-directory: docs run: npm run build + - name: Skip (no docs changes) + if: steps.changes.outputs.docs != 'true' + run: echo "No docs changes detected — skipping." + agents-structural: name: agents-structural runs-on: ubuntu-latest @@ -99,13 +123,6 @@ jobs: npx markdownlint-cli2 "AGENTS.md" "CLAUDE.md" "README.md" "TEST_MANIFEST.md" ".claude/rules/**/*.md" - ".claude/skills/close-linear-issue/SKILL.md" - ".claude/skills/create-linear-issue/SKILL.md" - ".claude/skills/explaining-code/SKILL.md" - ".claude/skills/front-end-design/SKILL.md" - ".claude/skills/implement-linear-issue/SKILL.md" - ".claude/skills/implement-linear-issue/references/*.md" - ".claude/skills/playwright/SKILL.md" "agent-sources/**/*.md" "#agent-sources/plugins/vd-agent/**" "#agent-sources/plugins/skill-creator/skills/skill-creator/**" @@ -116,6 +133,66 @@ jobs: if: steps.changes.outputs.docs != 'true' run: echo "No markdown/instruction-doc changes detected — skipping." + eval-harness: + name: eval-harness + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Detect relevant changes + id: changes + uses: dorny/paths-filter@v4 + with: + filters: | + evals: + - 'tests/evals/**' + + - name: Setup Node.js + if: steps.changes.outputs.evals == 'true' + uses: actions/setup-node@v6 + with: + node-version: "lts/*" + cache: "npm" + cache-dependency-path: tests/evals/package-lock.json + + - name: Install eval harness dependencies + if: steps.changes.outputs.evals == 'true' + working-directory: tests/evals + run: npm ci --prefer-offline + + - name: Run deterministic eval harness tests + if: steps.changes.outputs.evals == 'true' + working-directory: tests/evals + run: npm test + + - name: Skip (no eval harness changes) + if: steps.changes.outputs.evals != 'true' + run: echo "No eval harness changes detected — skipping." + + script-tests: + name: script-tests + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Detect relevant changes + id: changes + uses: dorny/paths-filter@v4 + with: + filters: | + scripts: + - 'scripts/*.mjs' + + - name: Run script tests + if: steps.changes.outputs.scripts == 'true' + run: node --test scripts/*.test.mjs + + - name: Skip (no script changes) + if: steps.changes.outputs.scripts != 'true' + run: echo "No script changes detected — skipping." + repo-map-audit: name: repo-map-audit runs-on: ubuntu-latest @@ -131,6 +208,9 @@ jobs: HEAD_SHA="${{ github.event.pull_request.head.sha }}" STRUCTURAL_DIRS=( + ".github/" + "scripts/" + "tests/evals/" "app/src-tauri/src/commands/" "app/src/stores/" "app/src/pages/" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4d51eea4f..777362243 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -101,6 +101,7 @@ jobs: open -n "$DIR/Skill Builder.app" SCRIPT chmod +x "$STAGE/run.sh" + node scripts/verify-release-stage.mjs "$STAGE" macos zip -r "${STAGE}.zip" "$STAGE" - name: Package Windows release @@ -113,26 +114,24 @@ jobs: mkdir -p "$STAGE" cp "app/src-tauri/target/release/skill-builder.exe" "$STAGE/" - # Copy sidecar JS files (bootstrap + agent-runner + SDK) - # The Rust exe-relative fallback looks for {exe_dir}/sidecar/dist/... + # Copy sidecar JS files. The Rust exe-relative fallback looks for + # {exe_dir}/sidecar/dist/... mkdir -p "$STAGE/sidecar/dist/sdk" cp "app/sidecar/dist/package.json" "$STAGE/sidecar/dist/" cp "app/sidecar/dist/bootstrap.js" "$STAGE/sidecar/dist/" cp "app/sidecar/dist/agent-runner.js" "$STAGE/sidecar/dist/" - cp "app/sidecar/dist/sdk/cli.js" "$STAGE/sidecar/dist/sdk/" - cp "app/sidecar/dist/sdk/manifest.json" "$STAGE/sidecar/dist/sdk/" + cp "app/sidecar/dist/sdk/claude.exe" "$STAGE/sidecar/dist/sdk/" cp app/sidecar/dist/sdk/*.wasm "$STAGE/sidecar/dist/sdk/" 2>/dev/null || true if [ -d "app/sidecar/dist/sdk/vendor" ]; then cp -r "app/sidecar/dist/sdk/vendor" "$STAGE/sidecar/dist/sdk/" fi - # Copy agents and references (used by the sidecar at runtime) - if [ -d "agents" ]; then - cp -r "agents" "$STAGE/agents" - fi - if [ -d "references" ]; then - cp -r "references" "$STAGE/references" - fi + mkdir -p "$STAGE/agent-sources" "$STAGE/workspace" + cp -r "agent-sources/plugins" "$STAGE/agent-sources/plugins" + cp -r "agent-sources/skills" "$STAGE/agent-sources/skills" + cp -r "agent-sources/workspace/." "$STAGE/workspace/" + + node scripts/verify-release-stage.mjs "$STAGE" windows 7z a "${STAGE}.zip" "$STAGE" diff --git a/AGENTS.md b/AGENTS.md index 0ad954204..99cea6788 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # Skill Builder -Multi-agent workflow for creating domain-specific Claude skills. Tauri desktop app (React + Rust) orchestrates agents via a Node.js sidecar. +Desktop app for creating domain-specific Claude Code-compatible skills. Tauri desktop app (React + Rust) orchestrates agents via a Node.js sidecar. **Maintenance rule:** This file contains architecture, conventions, and guidelines — not product details. Do not add counts, feature descriptions, or any fact that can be discovered by reading code. If it will go stale when the code changes, it doesn't belong here — point to the source file instead. @@ -10,7 +10,7 @@ Use this precedence when maintaining agent guidance: 1. `AGENTS.md` (canonical, cross-agent source of truth) 2. `.claude/rules/*.md` (shared detailed rules; agent-agnostic content) -3. `.claude/skills/*/SKILL.md` (workflow playbooks) +3. `agent-sources/**` (runtime agent, plugin, skill, and workspace instructions) 4. Agent-specific adapter files (for example `CLAUDE.md`) that reference canonical docs Adapter files must not duplicate canonical policy unless they are adding agent-specific behavior. @@ -20,7 +20,7 @@ Adapter files must not duplicate canonical policy unless they are adding agent-s | Layer | Technology | |---|---| | Desktop framework | Tauri v2 | -| Frontend | React 19, TypeScript strict, Vite 7 | +| Frontend | React 19, TypeScript strict, Vite 8 | | Styling | Tailwind CSS 4, shadcn/ui | | State | Zustand, TanStack Router | | Icons | Lucide React | @@ -59,7 +59,7 @@ Read these before starting any non-trivial task: | Artifact | Update when | |---|---| -| `AGENTS.md` | A fact is durable, non-obvious, and won't be obvious from code · a skill is added to `.claude/skills/` | +| `AGENTS.md` | A fact is durable, non-obvious, and won't be obvious from code | | `repo-map.json` | Any file added, removed, or renamed inside `commands/`, `stores/`, `pages/`, `components/`, `lib/`, `hooks/` · sub-module directory added or restructured · new Tauri command file · entrypoint or package structure change | | `README.md` | User-facing installation, configuration, commands, or architecture overview changes | | `TEST_MANIFEST.md` | Rust command file added/removed · E2E spec added/removed · shared infra file added/removed · agent artifact format changes affecting a Rust or TS parser | @@ -96,6 +96,7 @@ Run these automatically before reporting completion when files match: | `app/e2e/fixtures/agent-responses/**` | `cd app && npm run test:unit` | | `app/src-tauri/src/contracts/**` | `cd app && npm run codegen && cd src-tauri && cargo test contracts::` | | `app/src/**` | `cd app && npm run test:unit` | +| `tests/evals/**` | `cd tests/evals && npm test` | **E2E tests** use Playwright to drive the real Tauri app UI, but with mocked Tauri commands (`__TAURI_MOCK_OVERRIDES__` / `reloadWithOverrides`). They are not bare-metal system tests — the backend is always mocked. @@ -103,21 +104,20 @@ For artifact format changes (agent output + app parser + mock templates): run `t For Rust and cross-layer changes, consult `TEST_MANIFEST.md` for the correct cargo filter and E2E tag. Unsure? `app/tests/run.sh` runs everything. -**Never run `test:agents:smoke` autonomously** — it makes live API calls. Tell the user to run it manually. +**Never run `test:agents:smoke` autonomously unless explicitly requested** — it makes live API/model calls through the OpenCode eval harness in `tests/evals`. The deterministic harness contract test is `cd tests/evals && npm test`. ## Issue Management - **PR title format:** `VU-XXX: short description` - **PR body link:** `Fixes VU-XXX` - **Linear project:** All issues created for this repository must be created under **Skill Builder**. -- **Worktrees:** `../worktrees/` relative to repo root, preserving the full branch name including the `feature/` prefix. Pre-create the parent directory before adding: +- **Worktrees:** Use `./scripts/worktree.sh ` as the canonical maintainer workflow for creating or attaching a repo worktree and bootstrapping it. It preserves the full branch name under `../worktrees/` and symlinks each worktree's `tests/evals/.promptfoo` back to the source checkout so Promptfoo history/database state stays out of feature worktrees. ```bash - mkdir -p ../worktrees/feature - git worktree add ../worktrees/feature/ + ./scripts/worktree.sh feature/ ``` -**Pre-commit:** `markdownlint ` for `.md` files · `cd app && npx tsc --noEmit` · `cargo clippy --manifest-path app/src-tauri/Cargo.toml -- -D warnings` · `bash app/scripts/lint-agent-docs.sh` when editing `AGENTS.md`, `CLAUDE.md`, `.claude/rules/`, or `.claude/skills/` · `cd app && npm run test:unit` when changing event types in `app/src/lib/` or `app/sidecar/`. +**Pre-commit:** `markdownlint ` for `.md` files · `cd app && npx tsc --noEmit` · `cargo clippy --manifest-path app/src-tauri/Cargo.toml -- -D warnings` · `bash app/scripts/lint-agent-docs.sh` when editing `AGENTS.md`, `CLAUDE.md`, or `.claude/rules/` · `cd app && npm run test:unit` when changing event types in `app/src/lib/` or `app/sidecar/`. **Pre-PR `repo-map.json` audit (required):** Before opening or updating a PR, verify `repo-map.json` reflects the current codebase. Check: diff --git a/CLAUDE.md b/CLAUDE.md index 53a842368..b31b5fb43 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,6 @@ NEVER make edits, run non-readonly tools, or create files while in plan mode. On ### Model tiers | Tier | Model | When | - |---|---|---| | Reasoning | sonnet | Planning, architecture, requirements drafting | | Implementation | default | Coding, exploration, review, merge | diff --git a/README.md b/README.md index 2c1f7ab54..6610c41b9 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,87 @@ # Skill Builder -A multi-agent workflow for creating domain-specific Claude skills. Skills are knowledge packages that help data and analytics engineers build silver and gold layer models with proper functional context. +Skill Builder is a desktop app for turning domain expertise into reusable AI skills. It guides a product or domain owner through research, clarification, decision confirmation, skill generation, review, and refinement so the resulting `SKILL.md` and supporting references are useful in Claude Code-compatible workflows. -Available as a **Tauri desktop app** (GUI) that orchestrates agents via a Node.js sidecar. +The app is designed for teams that need skills to carry business context, data-model vocabulary, operating rules, and implementation guidance into agent-assisted work. Generated skills are stored as local files, versioned with git, and can be reviewed or updated after the initial workflow completes. -## Quick Start +## What It Helps You Do -Requires: Node.js 18+, Rust toolchain, [Tauri prerequisites](https://v2.tauri.app/start/prerequisites/) +- Research a skill topic and turn broad intent into concrete scope. +- Collect and review clarification answers before generation. +- Detect gaps or contradictory answers before those assumptions become skill instructions. +- Generate a skill package with `SKILL.md` and supporting reference files. +- Refine existing skills through the review and update surfaces. +- Run deterministic local tests and optional live eval smoke checks for the agent harness. -```bash -cd app -npm install -npm run sidecar:build # Bundle the Node.js agent runner -npm run dev # Start in dev mode -``` +## Product Flow -Configure your Anthropic API key in Settings before running workflows. The app manages its workspace directory automatically. +1. **Research** surveys the domain and produces clarification questions. +2. **Detailed Research** deepens the unresolved areas and adds follow-up questions. +3. **Confirm Decisions** converts answers into a final decision set. +4. **Generate Skill** writes the skill package into the configured skills folder. +5. **Review and Refine** lets you inspect, update, benchmark, and improve the generated skill. -**Mock mode** -- for UI development without API calls: +Skill files are written under the skills folder configured in Settings. The canonical layout is: -```bash -cd app && MOCK_AGENTS=true npm run dev +```text +{skills_path}/{plugin_slug}/{skill_name}/SKILL.md ``` -This replays bundled JSONL templates with short delays, writes mock output files, and advances the workflow through all steps without hitting the Anthropic API. - -### Mock Scenarios - -Set `MOCK_SCENARIO` to switch between pre-built scenarios: - -| Scenario | Command | Behaviour | -| --- | --- | --- | -| `default` | `MOCK_AGENTS=true npm run dev` | Happy path -- all answers clear, gate verdict `sufficient`, workflow advances without friction | -| `contradictory` | `MOCK_AGENTS=true MOCK_SCENARIO=contradictory npm run dev` | Step 0 produces pre-filled answers with contradictions (Q1 self-contradicts choice vs free-text, Q2 beginner target conflicts with Q7 advanced examples, Q5 vague, Q8 unanswered). Gate evaluator returns `mixed` verdict triggering the gate dialog with per-question feedback notes | - -## How It Works - -The workflow guides you through these core stages: +The app also keeps a separate workspace under the application data directory for transcripts, intermediate artifacts, eval state, and other runtime files. -1. **Research** -- agents select and research relevant dimensions, then generate clarification questions. If scope is too broad, they recommend narrower skill directions. -2. **Detailed Research** -- agents dig deeper into each section and produce follow-up refinement questions. -3. **Confirm Decisions** -- an agent analyzes your answers, detects gaps and contradictions, and prepares the final decision set. -4. **Generate Skill** -- the app writes `SKILL.md` and any supporting reference files. -5. **Refine** -- after generation, you can iteratively revise the skill through the desktop UI. - -Generated skills are version-controlled locally and can be prepared for branch-and-PR workflows from the desktop app. +## Quick Start -## Architecture +Requires Node.js 18+, a Rust toolchain, and the [Tauri prerequisites](https://v2.tauri.app/start/prerequisites/). -```text -skill-builder/ -├── agent-sources/ -│ ├── agents/ # Top-level agent prompts -│ ├── plugins/ # Plugin-owned agents and skills -│ ├── skills/ # Bundled skills -│ └── workspace/ # Workspace instructions deployed at startup -├── app/ # Desktop application -│ ├── src/ # React 19 + Tailwind 4 + shadcn/ui -│ ├── src-tauri/ # Rust backend (Tauri 2 + SQLite) -│ └── sidecar/ # Node.js agent runner (Claude Agent SDK) -└── scripts/ # Validation and eval scripts +```bash +cd app +npm install +npm run sidecar:build +npm run dev ``` -Spawns agents via a Node.js sidecar process using the Claude Agent SDK. State tracked in SQLite. Agents stream JSON messages to the Rust backend, which emits Tauri events to the React frontend. +Configure your Anthropic API key in Settings before running live workflows. -## Testing +For UI development without API calls: ```bash cd app -npm run test:unit # Frontend unit tests (Vitest) -cargo test # Rust tests (from app/src-tauri/) -npm run test:e2e # E2E tests (Playwright) -npm run test:agents:structural # Agent structural checks (free, no API key) +MOCK_AGENTS=true npm run dev ``` -See [`app/tests/README.md`](app/tests/README.md) for all test levels. -For Rust-to-E2E mapping and cross-layer test selection, see [`TEST_MANIFEST.md`](TEST_MANIFEST.md). +Mock mode replays bundled JSONL templates, writes mock output files, and advances the workflow without contacting an LLM provider. -## Contributing +## Development -Start with [`CLAUDE.md`](CLAUDE.md) for architecture, dev commands, testing strategy, and code style. +Skill Builder is a Tauri desktop app: -### Local Anthropic Key (Claude Code) +- `app/src/` contains the React frontend. +- `app/src-tauri/` contains the Rust backend and SQLite persistence. +- `app/sidecar/` contains the Node.js agent runtime boundary. +- `agent-sources/` contains bundled agents, plugins, skills, and workspace instructions. +- `tests/evals/` contains the Promptfoo/OpenCode eval harness. -Use `.claude/settings.local.json` for your local `ANTHROPIC_API_KEY`. +Common checks: ```bash -# One-time per clone/worktree to activate shared hooks -git config core.hooksPath .githooks +cd app && npm run test:unit +cd app && npm run test:agents:structural +cd tests/evals && npm test +cargo test --manifest-path app/src-tauri/Cargo.toml ``` -The pre-commit hook blocks commits that contain Anthropic API keys and prevents committing a real key in `.claude/settings.local.json`. +Live eval smoke tests make model calls and should be run intentionally: + +```bash +cd tests/evals && npm run eval:harness-smoke +``` + +## Contributor Docs + +- Start with [`AGENTS.md`](AGENTS.md) for repository conventions, testing policy, and worktree setup. +- See [`repo-map.json`](repo-map.json) for the current code map and command reference. +- See [`TEST_MANIFEST.md`](TEST_MANIFEST.md) for test-selection guidance. +- See [`docs/design/`](docs/design/) for design notes and architecture details. ## License diff --git a/TEST_MANIFEST.md b/TEST_MANIFEST.md index 4ccec5ffc..8c67a9d2a 100644 --- a/TEST_MANIFEST.md +++ b/TEST_MANIFEST.md @@ -73,6 +73,7 @@ Rust modules have inline `#[cfg(test)]` tests run via `cargo test`. When a Rust |---|---| | `agent-sources/agents/*.md` | `test:agents:structural`, `test:agents:smoke` (Promptfoo) | | `agent-sources/workspace/CLAUDE.md` | `test:agents:structural` | +| `tests/evals/**` | `cd tests/evals && npm test`; live smoke via `cd tests/evals && npm run eval:harness-smoke` only when explicitly requested | ## E2E Spec Files @@ -135,9 +136,13 @@ cargo test --manifest-path src-tauri/Cargo.toml commands::workflow # Agents npm run test:agents:structural # Quick structural check (free) -npm run test:agents:smoke # Promptfoo behavior evals (requires API key) +npm run test:agents:smoke # OpenCode/Promptfoo smoke evals (live model call) npm run test:agents # All agent tests (structural + smoke) +# Eval harness +cd ../tests/evals && npm test # Deterministic harness contracts +cd ../tests/evals && npm run eval:harness-smoke # Live OpenCode harness smoke + # Full suite (shared infrastructure changes) ./tests/run.sh ``` diff --git a/app/agent-tests/promptfoo/assertions/contracts.mjs b/app/agent-tests/promptfoo/assertions/contracts.mjs deleted file mode 100644 index 952e2936f..000000000 --- a/app/agent-tests/promptfoo/assertions/contracts.mjs +++ /dev/null @@ -1,182 +0,0 @@ -export function allTrue(values) { - return Object.values(values).every((value) => value === true); -} - -export function parseFrontmatter(markdown) { - const match = markdown.match(/^---\n([\s\S]*?)\n---/); - if (!match) return {}; - const map = {}; - let currentSection = null; - for (const line of match[1].split("\n")) { - const trimmed = line.trim(); - const isIndented = line.startsWith(" ") || line.startsWith("\t"); - if (!isIndented) { - currentSection = null; - if (trimmed.endsWith(":") && !trimmed.slice(0, -1).includes(":")) { - currentSection = trimmed.slice(0, -1); - continue; - } - } - const idx = line.indexOf(":"); - if (idx === -1) continue; - const key = line.slice(0, idx).trim(); - const value = line.slice(idx + 1).trim(); - const cleaned = - (value.startsWith('"') && value.endsWith('"')) - || (value.startsWith("'") && value.endsWith("'")) - ? value.slice(1, -1) - : value; - if (currentSection === "metadata") { - if (key === "version" || key === "author") { - map[key] = cleaned; - } - continue; - } - map[key] = cleaned; - } - return map; -} - -export function assessClarificationsSchema(clarifications) { - return { - version: clarifications?.version === "1", - metadata: Boolean(clarifications?.metadata), - questionCountNumber: typeof clarifications?.metadata?.question_count === "number", - sectionCountNumber: typeof clarifications?.metadata?.section_count === "number", - sectionsArray: Array.isArray(clarifications?.sections), - notesArray: Array.isArray(clarifications?.notes), - }; -} - -export function assessAnswerEvaluationSchema(evaluation) { - const requiredFields = [ - "total_count", - "answered_count", - "empty_count", - "vague_count", - "contradictory_count", - "per_question", - "verdict", - "reasoning", - ]; - const perQuestion = Array.isArray(evaluation?.per_question) - ? evaluation.per_question - : []; - const contradictoryEntries = perQuestion.filter((entry) => entry?.verdict === "contradictory"); - const vagueEntries = perQuestion.filter((entry) => entry?.verdict === "vague"); - return { - hasRequiredFields: requiredFields.every((field) => - Object.prototype.hasOwnProperty.call(evaluation ?? {}, field), - ), - verdictValid: ["sufficient", "mixed", "insufficient"].includes(evaluation?.verdict), - perQuestionArray: Array.isArray(evaluation?.per_question), - contradictoryEntriesHaveFields: contradictoryEntries.every( - (entry) => - typeof entry?.reason === "string" && - entry.reason.trim().length > 0 && - typeof entry?.contradicts === "string" && - entry.contradicts.trim().length > 0, - ), - vagueEntriesHaveReason: vagueEntries.every( - (entry) => typeof entry?.reason === "string" && entry.reason.trim().length > 0, - ), - }; -} - -export function assessDecisionsCanonical(markdown) { - const frontmatter = parseFrontmatter(markdown); - return { - frontmatter: /^---\n[\s\S]*?\n---/m.test(markdown), - heading: /^### D\d+:/m.test(markdown), - originalQuestion: /\*\*Original question:\*\*/.test(markdown), - decision: /\*\*Decision:\*\*/.test(markdown), - implication: /\*\*Implication:\*\*/.test(markdown), - status: /\*\*Status:\*\*/.test(markdown), - decisionCountField: Object.prototype.hasOwnProperty.call(frontmatter, "decision_count"), - conflictsResolvedField: Object.prototype.hasOwnProperty.call(frontmatter, "conflicts_resolved"), - roundField: Object.prototype.hasOwnProperty.call(frontmatter, "round"), - }; -} - -export function assessDecisionsJsonSchema(payload) { - const metadata = payload?.metadata ?? {}; - const decisions = Array.isArray(payload?.decisions) ? payload.decisions : []; - return { - version: payload?.version === "1", - metadataObject: typeof payload?.metadata === "object" && payload?.metadata !== null && !Array.isArray(payload.metadata), - decisionCountNumber: typeof metadata?.decision_count === "number", - conflictsResolvedNumber: typeof metadata?.conflicts_resolved === "number", - roundNumber: typeof metadata?.round === "number", - decisionsArray: Array.isArray(payload?.decisions), - decisionsHaveRequiredFields: decisions.every((decision) => - typeof decision?.id === "string" - && typeof decision?.title === "string" - && typeof decision?.original_question === "string" - && typeof decision?.decision === "string" - && typeof decision?.implication === "string" - && ["resolved", "conflict-resolved", "needs-review", "revised"].includes(decision?.status), - ), - }; -} - -export function assessInvocationContracts(expected, observed) { - const normalize = (value) => { - const lower = String(value ?? "").toLowerCase().trim(); - if (!lower) return ""; - if (lower.includes("read user-context")) return "read-user-context"; - if (lower.includes("read-user-context")) return "read-user-context"; - if (lower.includes("read:user-context.md")) return "read-user-context"; - if (lower.includes("read:user-context-md")) return "read-user-context"; - if (lower.includes("read decisions")) return "read-decisions"; - if (lower.includes("read decisions.json")) return "read-decisions"; - if (lower.includes("read:decisions.json")) return "read-decisions"; - if (lower.includes("read:decisions-json")) return "read-decisions"; - if (lower.includes("read-decisions-json")) return "read-decisions"; - if (lower.includes("skip-clarifications-read")) return "skip-clarifications-read"; - if (lower.includes("read clarifications")) return "read-clarifications"; - if (lower.includes("invoke-research-skill")) return "invoke-research-skill"; - if (lower.includes("write-research-plan")) return "write-research-plan"; - if (lower.includes("write-clarifications")) return "write-clarifications"; - if (lower.includes("write skill") || lower.includes("write-skill")) return "write-skill"; - if (lower.includes("write:skill.md") || lower.includes("write:skill-md")) return "write-skill"; - if (lower.includes("wrote skill.md") || lower.includes("wrote skill-md")) return "write-skill"; - if (lower.includes("write references")) return "write-references"; - if (lower.startsWith("write-references/")) return "write-references"; - if (lower.startsWith("wrote references/")) return "write-references"; - if (lower.includes("write:references/") || lower.includes("write:references-")) return "write-references"; - if (lower.includes("wrote references/") || lower.includes("wrote references-")) return "write-references"; - if (lower.includes("write-evaluations") || lower.includes("evaluations.md")) return "write-evaluations"; - if (lower.includes("write-evals") || lower.includes("write:evals")) return "write-evaluations"; - if (lower.includes("return-evaluations-markdown")) return "write-evaluations"; - if (lower.includes("wrote context/evaluations.md") || lower.includes("wrote context-evaluations-md")) return "write-evaluations"; - if ( - lower.startsWith("write-") - && !lower.startsWith("write-skill") - && !lower.startsWith("write-evaluations") - && !lower.startsWith("write-clarifications") - && !lower.startsWith("write-research-plan") - ) { - return "write-references"; - } - return lower - .replace(/[/.]/g, "-") - .replace(/\s+/g, "-") - .replace(/-+/g, "-"); - }; - const expectedNorm = expected.map(normalize).filter(Boolean); - const observedNorm = observed.map(normalize).filter(Boolean); - const observedSet = new Set(observedNorm); - const expectedSet = new Set(expectedNorm); - const missing = expectedNorm.filter((value) => !observedSet.has(value)); - const unexpected = observedNorm.filter((value) => !expectedSet.has(value)); - let orderCursor = 0; - for (const value of observedNorm) { - if (value === expectedNorm[orderCursor]) orderCursor += 1; - } - return { - invocationPresence: missing.length === 0, - invocationOrder: orderCursor === expectedNorm.length, - unexpectedCalls: unexpected, - missingCalls: missing, - }; -} diff --git a/app/agent-tests/promptfoo/promptfooconfig.yaml b/app/agent-tests/promptfoo/promptfooconfig.yaml deleted file mode 100644 index db2a7b999..000000000 --- a/app/agent-tests/promptfoo/promptfooconfig.yaml +++ /dev/null @@ -1,323 +0,0 @@ -description: Skill Builder agent contract regressions via Promptfoo. - -prompts: - - "{{scenario}}" - -providers: - - file://./provider.mjs - -tests: - - description: research-orchestrator-normal - vars: - scenario: research-orchestrator - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"scenario":"research-orchestrator"' - - type: contains - value: '"structuredResponseObject":true' - - type: contains - value: '"statusResearchComplete":true' - - type: contains - value: '"dimensionsSelectedNumber":true' - - type: contains - value: '"questionCountNumber":true' - - type: contains - value: '"returnsResearchOutput":true' - - type: contains - value: '"sectionCountNumber":true' - - type: contains - value: '"failures":[]' - - description: research-orchestrator-scope-guard - vars: - scenario: research-orchestrator-scope-guard - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"statusResearchComplete":true' - - type: contains - value: '"scopeRecommendation":true' - - type: contains - value: '"zeroDimensions":true' - - type: contains - value: '"zeroQuestions":true' - - type: contains - value: '"hasScopeReasonOrNotes":true' - - type: contains - value: '"failures":[]' - - description: research-scoping-quality - vars: - scenario: research-scoping-quality - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"statusResearchComplete":true' - - type: contains - value: '"hasQuestions":true' - - type: contains - value: '"hasCapabilityFraming":true' - - type: contains - value: '"hasScopeQuestion":true' - - type: contains - value: '"hasTypicalRequestQuestion":true' - - type: contains - value: '"hasSuccessDefinition":true' - - type: contains - value: '"failures":[]' - - description: detailed-research-normal - vars: - scenario: detailed-research - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"scenario":"detailed-research"' - - type: contains - value: '"structuredResponseObject":true' - - type: contains - value: '"statusDetailedResearchComplete":true' - - type: contains - value: '"refinementCountNumber":true' - - type: contains - value: '"sectionCountNumber":true' - - type: contains - value: '"returnsClarificationsJson":true' - - type: contains - value: '"failures":[]' - - description: detailed-research-scope-guard - vars: - scenario: detailed-research-scope-guard - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"scenario":"detailed-research-scope-guard"' - - type: contains - value: '"statusDetailedResearchComplete":true' - - type: contains - value: '"scopeRecommendation":true' - - type: contains - value: '"zeroRefinements":true' - - type: contains - value: '"sectionCountZero":true' - - type: contains - value: '"canonicalShape":true' - - type: contains - value: '"failures":[]' - - description: detailed-research-all-clear - vars: - scenario: detailed-research-all-clear - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"statusDetailedResearchComplete":true' - - type: contains - value: '"zeroRefinements":true' - - type: contains - value: '"sectionCountNumber":true' - - type: contains - value: '"failures":[]' - - description: detailed-research-missing-evaluation-fallback - vars: - scenario: detailed-research-missing-evaluation-fallback - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"statusDetailedResearchComplete":true' - - type: contains - value: '"returnsClarificationsJson":true' - - type: contains - value: '"hasRefinementCount":true' - - type: contains - value: '"failures":[]' - - description: answer-evaluator-normal - vars: - scenario: answer-evaluator - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"scenario":"answer-evaluator"' - - type: contains - value: '"structuredResponseObject":true' - - type: contains - value: '"hasRequiredFields":true' - - type: contains - value: '"contradictoryEntriesHaveFields":true' - - type: contains - value: '"vagueEntriesHaveReason":true' - - type: contains - value: '"failures":[]' - - description: confirm-decisions-normal - vars: - scenario: confirm-decisions - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"scenario":"confirm-decisions"' - - type: contains - value: '"decisionsExists":true' - - type: contains - value: '"decisionCountField":true' - - type: contains - value: '"status":true' - - type: contains - value: '"failures":[]' - - description: confirm-decisions-scope-guard - vars: - scenario: confirm-decisions-scope-guard - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"hasScopeRecommendationFlag":true' - - type: contains - value: '"hasZeroDecisionCount":true' - - type: contains - value: '"failures":[]' - - description: confirm-decisions-contradictory - vars: - scenario: confirm-decisions-contradictory - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"contradictoryFlagSet":true' - - type: contains - value: '"canonicalShape":true' - - type: contains - value: '"failures":[]' - - description: confirm-decisions-resolvable-conflict - vars: - scenario: confirm-decisions-resolvable-conflict - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"noContradictoryFlag":true' - - type: contains - value: '"hasConflictResolvedOrResolved":true' - - type: contains - value: '"failures":[]' - - description: generate-skill-normal - vars: - scenario: generate-skill - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"skillMdExists":true' - - type: contains - value: '"evaluationsExists":true' - - type: contains - value: '"invocationPresence":true' - - type: contains - value: '"failures":[]' - - description: generate-skill-scope-guard - vars: - scenario: generate-skill-scope-guard - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"scopeStubWritten":true' - - type: contains - value: '"scopeStubHeading":true' - - type: contains - value: '"failures":[]' - - description: generate-skill-contradictory - vars: - scenario: generate-skill-contradictory - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"contradictionStubWritten":true' - - type: contains - value: '"contradictionStubHeading":true' - - type: contains - value: '"failures":[]' - - description: generate-skill-revised - vars: - scenario: generate-skill-revised - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"notStub":true' - - type: contains - value: '"invocationPresence":true' - - type: contains - value: '"failures":[]' - - description: rewrite-skill-normal - vars: - scenario: rewrite-skill - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"scenario":"rewrite-skill"' - - type: contains - value: '"descriptionUpdated":true' - - type: contains - value: '"descriptionPreserved":true' - - type: contains - value: '"modifiedUpdated":true' - - type: contains - value: '"failures":[]' - - description: rewrite-skill-scope-guard - vars: - scenario: rewrite-skill-scope-guard - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"scopeStubWritten":true' - - type: contains - value: '"scopeStubHeading":true' - - type: contains - value: '"blockedMessage":true' - - type: contains - value: '"failures":[]' - - description: validate-skill-scope-guard - vars: - scenario: validate-skill-scope-guard - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"validationStub":true' - - type: contains - value: '"testStub":true' - - type: contains - value: '"failures":[]' - - description: validate-skill-parameter-guard - vars: - scenario: validate-skill-missing-skill-md - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"guardMessage":true' - - type: contains - value: '"noValidationFile":true' - - type: contains - value: '"failures":[]' - - description: skill-test-contract - vars: - scenario: skill-test-contract - assert: - - type: contains - value: '"ok":true' - - type: contains - value: '"hasName":true' - - type: contains - value: '"hasRubricSection":true' - - type: contains - value: '"failures":[]' diff --git a/app/agent-tests/promptfoo/provider.mjs b/app/agent-tests/promptfoo/provider.mjs deleted file mode 100644 index 70d89f388..000000000 --- a/app/agent-tests/promptfoo/provider.mjs +++ /dev/null @@ -1,1303 +0,0 @@ -import { spawnSync } from "node:child_process"; -import fs from "node:fs"; -import os from "node:os"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; -import { - allTrue, - assessAnswerEvaluationSchema, - assessClarificationsSchema, - assessDecisionsJsonSchema, - assessInvocationContracts, - parseFrontmatter, -} from "./assertions/contracts.mjs"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -const REPO_ROOT = path.resolve(__dirname, "../../.."); -const AGENTS_DIR = path.join(REPO_ROOT, "agent-sources", "agents"); -const PLUGINS_DIR = path.join(REPO_ROOT, "agent-sources", "plugins"); -const CLAUDE_BIN = process.env.CLAUDE_BIN ?? "claude"; -const DEFAULT_SKILL_NAME = "pet-store-analytics"; - -function parseBudget(...candidates) { - for (const value of candidates) { - if (value === "none") return null; - if (value != null && value !== "") return value; - } - return null; -} - -function makeTempDir(label) { - return fs.mkdtempSync(path.join(os.tmpdir(), `skill-builder-promptfoo-${label}-`)); -} - -function hasApiAccess() { - return Boolean(process.env.ANTHROPIC_API_KEY || process.env.FORCE_PLUGIN_TESTS); -} - -function runAgent(prompt, { budgetUsd, timeoutMs, cwd }) { - const env = { ...process.env, CLAUDECODE: undefined }; - const budgetArgs = budgetUsd != null ? ["--max-budget-usd", budgetUsd] : []; - const modelArgs = process.env.AGENTS_TEST_MODEL - ? ["--model", process.env.AGENTS_TEST_MODEL] - : []; - - const result = spawnSync( - CLAUDE_BIN, - ["-p", "--dangerously-skip-permissions", ...modelArgs, ...budgetArgs], - { - input: prompt, - encoding: "utf8", - cwd, - env, - timeout: timeoutMs, - stdio: ["pipe", "pipe", "pipe"], - } - ); - - if (result.error) { - throw new Error(`runAgent process error: ${result.error.message}`); - } - if (result.status !== 0) { - const stderr = (result.stderr ?? "").trim(); - const stdout = (result.stdout ?? "").trim(); - throw new Error( - `runAgent exited with status ${result.status}\nstdout: ${stdout}\nstderr: ${stderr}` - ); - } - return (result.stdout ?? "").trim(); -} - -function writeFile(filePath, content) { - fs.mkdirSync(path.dirname(filePath), { recursive: true }); - fs.writeFileSync(filePath, content); -} - -function readJson(filePath) { - return JSON.parse(fs.readFileSync(filePath, "utf8")); -} - -function writeSessionJson(dir, skillName, phase) { - writeFile( - path.join(dir, "workspace", skillName, "session.json"), - JSON.stringify( - { - skill_name: skillName, - skill_type: "domain", - domain: "Pet Store Analytics", - skill_dir: `./${skillName}/`, - created_at: "2026-01-01T00:00:00Z", - last_activity: "2026-01-01T01:00:00Z", - current_phase: phase, - phases_completed: [], - mode: "guided", - research_dimensions_used: ["entities", "metrics"], - clarification_status: { total_questions: 6, answered: 0 }, - auto_filled: false, - iterative_history: [], - }, - null, - 2 - ) - ); -} - -function makeSkillDirs(dir, skillName) { - fs.mkdirSync(path.join(dir, "workspace", skillName, "context"), { recursive: true }); - fs.mkdirSync(path.join(dir, skillName, "references"), { recursive: true }); -} - -function writeUserContext(dir, skillName) { - writeFile( - path.join(dir, "workspace", skillName, "user-context.md"), - `# User Context - -- **Industry**: Retail / E-commerce -- **Function**: Analytics Engineering -- **Target Audience**: Intermediate data engineers building dbt models -- **Key Challenges**: Handling seasonal spikes, multi-location inventory reconciliation -- **Scope**: Silver and gold layer dbt modeling for pet store operations -- **What Makes This Setup Unique**: Multi-location with centralized e-commerce fulfillment -- **What Claude Gets Wrong**: Assumes single-store context; misses cross-location stock logic -` - ); -} - -function createFixtureScoping(dir, skillName) { - writeSessionJson(dir, skillName, "scoping"); - writeUserContext(dir, skillName); - makeSkillDirs(dir, skillName); -} - -function createFixtureClarification(dir, skillName) { - writeSessionJson(dir, skillName, "clarification"); - writeUserContext(dir, skillName); - makeSkillDirs(dir, skillName); - writeFile( - path.join(dir, "workspace", skillName, "context", "clarifications.json"), - JSON.stringify( - { - version: "1", - metadata: { - title: "Pet Store Analytics Clarifications", - question_count: 6, - section_count: 2, - refinement_count: 0, - must_answer_count: 2, - priority_questions: ["Q1", "Q4"], - scope_recommendation: false, - }, - sections: [ - { - id: "S1", - title: "Core Entities", - questions: [ - { - id: "Q1", - title: "Primary entities", - must_answer: true, - text: "What are the primary business entities in pet store analytics?", - choices: [ - { id: "A", text: "Products, Customers, Transactions", is_other: false }, - { - id: "B", - text: "Products, Customers, Transactions, Inventory", - is_other: false, - }, - { id: "C", text: "Other (please specify)", is_other: true }, - ], - recommendation: "B", - answer_choice: "B", - answer_text: "We track all four entities in the core model.", - refinements: [], - }, - { - id: "Q2", - title: "Customer segmentation", - must_answer: false, - text: "How do you segment customers?", - choices: [ - { id: "A", text: "Purchase frequency", is_other: false }, - { id: "B", text: "Pet type", is_other: false }, - { id: "C", text: "Both dimensions", is_other: false }, - ], - recommendation: "C", - answer_choice: "C", - answer_text: "Both frequency and pet type are required.", - refinements: [], - }, - ], - }, - { - id: "S2", - title: "Data Modeling", - questions: [ - { - id: "Q4", - title: "Return policy", - must_answer: true, - text: "What is the return model for different product types?", - choices: [ - { id: "A", text: "30-day refund for all products", is_other: false }, - { id: "B", text: "Exchange-only for live animals", is_other: false }, - { id: "C", text: "Custom by category", is_other: false }, - ], - recommendation: "B", - answer_choice: null, - answer_text: null, - refinements: [], - }, - ], - }, - ], - notes: [], - }, - null, - 2 - ) - ); -} - -function createFixtureDetailedResearchWorkspace(dir, skillName, { scopeRecommendation = false } = {}) { - createFixtureClarification(dir, skillName); - const clarificationsPath = path.join(dir, "workspace", skillName, "context", "clarifications.json"); - const clarifications = readJson(clarificationsPath); - clarifications.metadata.scope_recommendation = scopeRecommendation; - writeFile(clarificationsPath, JSON.stringify(clarifications, null, 2)); - - writeFile( - path.join(dir, "workspace", skillName, "answer-evaluation.json"), - JSON.stringify( - { - verdict: "mixed", - answered_count: 2, - empty_count: 1, - vague_count: 1, - contradictory_count: 0, - total_count: 4, - reasoning: "Some answers need follow-up clarifications.", - per_question: [ - { question_id: "Q1", verdict: "clear" }, - { question_id: "Q2", verdict: "vague", reason: "Needs more detail." }, - { question_id: "Q4", verdict: "not_answered" }, - { question_id: "Q5", verdict: "needs_refinement" }, - ], - }, - null, - 2 - ) - ); -} - -function createFixtureDecisionWorkspace(dir, skillName, { scopeRecommendation = false } = {}) { - writeSessionJson(dir, skillName, "clarification"); - writeUserContext(dir, skillName); - makeSkillDirs(dir, skillName); - writeFile( - path.join(dir, "workspace", skillName, "context", "clarifications.json"), - JSON.stringify( - { - version: "1", - metadata: { - title: "Pet Store Analytics Clarifications", - question_count: 3, - section_count: 1, - refinement_count: 0, - must_answer_count: 1, - priority_questions: ["Q1"], - scope_recommendation: scopeRecommendation, - }, - sections: [ - { - id: "S1", - title: "Core Entities", - questions: [ - { - id: "Q1", - title: "Primary entities", - must_answer: true, - text: "What are the primary business entities?", - choices: [ - { id: "A", text: "Products, Customers, Transactions", is_other: false }, - { - id: "B", - text: "Products, Customers, Transactions, Inventory", - is_other: false, - }, - ], - recommendation: "B", - answer_choice: "B", - answer_text: "Track products, customers, transactions, and inventory.", - refinements: [], - }, - ], - }, - ], - notes: [], - }, - null, - 2 - ) - ); -} - -function createFixtureRefinableSkill(dir, skillName) { - writeSessionJson(dir, skillName, "refinement"); - writeUserContext(dir, skillName); - makeSkillDirs(dir, skillName); - writeFile( - path.join(dir, skillName, "SKILL.md"), - `--- -name: ${skillName} -description: Guides data engineers to build silver and gold layer dbt models for pet store analytics. Use when modeling sales transactions, inventory levels, or customer behavior from a pet store POS system. -domain: Pet Store Analytics -type: domain -tools: Read, Edit, Write, Glob, Grep, Task -metadata: - version: 1.0.0 - author: testuser -created: 2026-01-15 -modified: 2026-01-15 ---- - -# Pet Store Analytics -` - ); -} - -function writeDecisionsJson(dir, skillName, metadata, decisions = []) { - writeFile( - path.join(dir, "workspace", skillName, "context", "decisions.json"), - JSON.stringify({ version: "1", metadata, decisions }, null, 2), - ); -} - -function writeClarificationsFile(dir, skillName, payload) { - writeFile( - path.join(dir, "workspace", skillName, "context", "clarifications.json"), - JSON.stringify(payload, null, 2), - ); -} - -function stripFrontmatter(markdown) { - return markdown.replace(/^---[\s\S]*?---\n/, ""); -} - -function loadWorkspaceContext() { - return fs.readFileSync( - path.join(REPO_ROOT, "agent-sources", "workspace", "CLAUDE.md"), - "utf8" - ); -} - -function loadRefineInstructions() { - return loadAgentInstructions("rewrite-skill"); -} - -function loadAgentInstructions(agentName) { - const primary = path.join(AGENTS_DIR, `${agentName}.md`); - if (fs.existsSync(primary)) { - return stripFrontmatter(fs.readFileSync(primary, "utf8")); - } - // Fall back to plugin agents (e.g. generate-skill lives under skill-creator plugin) - const pluginDirs = fs.readdirSync(PLUGINS_DIR, { withFileTypes: true }) - .filter((d) => d.isDirectory()) - .map((d) => d.name); - for (const plugin of pluginDirs) { - const pluginAgent = path.join(PLUGINS_DIR, plugin, "agents", `${agentName}.md`); - if (fs.existsSync(pluginAgent)) { - return stripFrontmatter(fs.readFileSync(pluginAgent, "utf8")); - } - } - // Fall back to plugin skills (e.g. validate-skill is now skill-validator SKILL.md) - const SKILL_NAME_MAP = { - "validate-skill": "skill-validator", - "eval-skill": "skill-evaluator", - }; - const skillDirName = SKILL_NAME_MAP[agentName]; - if (skillDirName) { - for (const plugin of pluginDirs) { - const skillFile = path.join(PLUGINS_DIR, plugin, "skills", skillDirName, "SKILL.md"); - if (fs.existsSync(skillFile)) { - return stripFrontmatter(fs.readFileSync(skillFile, "utf8")); - } - } - } - throw new Error(`Agent instructions not found for "${agentName}" in agents/ or plugins/`); -} - -function parseAgentJsonOutput(stdout) { - if (!stdout) return null; - try { - return JSON.parse(stdout); - } catch { - const start = stdout.indexOf("{"); - const end = stdout.lastIndexOf("}"); - if (start === -1 || end === -1 || end <= start) return null; - try { - return JSON.parse(stdout.slice(start, end + 1)); - } catch { - return null; - } - } -} - -function finalizeScenario(scenario, contracts, invocationExpected = [], invocationObserved = []) { - const invocation = assessInvocationContracts(invocationExpected, invocationObserved); - const mergedContracts = { - ...contracts, - invocationPresence: invocation.invocationPresence, - invocationOrder: invocation.invocationOrder, - }; - const failures = [ - ...Object.entries(mergedContracts) - .filter(([, value]) => value !== true) - .map(([key]) => key), - ...invocation.missingCalls.map((value) => `missing:${value}`), - ]; - return { - scenario, - ok: failures.length === 0, - contracts: mergedContracts, - invocations: { - expected: invocationExpected, - observed: invocationObserved, - unexpectedCalls: invocation.unexpectedCalls, - missingCalls: invocation.missingCalls, - }, - failures, - }; -} - -function runResearchOrchestrator({ budgetUsd }) { - const dir = makeTempDir("research"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureScoping(dir, skillName); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("research-orchestrator"); - - const prompt = `You are the research-orchestrator agent for the skill-builder plugin. - -Skill type: domain -Domain: Pet Store Analytics -Skill name: ${skillName} -Context directory: ${dir}/workspace/${skillName}/context -Workspace directory: ${dir}/workspace/${skillName} - - -${workspaceContext} - - -${agentInstructions} - - -Return JSON only: -{ - "status": "research_complete", - "dimensions_selected": , - "question_count": , - "research_output": { "" } -}`; - - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 260_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const researchOutput = response?.research_output ?? null; - const schema = assessClarificationsSchema(researchOutput); - return finalizeScenario( - "research-orchestrator", - { - structuredResponseObject: Boolean(response && typeof response === "object"), - statusResearchComplete: response?.status === "research_complete", - dimensionsSelectedNumber: - typeof response?.dimensions_selected === "number" && response.dimensions_selected >= 0, - questionCountNumber: typeof response?.question_count === "number" && response.question_count >= 0, - returnsResearchOutput: Boolean(researchOutput && typeof researchOutput === "object"), - ...schema, - }, - [], - [], - ); -} - -function runResearchOrchestratorScopeGuard({ budgetUsd }) { - const dir = makeTempDir("research-scope"); - const skillName = "testing"; - createFixtureScoping(dir, skillName); - writeFile( - path.join(dir, "workspace", skillName, "user-context.md"), - `# User Context -- **Purpose**: Business process knowledge -- **Description**: Just testing -- **What Claude Needs to Know**: Throwaway UI test only -`, - ); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("research-orchestrator"); - const prompt = `You are the research-orchestrator agent for the skill-builder plugin. -Skill type: domain -Skill name: ${skillName} -Context directory: ${dir}/workspace/${skillName}/context -Workspace directory: ${dir}/workspace/${skillName} - -${workspaceContext} - - -${agentInstructions} - -Return JSON only with status, dimensions_selected, question_count, and research_output.`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 260_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const researchOutput = response?.research_output ?? {}; - return finalizeScenario( - "research-orchestrator-scope-guard", - { - statusResearchComplete: response?.status === "research_complete", - scopeRecommendation: researchOutput?.metadata?.scope_recommendation === true, - zeroDimensions: Number(response?.dimensions_selected ?? -1) === 0, - zeroQuestions: Number(response?.question_count ?? -1) === 0, - hasScopeReasonOrNotes: - typeof researchOutput?.metadata?.scope_reason === "string" - || (Array.isArray(researchOutput?.notes) && researchOutput.notes.length > 0), - }, - [], - [], - ); -} - -function runResearchScopingQuality({ budgetUsd }) { - const dir = makeTempDir("research-quality"); - const skillName = "inventory-tracking"; - createFixtureScoping(dir, skillName); - writeFile( - path.join(dir, "workspace", skillName, "user-context.md"), - `## User Context - -### Skill - -**Purpose**: Business process knowledge (domain) -**Description**: inventory tracking for retail stores - -### About You - -**Industry**: Retail -**Function**: Analytics Engineering -`, - ); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("research-orchestrator"); - const prompt = `You are the research-orchestrator agent for the skill-builder plugin. - -Skill type: domain -Skill name: ${skillName} -Context directory: ${dir}/workspace/${skillName}/context -Workspace directory: ${dir}/workspace/${skillName} - - -${workspaceContext} - - -${agentInstructions} - - -Return JSON only: -{ - "status": "research_complete", - "dimensions_selected": , - "question_count": , - "research_output": { "" } -}`; - - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 260_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const researchOutput = response?.research_output ?? null; - - // Collect all question text across all sections for semantic matching - const allQuestionText = (researchOutput?.sections ?? []) - .flatMap((s) => (s?.questions ?? []).map((q) => `${q?.title ?? ""} ${q?.text ?? ""}`)) - .join(" ") - .toLowerCase(); - - // Semantic checks — keyword patterns, not literal strings - const hasCapabilityFraming = /enable|what.*can|capabilities|should.*do|designed to/.test(allQuestionText); - const hasScopeQuestion = /narrow|broad|scope|range|coverage|how wide|how specific/.test(allQuestionText); - const hasTypicalRequestQuestion = /typical|request|example|common.*use|use case|dbt|silver|gold/.test(allQuestionText); - const hasSuccessDefinition = /success|outcome|done|complet|measur|looks like|good result|goal|valid|accept|expected output|qualit|finish|deliverable|standard|how.*know|when.*consider/.test(allQuestionText); - - return finalizeScenario( - "research-scoping-quality", - { - statusResearchComplete: response?.status === "research_complete", - hasQuestions: Number(response?.question_count ?? 0) > 0, - hasCapabilityFraming, - hasScopeQuestion, - hasTypicalRequestQuestion, - hasSuccessDefinition, - }, - [], - [], - ); -} - -function runDetailedResearch({ budgetUsd }) { - const dir = makeTempDir("detailed-research"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureDetailedResearchWorkspace(dir, skillName); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("detailed-research"); - - const prompt = `You are the detailed-research agent for the skill-builder plugin. - -Skill type: domain -Skill name: ${skillName} -Context directory: ${dir}/workspace/${skillName}/context -Skill output directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} - - -${workspaceContext} - - -${agentInstructions} - - -Return JSON only with: -{ - "status": "detailed_research_complete", - "refinement_count": , - "section_count": , - "clarifications_json": { ...canonical object... } -}`; - - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 260_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const clarifications = response?.clarifications_json ?? null; - const schema = assessClarificationsSchema(clarifications); - return finalizeScenario( - "detailed-research", - { - structuredResponseObject: Boolean(response && typeof response === "object"), - statusDetailedResearchComplete: response?.status === "detailed_research_complete", - refinementCountNumber: - typeof response?.refinement_count === "number" && response.refinement_count >= 0, - sectionCountNumber: typeof response?.section_count === "number" && response.section_count >= 0, - returnsClarificationsJson: Boolean(clarifications && typeof clarifications === "object"), - ...schema, - }, - [], - [], - ); -} - -function runDetailedResearchScopeGuard({ budgetUsd }) { - const dir = makeTempDir("detailed-research-scope"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureDetailedResearchWorkspace(dir, skillName, { scopeRecommendation: true }); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("detailed-research"); - - const prompt = `You are the detailed-research agent for the skill-builder plugin. -Skill type: domain -Skill name: ${skillName} -Context directory: ${dir}/workspace/${skillName}/context -Skill output directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} - -${workspaceContext} - - -${agentInstructions} - -Return JSON only with status, refinement_count, section_count, and clarifications_json.`; - - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 260_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const clarifications = response?.clarifications_json ?? {}; - return finalizeScenario( - "detailed-research-scope-guard", - { - statusDetailedResearchComplete: response?.status === "detailed_research_complete", - scopeRecommendation: clarifications?.metadata?.scope_recommendation === true, - zeroRefinements: Number(response?.refinement_count ?? -1) === 0, - sectionCountZero: Number(response?.section_count ?? -1) === 0, - canonicalShape: Boolean( - clarifications - && typeof clarifications === "object" - && clarifications.version === "1" - && Array.isArray(clarifications.sections) - ), - }, - [], - [], - ); -} - -function runDetailedResearchAllClear({ budgetUsd }) { - const dir = makeTempDir("detailed-research-all-clear"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureDetailedResearchWorkspace(dir, skillName); - writeFile( - path.join(dir, "workspace", skillName, "answer-evaluation.json"), - JSON.stringify( - { - verdict: "sufficient", - answered_count: 4, - empty_count: 0, - vague_count: 0, - contradictory_count: 0, - total_count: 4, - reasoning: "All answers are clear.", - per_question: [ - { question_id: "Q1", verdict: "clear" }, - { question_id: "Q2", verdict: "clear" }, - { question_id: "Q4", verdict: "clear" }, - { question_id: "Q5", verdict: "clear" }, - ], - }, - null, - 2 - ) - ); - - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("detailed-research"); - const prompt = `You are the detailed-research agent for the skill-builder plugin. -Skill type: domain -Skill name: ${skillName} -Context directory: ${dir}/workspace/${skillName}/context -Skill output directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} - -${workspaceContext} - - -${agentInstructions} - -Return JSON only with status, refinement_count, section_count, and clarifications_json.`; - - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 260_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - return finalizeScenario("detailed-research-all-clear", { - statusDetailedResearchComplete: response?.status === "detailed_research_complete", - zeroRefinements: Number(response?.refinement_count ?? -1) === 0, - sectionCountNumber: typeof response?.section_count === "number" && response.section_count >= 0, - }); -} - -function runDetailedResearchMissingEvaluationFallback({ budgetUsd }) { - const dir = makeTempDir("detailed-research-fallback"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureDetailedResearchWorkspace(dir, skillName); - fs.rmSync(path.join(dir, "workspace", skillName, "answer-evaluation.json")); - - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("detailed-research"); - const prompt = `You are the detailed-research agent for the skill-builder plugin. -Skill type: domain -Skill name: ${skillName} -Context directory: ${dir}/workspace/${skillName}/context -Skill output directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} - -${workspaceContext} - - -${agentInstructions} - -Return JSON only with status, refinement_count, section_count, and clarifications_json.`; - - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 260_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const clarifications = response?.clarifications_json ?? null; - return finalizeScenario("detailed-research-missing-evaluation-fallback", { - statusDetailedResearchComplete: response?.status === "detailed_research_complete", - returnsClarificationsJson: Boolean(clarifications && typeof clarifications === "object"), - hasRefinementCount: typeof response?.refinement_count === "number", - }); -} - -function runAnswerEvaluator({ budgetUsd }) { - const dir = makeTempDir("answer-eval"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureClarification(dir, skillName); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("answer-evaluator"); - - const prompt = `You are the answer-evaluator agent for the skill-builder plugin. - -Context directory: ${dir}/workspace/${skillName}/context -Workspace directory: ${dir}/workspace/${skillName} - - -${workspaceContext} - - -${agentInstructions} - - -Read the clarification file at: ${dir}/workspace/${skillName}/context/clarifications.json -Return JSON only with these fields: -{ - "total_count": , - "answered_count": , - "empty_count": , - "vague_count": , - "contradictory_count": , - "verdict": "sufficient" | "mixed" | "insufficient", - "per_question": [ ... ], - "reasoning": "" -} - -Return only the evaluation object (no markdown).`; - - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 120_000, cwd: dir }); - const evaluation = parseAgentJsonOutput(stdout) ?? {}; - const contracts = { - structuredResponseObject: typeof evaluation === "object" && !Array.isArray(evaluation), - ...assessAnswerEvaluationSchema(evaluation), - }; - return finalizeScenario("answer-evaluator", contracts); -} - -function runConfirmDecisions({ budgetUsd }) { - const dir = makeTempDir("decisions"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureDecisionWorkspace(dir, skillName); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("confirm-decisions"); - - const prompt = `You are the confirm-decisions agent for the skill-builder plugin. - -Skill type: domain -Domain: Pet Store Analytics -Skill name: ${skillName} -Context directory: ${dir}/workspace/${skillName}/context -Skill directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} - - -${workspaceContext} - - -${agentInstructions} - - -Read the answered clarifications at: ${dir}/workspace/${skillName}/context/clarifications.json -Synthesize the answers into concrete design decisions for the skill. -Return JSON only with: -{ - "status": "decisions_complete", - "decisions_json": { "" }, - "call_trace": ["..."] -}`; - - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 120_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const decisions_json = response?.decisions_json ?? null; - return finalizeScenario( - "confirm-decisions", - { - decisionsExists: Boolean(decisions_json && typeof decisions_json === "object"), - decisionCountField: typeof decisions_json?.metadata?.decision_count === "number", - status: Array.isArray(decisions_json?.decisions) && decisions_json.decisions.every((d) => typeof d.status === "string" && d.status.length > 0), - }, - [], - response?.call_trace ?? [], - ); -} - -function runConfirmDecisionsScopeGuard({ budgetUsd }) { - const dir = makeTempDir("decisions-scope"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureDecisionWorkspace(dir, skillName, { scopeRecommendation: true }); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("confirm-decisions"); - const prompt = `You are the confirm-decisions agent. -Context directory: ${dir}/workspace/${skillName}/context -Workspace directory: ${dir}/workspace/${skillName} -${workspaceContext} -${agentInstructions} -Return JSON only with "status":"decisions_complete" and "decisions_json".`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 120_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const decisions_json = response?.decisions_json ?? null; - return finalizeScenario("confirm-decisions-scope-guard", { - hasScopeRecommendationFlag: decisions_json?.metadata?.scope_recommendation === true, - hasZeroDecisionCount: decisions_json?.metadata?.decision_count === 0, - }); -} - -function runConfirmDecisionsContradictory({ budgetUsd }) { - const dir = makeTempDir("decisions-contradictory"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureDecisionWorkspace(dir, skillName); - const clarificationsPath = path.join(dir, "workspace", skillName, "context", "clarifications.json"); - const clarifications = readJson(clarificationsPath); - clarifications.sections[0].questions.push({ - id: "Q9", - title: "Revenue tracking scope", - must_answer: true, - text: "Should this skill track revenue metrics?", - choices: [ - { id: "A", text: "Track revenue monthly", is_other: false }, - { id: "B", text: "Do not track revenue at all", is_other: false }, - { id: "C", text: "Other (please specify)", is_other: true }, - ], - recommendation: "A", - answer_choice: "B", - answer_text: "Do not track revenue at all.", - refinements: [], - }); - clarifications.sections[0].questions.push({ - id: "Q10", - title: "Revenue reporting cadence", - must_answer: true, - text: "How often should revenue be reported?", - choices: [ - { id: "A", text: "Monthly revenue reporting", is_other: false }, - { id: "B", text: "Quarterly only", is_other: false }, - { id: "C", text: "Other (please specify)", is_other: true }, - ], - recommendation: "A", - answer_choice: "A", - answer_text: "Track monthly revenue reports.", - refinements: [], - }); - writeClarificationsFile(dir, skillName, clarifications); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("confirm-decisions"); - const prompt = `You are confirm-decisions. -Context directory: ${dir}/workspace/${skillName}/context -Workspace directory: ${dir}/workspace/${skillName} -${workspaceContext} -${agentInstructions} -Return JSON only with "status":"decisions_complete" and "decisions_json".`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 120_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const decisions_json = response?.decisions_json ?? null; - return finalizeScenario("confirm-decisions-contradictory", { - decisionsPayloadExists: Boolean(decisions_json && typeof decisions_json === "object"), - contradictoryFlagSet: decisions_json?.metadata?.contradictory_inputs === true, - canonicalShape: allTrue(assessDecisionsJsonSchema(decisions_json ?? {})), - }); -} - -function runConfirmDecisionsResolvableConflict({ budgetUsd }) { - const dir = makeTempDir("decisions-resolvable"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureDecisionWorkspace(dir, skillName); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("confirm-decisions"); - const prompt = `You are confirm-decisions. -Context directory: ${dir}/workspace/${skillName}/context -Workspace directory: ${dir}/workspace/${skillName} -${workspaceContext} -${agentInstructions} -Return JSON only with "status":"decisions_complete" and "decisions_json".`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 120_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const decisions_json = response?.decisions_json ?? null; - return finalizeScenario("confirm-decisions-resolvable-conflict", { - decisionsPayloadExists: Boolean(decisions_json && typeof decisions_json === "object"), - noContradictoryFlag: decisions_json?.metadata?.contradictory_inputs !== true, - hasConflictResolvedOrResolved: Array.isArray(decisions_json?.decisions) - && decisions_json.decisions.some((d) => d.status === "conflict-resolved" || d.status === "resolved"), - }); -} - -function runGenerateSkill({ budgetUsd }) { - const dir = makeTempDir("generate"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureRefinableSkill(dir, skillName); - createFixtureDecisionWorkspace(dir, skillName); - writeDecisionsJson(dir, skillName, { decision_count: 2, conflicts_resolved: 0, round: 1 }, [ - { - id: "D1", - title: "Capability", - original_question: "What should this skill enable Claude to do?", - decision: "Build dbt-ready silver and gold model guidance for pet-store analytics.", - implication: "Include concrete layer-specific patterns and tests.", - status: "needs-review", - }, - { - id: "D2", - title: "Trigger", - original_question: "When should this skill trigger?", - decision: "Trigger for requests about pet-store dbt modeling, medallion layers, and data tests.", - implication: "Use these trigger contexts in SKILL frontmatter description.", - status: "needs-review", - }, - ]); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("generate-skill"); - const prompt = `You are generate-skill. -Skill name: ${skillName} -Purpose: Business process knowledge -Context directory: ${dir}/workspace/${skillName}/context -Skill output directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} -${workspaceContext} -${agentInstructions} -Return JSON only with "status":"generated", "commit_summary", "version_bump", and "call_trace".`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 300_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const skillMdPath = path.join(dir, skillName, "SKILL.md"); - const evalsPath = path.join(dir, "workspace", skillName, "evals", "evals.json"); - return finalizeScenario( - "generate-skill", - { - skillMdExists: fs.existsSync(skillMdPath), - evaluationsExists: fs.existsSync(evalsPath), - }, - ["read-user-context", "read-decisions", "write-skill", "write-references", "write-evaluations"], - response?.call_trace ?? [], - ); -} - -function runGenerateSkillScopeGuard({ budgetUsd }) { - const dir = makeTempDir("generate-scope"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureRefinableSkill(dir, skillName); - // generate-skill reads scope_recommendation from clarifications.json - createFixtureDecisionWorkspace(dir, skillName, { scopeRecommendation: true }); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("generate-skill"); - const prompt = `You are generate-skill. -Context directory: ${dir}/workspace/${skillName}/context -Skill output directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} -${workspaceContext} -${agentInstructions} -Return JSON only with "status":"generated" and "call_trace".`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 180_000, cwd: dir }); - const content = fs.readFileSync(path.join(dir, skillName, "SKILL.md"), "utf8"); - return finalizeScenario("generate-skill-scope-guard", { - scopeStubWritten: /scope_recommendation:\s*true/.test(content), - scopeStubHeading: /## Scope Recommendation Active/.test(content), - }); -} - -function runGenerateSkillContradictory({ budgetUsd }) { - const dir = makeTempDir("generate-contradictory"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureRefinableSkill(dir, skillName); - createFixtureDecisionWorkspace(dir, skillName); - writeDecisionsJson(dir, skillName, { decision_count: 2, conflicts_resolved: 1, round: 1, contradictory_inputs: true }, [ - { - id: "D1", - title: "Contradiction", - original_question: "What revenue should be tracked?", - decision: "Track monthly revenue", - implication: "Requires revenue tracking in the data model.", - status: "conflict-resolved", - }, - ]); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("generate-skill"); - const prompt = `You are generate-skill. -Context directory: ${dir}/workspace/${skillName}/context -Skill output directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} -${workspaceContext} -${agentInstructions} -Return JSON only with "status":"generated" and "call_trace".`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 180_000, cwd: dir }); - const content = fs.readFileSync(path.join(dir, skillName, "SKILL.md"), "utf8"); - return finalizeScenario("generate-skill-contradictory", { - contradictionStubWritten: /contradictory_inputs:\s*true/.test(content), - contradictionStubHeading: /## Contradictory Inputs Detected/.test(content), - }); -} - -function runGenerateSkillRevised({ budgetUsd }) { - const dir = makeTempDir("generate-revised"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureRefinableSkill(dir, skillName); - createFixtureDecisionWorkspace(dir, skillName); - writeDecisionsJson(dir, skillName, { decision_count: 2, conflicts_resolved: 1, round: 1, contradictory_inputs: "revised" }, [ - { - id: "D1", - title: "Capability", - original_question: "What should this skill enable Claude to do?", - decision: "Build dbt guidance.", - implication: "Provide concrete modeling examples.", - status: "needs-review", - }, - ]); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("generate-skill"); - const prompt = `You are generate-skill. -Context directory: ${dir}/workspace/${skillName}/context -Skill output directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} -${workspaceContext} -${agentInstructions} -Return JSON only with "status":"generated", "commit_summary", "version_bump", and "call_trace".`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 300_000, cwd: dir }); - const response = parseAgentJsonOutput(stdout); - const content = fs.readFileSync(path.join(dir, skillName, "SKILL.md"), "utf8"); - return finalizeScenario( - "generate-skill-revised", - { - notStub: !/scope_recommendation:\s*true|contradictory_inputs:\s*true/.test(content), - generatedSkillBody: /# /.test(content), - }, - ["read-user-context", "read-decisions", "write-skill"], - response?.call_trace ?? [], - ); -} - -function runRefineSkill({ budgetUsd }) { - const dir = makeTempDir("refine"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureRefinableSkill(dir, skillName); - const workspaceContext = loadWorkspaceContext(); - const refineInstructions = loadRefineInstructions(); - const skillMdPath = path.join(dir, skillName, "SKILL.md"); - - const prompt = `You are the rewrite-skill agent for the skill-builder plugin. - -Skill directory: ${dir}/${skillName} -Context directory: ${dir}/workspace/${skillName}/context -Workspace directory: ${dir}/workspace/${skillName} -Skill type: domain -Command: refine - - -${refineInstructions} -${workspaceContext} - - -Current user message: Add to the description that this skill works well with dbt-testing when running test suites`; - - runAgent(prompt, { budgetUsd, timeoutMs: 120_000, cwd: dir }); - - const content = fs.existsSync(skillMdPath) ? fs.readFileSync(skillMdPath, "utf8") : ""; - const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/); - const frontmatter = frontmatterMatch ? frontmatterMatch[1] : ""; - const modifiedMatch = frontmatter.match(/^modified:\s*(.+)$/m); - - return finalizeScenario("rewrite-skill", { - descriptionUpdated: /dbt.testing/i.test(content), - descriptionPreserved: frontmatter.includes("Guides data engineers"), - modifiedUpdated: modifiedMatch != null && modifiedMatch[1].trim() !== "2026-01-15", - }); -} - -function runRefineSkillScopeGuard({ budgetUsd }) { - const dir = makeTempDir("refine-scope"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureRefinableSkill(dir, skillName); - createFixtureDecisionWorkspace(dir, skillName); - writeDecisionsJson(dir, skillName, - { scope_recommendation: true, decision_count: 0, conflicts_resolved: 0, round: 1 }, - [], - ); - writeClarificationsFile(dir, skillName, { - version: "1", - metadata: { scope_recommendation: true, question_count: 0, section_count: 0, refinement_count: 0, must_answer_count: 0, priority_questions: [] }, - sections: [], - notes: [], - }); - const workspaceContext = loadWorkspaceContext(); - const refineInstructions = loadRefineInstructions(); - const prompt = `You are rewrite-skill. -Skill directory: ${dir}/${skillName} -Context directory: ${dir}/workspace/${skillName}/context -Workspace directory: ${dir}/workspace/${skillName} -${workspaceContext} -${refineInstructions} -Current user message: update description`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 120_000, cwd: dir }); - const content = fs.readFileSync(path.join(dir, skillName, "SKILL.md"), "utf8"); - return finalizeScenario("rewrite-skill-scope-guard", { - scopeStubWritten: /scope_recommendation:\s*true/.test(content), - scopeStubHeading: /## Scope Recommendation Active/.test(content), - blockedMessage: /scope recommendation/i.test(stdout), - }); -} - -function runValidateSkillScopeGuard({ budgetUsd }) { - const dir = makeTempDir("validate-scope"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureRefinableSkill(dir, skillName); - createFixtureDecisionWorkspace(dir, skillName, { scopeRecommendation: true }); - writeDecisionsJson(dir, skillName, - { decision_count: 0, conflicts_resolved: 0, round: 1 }, - [], - ); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("validate-skill"); - const prompt = `You are validate-skill. -Skill name: ${skillName} -Purpose: Business process knowledge -Context directory: ${dir}/workspace/${skillName}/context -Skill output directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} -${workspaceContext} -${agentInstructions}`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 180_000, cwd: dir }); - return finalizeScenario("validate-skill-scope-guard", { - validationStub: /Scope recommendation is active|Validation Skipped/i.test(stdout), - testStub: !fs.existsSync(path.join(dir, skillName, "test-skill.md")) - && !fs.existsSync(path.join(dir, "workspace", skillName, "agent-validation-log.md")), - }); -} - -function runValidateSkillMissingSkillMd({ budgetUsd }) { - const dir = makeTempDir("validate-missing-skill"); - const skillName = DEFAULT_SKILL_NAME; - createFixtureDecisionWorkspace(dir, skillName); - const workspaceContext = loadWorkspaceContext(); - const agentInstructions = loadAgentInstructions("validate-skill"); - const prompt = `You are validate-skill. -Skill name: ${skillName} -Purpose: Business process knowledge -Context directory: ${dir}/workspace/${skillName}/context -Skill output directory: ${dir}/${skillName} -Workspace directory: ${dir}/workspace/${skillName} -${workspaceContext} -${agentInstructions}`; - const stdout = runAgent(prompt, { budgetUsd, timeoutMs: 180_000, cwd: dir }); - return finalizeScenario("validate-skill-missing-skill-md", { - guardMessage: /No SKILL\.md found|Validation Skipped/i.test(stdout), - noValidationFile: !fs.existsSync(path.join(dir, "workspace", skillName, "agent-validation-log.md")) - && !fs.existsSync(path.join(dir, skillName, "test-skill.md")), - }); -} - -function runSkillTestContract() { - const skillTestPath = path.join(REPO_ROOT, "agent-sources", "skills", "skill-test", "SKILL.md"); - const content = fs.readFileSync(skillTestPath, "utf8"); - const fm = parseFrontmatter(content); - return finalizeScenario("skill-test-contract", { - hasName: fm.name === "skill-test", - hasVersion: typeof fm.version === "string" && fm.version.length > 0, - notUserInvocable: fm["user-invocable"] === "false", - hasRubricSection: /## Evaluation Rubric/.test(content), - }); -} - -const scenarioHandlers = { - "research-orchestrator": runResearchOrchestrator, - "research-orchestrator-scope-guard": runResearchOrchestratorScopeGuard, - "research-scoping-quality": runResearchScopingQuality, - "detailed-research": runDetailedResearch, - "detailed-research-scope-guard": runDetailedResearchScopeGuard, - "detailed-research-all-clear": runDetailedResearchAllClear, - "detailed-research-missing-evaluation-fallback": runDetailedResearchMissingEvaluationFallback, - "answer-evaluator": runAnswerEvaluator, - "confirm-decisions": runConfirmDecisions, - "confirm-decisions-scope-guard": runConfirmDecisionsScopeGuard, - "confirm-decisions-contradictory": runConfirmDecisionsContradictory, - "confirm-decisions-resolvable-conflict": runConfirmDecisionsResolvableConflict, - "generate-skill": runGenerateSkill, - "generate-skill-scope-guard": runGenerateSkillScopeGuard, - "generate-skill-contradictory": runGenerateSkillContradictory, - "generate-skill-revised": runGenerateSkillRevised, - "rewrite-skill": runRefineSkill, - "rewrite-skill-scope-guard": runRefineSkillScopeGuard, - "validate-skill-scope-guard": runValidateSkillScopeGuard, - "validate-skill-missing-skill-md": runValidateSkillMissingSkillMd, - "skill-test-contract": runSkillTestContract, -}; - -export default class SkillBuilderAgentProvider { - id() { - return "skill-builder-agent-regression"; - } - - async callApi(prompt, context) { - if (!hasApiAccess()) { - return { - error: - "Missing API auth. Set ANTHROPIC_API_KEY or FORCE_PLUGIN_TESTS=1 before running Promptfoo agent evals.", - }; - } - - const scenario = String(context?.vars?.scenario ?? prompt ?? "").trim(); - const runScenario = scenarioHandlers[scenario]; - if (!runScenario) { - return { - error: `Unknown scenario '${scenario}'. Expected one of: ${Object.keys( - scenarioHandlers - ).join(", ")}`, - }; - } - - const budgetUsd = parseBudget( - process.env.MAX_BUDGET_AGENTS, - process.env.MAX_BUDGET_WORKFLOW, - "2.00" - ); - - try { - const result = runScenario({ budgetUsd }); - return { output: JSON.stringify(result) }; - } catch (error) { - return { - error: error instanceof Error ? error.message : String(error), - }; - } - } -} diff --git a/app/agent-tests/promptfoo/scope-advisor-config.yaml b/app/agent-tests/promptfoo/scope-advisor-config.yaml deleted file mode 100644 index fd4a1fd80..000000000 --- a/app/agent-tests/promptfoo/scope-advisor-config.yaml +++ /dev/null @@ -1,138 +0,0 @@ -description: Scope advisor prompt quality — LLM behavior tests for review_skill_scope. - -# These tests call Sonnet directly with the exact prompt the Rust command builds. -# They verify what unit/component tests cannot: actual LLM reasoning quality. -# Run manually: npm run test:scope-advisor:smoke - -prompts: - - "{{scenario}}" - -providers: - - file://./scope-advisor-provider.mjs - -tests: - # Case 2: both name and description span multiple distinct processes - - description: scope-advisor-too-broad - vars: - scenario: scope-advisor-too-broad - assert: - - type: contains - value: '"parseSuccess":true' - - type: contains - value: '"statusIsString":true' - - type: contains - value: '"statusIsTooBoard":true' - - type: contains - value: '"reasonNonEmpty":true' - - type: contains - value: '"suggestedSkillsArray":true' - - type: contains - value: '"suggestionCountAtLeastThree":true' - - type: contains - value: '"allNamesGerund":true' - - type: contains - value: '"failures":[]' - - # Case 1: name not gerund, description already focused → 1 chip, description preserved - - description: scope-advisor-name-needs-improvement - vars: - scenario: scope-advisor-name-needs-improvement - assert: - - type: contains - value: '"parseSuccess":true' - - type: contains - value: '"statusIsNameNeedsImprovement":true' - - type: contains - value: '"reasonNonEmpty":true' - - type: contains - value: '"exactlyOneSuggestion":true' - - type: contains - value: '"suggestionNameIsGerund":true' - - type: contains - value: '"originalDescriptionPreserved":true' - - type: contains - value: '"failures":[]' - - # Case 4: name focused, description wanders into a second process → 2+ chips - - description: scope-advisor-description-needs-improvement - vars: - scenario: scope-advisor-description-needs-improvement - assert: - - type: contains - value: '"parseSuccess":true' - - type: contains - value: '"statusIsDescriptionNeedsImprovement":true' - - type: contains - value: '"reasonNonEmpty":true' - - type: contains - value: '"atLeastTwoSuggestions":true' - - type: contains - value: '"allNamesGerund":true' - - type: contains - value: '"failures":[]' - - # Case 3: both name and description too vague → 3-5 best-guess chips with caveat - - description: scope-advisor-both-need-improvement - vars: - scenario: scope-advisor-both-need-improvement - assert: - - type: contains - value: '"parseSuccess":true' - - type: contains - value: '"statusIsBothNeedImprovement":true' - - type: contains - value: '"reasonNonEmpty":true' - - type: contains - value: '"suggestionCountAtLeastThree":true' - - type: contains - value: '"allNamesGerund":true' - - type: contains - value: '"failures":[]' - - # Focused: both name and description pass all rules - - description: scope-advisor-focused - vars: - scenario: scope-advisor-focused - assert: - - type: contains - value: '"parseSuccess":true' - - type: contains - value: '"statusIsFocused":true' - - type: contains - value: '"reasonNonEmpty":true' - - type: contains - value: '"emptySuggestions":true' - - type: contains - value: '"failures":[]' - - # Context override: document narrows a broad-looking skill → focused - - description: scope-advisor-context-override - vars: - scenario: scope-advisor-context-override - assert: - - type: contains - value: '"parseSuccess":true' - - type: contains - value: '"contextOverrideWorks":true' - - type: contains - value: '"reasonNonEmpty":true' - - type: contains - value: '"failures":[]' - - # Non-English input: all suggested names must be English gerund kebab-case - - description: scope-advisor-non-english - vars: - scenario: scope-advisor-non-english - assert: - - type: contains - value: '"parseSuccess":true' - - type: contains - value: '"statusNotFocused":true' - - type: contains - value: '"hasSuggestions":true' - - type: contains - value: '"allNamesEnglish":true' - - type: contains - value: '"allNamesGerund":true' - - type: contains - value: '"failures":[]' diff --git a/app/agent-tests/promptfoo/scope-advisor-provider.mjs b/app/agent-tests/promptfoo/scope-advisor-provider.mjs deleted file mode 100644 index 0cf327a7a..000000000 --- a/app/agent-tests/promptfoo/scope-advisor-provider.mjs +++ /dev/null @@ -1,395 +0,0 @@ -/** - * Promptfoo provider for scope advisor smoke tests. - * - * Tests the prompt quality of the review_skill_scope Tauri command by sending - * the exact same prompt the Rust command builds to Sonnet via `claude -p`. - * Uses Claude Code's existing session auth — no ANTHROPIC_API_KEY required. - */ - -import { spawnSync } from "node:child_process"; - -const CLAUDE_BIN = process.env.CLAUDE_BIN ?? "claude"; - -function hasApiAccess() { - return Boolean(process.env.ANTHROPIC_API_KEY || process.env.FORCE_PLUGIN_TESTS || CLAUDE_BIN); -} - -/** - * Build the exact prompt the Rust `review_skill_scope` command sends to Sonnet. - * Keep in sync with app/src-tauri/src/commands/skill/scope_review.rs. - */ -function buildScopeReviewPrompt({ skillName, description, purpose, industry, documentContext }) { - const industryContext = industry - ? `\nIndustry context: ${industry}` - : ""; - const docContext = documentContext - ? `\n\n## Reference Documents\n\n${documentContext}` - : ""; - - return `You are evaluating whether a Claude skill is well-defined. These skills are used to build data warehouses and lakehouses — OLAP systems, not OLTP. The data source is valuable context but not compulsory. - -CORE TEST: Does the description describe exactly the process named by the skill? If yes → focused. If it wanders into a second process → fail. - -## Name rule -A good name uses the gerund pattern: verb-ing + specific object (kebab-case). -Pass: forecasting-churned-customers, validating-grain-feed-compliance -Fail: sales-analysis (not gerund), analyzing-data (object too vague) - -## Description rule -A good description serves ONE overarching process — the same process named by the skill. -Number of nouns does not matter — many nouns are fine if they all fall under one process. -Pass: validating-grain-feed-compliance covers quality testing + traceability docs + supplier audits → all serve one process → pass -Fail: description spans two distinct processes → split -Always fail: nouns from different business functions → split -Use general business knowledge for process boundaries. Uploaded documents can override. - -## Four cases — pick exactly one status and follow its action - -CASE 1 — name fails (not gerund OR too vague), description is already specific and focused → status: "name-needs-improvement" -Name fails when: not gerund (e.g. sales-analysis, procurement-process), or gerund but object too vague (e.g. analyzing-data) -Description must be good: specific nouns, one process, clear trigger -Example: name=sales-analysis, desc="Forecasts which customers are at risk of churning based on CRM health scores" → name not gerund, description already focused -Action: derive the correct gerund name from the description. Return exactly 1 suggestion with new name + ORIGINAL description unchanged. -Reason: state why name fails and that description was kept as-is. -NOTE: if description is also vague, use CASE 3 instead. - -CASE 2 — the skill covers a recognizable business domain that spans multiple distinct processes → status: "too-broad" -This applies even if the description does not explicitly list the sub-processes. If the name or description references a broad business function (e.g. recruitment, sales, procurement, supply chain) and you can infer from business knowledge what distinct processes it covers, it is too-broad — not vague. -Example A: name=sales-analysis, description="Analyzes revenue, pipeline health, and rep performance" (explicitly lists processes) -Example B: name=understand-recruitment-processes, description="understand recruitment processes of the company" (umbrella term — you can infer hiring, onboarding, interview scheduling, etc.) -Action: split into 3-5 focused skills. Anchor suggested names to the original name where possible. -Reason: name the distinct processes found (whether explicitly listed or inferred). - -CASE 3 — both name and description are so vague that you cannot identify even the business domain → status: "both-need-improvement" -The name and description give no signal about what area of the business is involved. You cannot infer sub-processes because there is no domain anchor. -Example: name=analyzing-data, description="Analyzes data for the team" — data about what? Which team? No domain signal at all. -Action: make 3-5 best-guess suggestions. -Reason: be transparent — state that both are too vague and suggestions may not match intent. -KEY DISTINCTION: if you can name the business domain (recruitment, sales, procurement, etc.) → use CASE 2 (too-broad). Only use CASE 3 when the domain itself is unclear. - -CASE 4 — name is focused, description wanders into one or more extra processes → status: "description-needs-improvement" -Example: name=forecasting-churned-customers, description="Forecasts churn risk and tracks renewal pipeline health" -Action: produce 1 suggestion per process found — (1) original name + description trimmed to match, then one additional suggestion per stray process (new gerund name + description for each). -Reason: name each stray process found. - -Use industry and document context to override a generic breadth signal. - -Skill to evaluate: -- Name: ${skillName} -- Description: ${description} -- Purpose: ${purpose}${industryContext}${docContext} - -All suggested names MUST use the gerund pattern: verb-ing + specific object (kebab-case). -Gerund examples: forecasting-churned-customers ✓ vs churn-forecast ✗, analyzing-rep-performance ✓ vs rep-performance-analysis ✗ - -Rules for names: present-participle verb + specific object, kebab-case, no generic nouns (data/metrics/analysis), no acronyms unless industry-standard (mrr, arr, crm). - -Rules for suggested descriptions: third person, one overarching process, specific nouns, one trigger (no OR listing). Each suggested description must itself pass the same evaluation criteria. - -Respond in English only. - -Respond with JSON only (no markdown fences, no extra text): -{"status": string, "reason": string, "suggested_skills": [{"name": string, "description": string}]}`; -} - -function callSonnet(promptText) { - const env = { ...process.env, CLAUDECODE: undefined, ANTHROPIC_API_KEY: undefined }; - const result = spawnSync( - CLAUDE_BIN, - ["-p", "--model", process.env.SCOPE_ADVISOR_MODEL ?? "claude-sonnet-4-6"], - { - input: promptText, - encoding: "utf8", - env, - timeout: 120_000, - stdio: ["pipe", "pipe", "pipe"], - }, - ); - if (result.error) throw new Error(`claude process error: ${result.error.message}`); - if (result.status !== 0) { - const stderr = (result.stderr ?? "").trim(); - const stdout = (result.stdout ?? "").trim(); - throw new Error(`claude exited ${result.status}: ${stderr || stdout || "(no output)"}`); - } - const text = (result.stdout ?? "").trim(); - // Strip markdown fences if the model wrapped its response - return text - .replace(/^```json\n?/, "") - .replace(/^```\n?/, "") - .replace(/\n?```$/, "") - .trim(); -} - -/** Returns true if name starts with a gerund word (ends in -ing) followed by at least one kebab segment */ -function isGerundName(name) { - // e.g. forecasting-churned-customers, analyzing-rep-performance - return /^[a-z]+ing(-[a-z0-9]+)+$/.test(name); -} - -/** Returns true if name is ASCII lowercase + hyphens only (no non-English characters) */ -function isEnglishKebab(name) { - return /^[a-z-]+$/.test(name); -} - -function finalizeScenario(scenario, contracts) { - const failures = Object.entries(contracts) - .filter(([, v]) => v !== true) - .map(([k]) => k); - return { scenario, ok: failures.length === 0, ...contracts, failures }; -} - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -function parseResult(raw, scenario) { - try { - return { parsed: JSON.parse(raw), parseSuccess: true }; - } catch { - return { parsed: null, parseSuccess: false }; - } -} - -// --------------------------------------------------------------------------- -// Scenario handlers — four evaluation cases + focused + context-override + non-english -// --------------------------------------------------------------------------- - -/** - * Case 2: both name and description span multiple distinct processes. - * Expected: status="too-broad", 3–5 split suggestions, all gerund-named. - */ -function runTooBroad() { - const prompt = buildScopeReviewPrompt({ - skillName: "sales-analysis", - description: - "Analyzes revenue trends, sales rep performance, pipeline health, and customer churn. " + - "Uses Salesforce CRM and Marketo data to generate reports across all commercial functions.", - purpose: "domain", - industry: null, - documentContext: null, - }); - const raw = callSonnet(prompt); - const { parsed, parseSuccess } = parseResult(raw, "scope-advisor-too-broad"); - if (!parseSuccess) return finalizeScenario("scope-advisor-too-broad", { parseSuccess: false }); - const suggestions = Array.isArray(parsed.suggested_skills) ? parsed.suggested_skills : []; - const allGerund = suggestions.length > 0 && suggestions.every((s) => isGerundName(s.name)); - return finalizeScenario("scope-advisor-too-broad", { - parseSuccess: true, - statusIsString: typeof parsed.status === "string", - statusIsTooBoard: parsed.status === "too-broad", - reasonNonEmpty: typeof parsed.reason === "string" && parsed.reason.trim().length > 0, - suggestedSkillsArray: Array.isArray(parsed.suggested_skills), - suggestionCountAtLeastThree: suggestions.length >= 3, - allNamesGerund: allGerund, - }); -} - -/** - * Case 1: name not gerund, description already focused. - * Expected: status="name-needs-improvement", exactly 1 suggestion, original description preserved. - */ -function runNameNeedsImprovement() { - const originalDescription = - "Forecasts which customers are at risk of churning based on Salesforce health scores. " + - "Use when the customer success team needs a prioritised list of at-risk accounts."; - const prompt = buildScopeReviewPrompt({ - skillName: "sales-analysis", - description: originalDescription, - purpose: "domain", - industry: "SaaS", - documentContext: null, - }); - const raw = callSonnet(prompt); - const { parsed, parseSuccess } = parseResult(raw, "scope-advisor-name-needs-improvement"); - if (!parseSuccess) return finalizeScenario("scope-advisor-name-needs-improvement", { parseSuccess: false }); - const suggestions = Array.isArray(parsed.suggested_skills) ? parsed.suggested_skills : []; - const oneSuggestion = suggestions.length === 1; - const suggestionGerund = oneSuggestion && isGerundName(suggestions[0].name); - const descriptionPreserved = oneSuggestion && suggestions[0].description === originalDescription; - return finalizeScenario("scope-advisor-name-needs-improvement", { - parseSuccess: true, - statusIsNameNeedsImprovement: parsed.status === "name-needs-improvement", - reasonNonEmpty: typeof parsed.reason === "string" && parsed.reason.trim().length > 0, - exactlyOneSuggestion: oneSuggestion, - suggestionNameIsGerund: suggestionGerund, - originalDescriptionPreserved: descriptionPreserved, - }); -} - -/** - * Case 4: name focused and gerund, description wanders into a second process. - * Expected: status="description-needs-improvement", 2+ suggestions (one per process). - */ -function runDescriptionNeedsImprovement() { - const prompt = buildScopeReviewPrompt({ - skillName: "forecasting-churned-customers", - description: - "Forecasts which customers are at risk of churning based on health scores " + - "and tracks renewal pipeline health across enterprise accounts.", - purpose: "domain", - industry: "SaaS", - documentContext: null, - }); - const raw = callSonnet(prompt); - const { parsed, parseSuccess } = parseResult(raw, "scope-advisor-description-needs-improvement"); - if (!parseSuccess) return finalizeScenario("scope-advisor-description-needs-improvement", { parseSuccess: false }); - const suggestions = Array.isArray(parsed.suggested_skills) ? parsed.suggested_skills : []; - const allGerund = suggestions.length > 0 && suggestions.every((s) => isGerundName(s.name)); - return finalizeScenario("scope-advisor-description-needs-improvement", { - parseSuccess: true, - statusIsDescriptionNeedsImprovement: parsed.status === "description-needs-improvement", - reasonNonEmpty: typeof parsed.reason === "string" && parsed.reason.trim().length > 0, - atLeastTwoSuggestions: suggestions.length >= 2, - allNamesGerund: allGerund, - }); -} - -/** - * Case 3: both name and description so vague that the business domain itself is unclear. - * Expected: status="both-need-improvement", 3–5 suggestions, caveat in reason. - */ -function runBothNeedImprovement() { - const prompt = buildScopeReviewPrompt({ - skillName: "analyzing-data", - description: "Analyzes data for the team.", - purpose: "domain", - industry: null, - documentContext: null, - }); - const raw = callSonnet(prompt); - const { parsed, parseSuccess } = parseResult(raw, "scope-advisor-both-need-improvement"); - if (!parseSuccess) return finalizeScenario("scope-advisor-both-need-improvement", { parseSuccess: false }); - const suggestions = Array.isArray(parsed.suggested_skills) ? parsed.suggested_skills : []; - const allGerund = suggestions.length > 0 && suggestions.every((s) => isGerundName(s.name)); - return finalizeScenario("scope-advisor-both-need-improvement", { - parseSuccess: true, - statusIsBothNeedImprovement: parsed.status === "both-need-improvement", - reasonNonEmpty: typeof parsed.reason === "string" && parsed.reason.trim().length > 0, - suggestionCountAtLeastThree: suggestions.length >= 3, - allNamesGerund: allGerund, - }); -} - -/** - * Focused: both name and description pass all rules. - * Expected: status="focused", empty suggested_skills. - */ -function runFocused() { - const prompt = buildScopeReviewPrompt({ - skillName: "forecasting-churned-customers", - description: - "Forecasts which customers are at risk of churning based on Salesforce activity signals " + - "and health scores. Use when the customer success team needs a prioritised list of at-risk accounts.", - purpose: "domain", - industry: "SaaS", - documentContext: null, - }); - const raw = callSonnet(prompt); - const { parsed, parseSuccess } = parseResult(raw, "scope-advisor-focused"); - if (!parseSuccess) return finalizeScenario("scope-advisor-focused", { parseSuccess: false }); - const suggestions = Array.isArray(parsed.suggested_skills) ? parsed.suggested_skills : []; - return finalizeScenario("scope-advisor-focused", { - parseSuccess: true, - statusIsFocused: parsed.status === "focused", - reasonNonEmpty: typeof parsed.reason === "string" && parsed.reason.trim().length > 0, - emptySuggestions: suggestions.length === 0, - }); -} - -/** - * Context override: description looks broad generically but a reference document - * establishes it as one tightly scoped workflow. Expected: status="focused". - */ -function runContextOverride() { - const prompt = buildScopeReviewPrompt({ - skillName: "reporting-arr-waterfall", - description: "Reports on revenue metrics and growth for the finance team.", - purpose: "domain", - industry: "SaaS", - documentContext: - "### ARR Reporting Standards\n" + - "In this company, revenue metrics refers exclusively to the ARR waterfall report: " + - "new ARR, expansion ARR, contraction ARR, and churned ARR. This is a single weekly report " + - "produced from Salesforce Opportunities data. No other revenue concepts are in scope.", - }); - const raw = callSonnet(prompt); - const { parsed, parseSuccess } = parseResult(raw, "scope-advisor-context-override"); - if (!parseSuccess) return finalizeScenario("scope-advisor-context-override", { parseSuccess: false }); - return finalizeScenario("scope-advisor-context-override", { - parseSuccess: true, - contextOverrideWorks: parsed.status === "focused", - reasonNonEmpty: typeof parsed.reason === "string" && parsed.reason.trim().length > 0, - }); -} - -/** - * Non-English input (French): all suggested names must be English gerund kebab-case. - */ -function runNonEnglish() { - const prompt = buildScopeReviewPrompt({ - skillName: "analyse-des-ventes", - description: - "Analyse les tendances de revenus, les performances des représentants commerciaux, " + - "la santé du pipeline et le taux de désabonnement des clients.", - purpose: "domain", - industry: null, - documentContext: null, - }); - const raw = callSonnet(prompt); - const { parsed, parseSuccess } = parseResult(raw, "scope-advisor-non-english"); - if (!parseSuccess) return finalizeScenario("scope-advisor-non-english", { parseSuccess: false }); - const suggestions = Array.isArray(parsed.suggested_skills) ? parsed.suggested_skills : []; - const allEnglish = suggestions.every((s) => isEnglishKebab(s.name)); - const allGerund = suggestions.length > 0 && suggestions.every((s) => isGerundName(s.name)); - return finalizeScenario("scope-advisor-non-english", { - parseSuccess: true, - statusNotFocused: parsed.status !== "focused", - hasSuggestions: suggestions.length >= 3, - allNamesEnglish: allEnglish, - allNamesGerund: allGerund, - }); -} - -// --------------------------------------------------------------------------- -// Provider export -// --------------------------------------------------------------------------- - -const scenarioHandlers = { - "scope-advisor-too-broad": runTooBroad, - "scope-advisor-name-needs-improvement": runNameNeedsImprovement, - "scope-advisor-description-needs-improvement": runDescriptionNeedsImprovement, - "scope-advisor-both-need-improvement": runBothNeedImprovement, - "scope-advisor-focused": runFocused, - "scope-advisor-context-override": runContextOverride, - "scope-advisor-non-english": runNonEnglish, -}; - -export default class ScopeAdvisorProvider { - id() { - return "scope-advisor-smoke"; - } - - async callApi(prompt, context) { - if (!hasApiAccess()) { - return { - error: - "Missing API auth. Set ANTHROPIC_API_KEY or FORCE_PLUGIN_TESTS=1 before running scope advisor smoke tests.", - }; - } - - const scenario = String(context?.vars?.scenario ?? prompt ?? "").trim(); - const handler = scenarioHandlers[scenario]; - if (!handler) { - return { - error: `Unknown scenario '${scenario}'. Expected one of: ${Object.keys(scenarioHandlers).join(", ")}`, - }; - } - - try { - const result = handler(); - return { output: JSON.stringify(result) }; - } catch (error) { - return { error: error instanceof Error ? error.message : String(error) }; - } - } -} diff --git a/app/package.json b/app/package.json index b1ecc96bb..b6d1be1ec 100644 --- a/app/package.json +++ b/app/package.json @@ -31,8 +31,9 @@ "test:changed": "vitest run --changed HEAD~1", "test:agents": "npm run test:agents:structural && npm run test:agents:smoke", "test:agents:structural": "vitest run --config vitest.config.agent.ts agent-tests/agent-structure.test.ts", - "test:agents:smoke": "mkdir -p test-results && promptfoo eval -c agent-tests/promptfoo/promptfooconfig.yaml -o test-results/promptfoo-results.json -o test-results/promptfoo-results.html", - "test:scope-advisor:smoke": "node -e \"require('fs').mkdirSync('test-results', {recursive:true})\" && promptfoo eval -c agent-tests/promptfoo/scope-advisor-config.yaml -o test-results/scope-advisor-results.json -o test-results/scope-advisor-results.html", + "test:agents:smoke": "cd ../tests/evals && npm run eval:agents", + "test:scope-advisor:smoke": "cd ../tests/evals && npm run eval:scope-advisor", + "test:evals:harness": "cd ../tests/evals && npm test", "test:all": "npm run test:unit && npm run test:guard && npm run test:integration && npm run test:e2e" }, "dependencies": { diff --git a/app/scripts/lint-agent-docs.sh b/app/scripts/lint-agent-docs.sh index 81804a119..f878912e9 100755 --- a/app/scripts/lint-agent-docs.sh +++ b/app/scripts/lint-agent-docs.sh @@ -9,9 +9,12 @@ check_paths=( "AGENTS.md" "CLAUDE.md" ".claude/rules" - ".claude/skills" ) +if [[ -d ".claude/skills" ]]; then + check_paths+=(".claude/skills") +fi + legacy_patterns=( "linear-server:" "feature-dev:" diff --git a/docs/superpowers/plans/2026-05-01-release-docs-ci.md b/docs/superpowers/plans/2026-05-01-release-docs-ci.md new file mode 100644 index 000000000..f7d997910 --- /dev/null +++ b/docs/superpowers/plans/2026-05-01-release-docs-ci.md @@ -0,0 +1,678 @@ +# Release Docs CI Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Fix release packaging, docs deployment, and PR CI so automated checks are cheap but still catch release-resource and help-doc drift. + +**Architecture:** Add two deterministic root scripts: one verifies staged release artifacts against the Tauri resource contract, and one verifies help URLs and VitePress sidebar links against `docs/user-guide`. Wire those scripts into targeted GitHub workflows, then narrow heavyweight PR CI so local `raising-linear-pr` remains the deep validation gate. + +**Tech Stack:** GitHub Actions YAML, Tauri v2 resource config, Node.js built-in `node:test`, VitePress, markdown user guide files. + +--- + +## File Structure + +- Create `scripts/verify-release-stage.mjs`: CLI and exported verifier for staged release directories. +- Create `scripts/verify-release-stage.test.mjs`: Node built-in tests for release verifier success and missing-file failure. +- Create `scripts/check-help-docs.mjs`: CLI and exported checker for help URL/sidebar markdown targets. +- Create `scripts/check-help-docs.test.mjs`: Node built-in tests for help checker path resolution and missing-file failure. +- Modify `.github/workflows/release.yml`: stage the Tauri resource paths and run release verification before upload. +- Modify `.github/workflows/docs.yml`: use `npm ci`, add lockfile path trigger, and run help-doc checker. +- Modify `.github/workflows/pr-policy.yml`: path-filter docs build/help checks and expand repo-map audit paths. +- Modify `.github/workflows/pr-ci.yml`: make expensive jobs main/manual by default and keep PR checks cheap. +- Modify `docs/.vitepress/config.ts`: keep sidebar links parseable by the help checker. +- Modify `docs/user-guide/**/*.md`: refresh stale help content found during the implementation. +- Modify `AGENTS.md` or `repo-map.json` only if the implementation adds durable commands or structural guidance that should be discoverable by later agents. + +## Task 1: Release Stage Verifier + +**Files:** + +- Create: `scripts/verify-release-stage.mjs` +- Create: `scripts/verify-release-stage.test.mjs` + +- [ ] **Step 1: Write the failing release verifier tests** + +Create `scripts/verify-release-stage.test.mjs` with Node's built-in test runner: + +```javascript +import test from "node:test"; +import assert from "node:assert/strict"; +import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs"; +import { join } from "node:path"; +import { tmpdir } from "node:os"; +import { verifyReleaseStage } from "./verify-release-stage.mjs"; + +function makeStage() { + const root = mkdtempSync(join(tmpdir(), "skill-builder-release-")); + const files = [ + "skill-builder.exe", + "sidecar/dist/package.json", + "sidecar/dist/bootstrap.js", + "sidecar/dist/agent-runner.js", + "sidecar/dist/sdk/manifest.json", + "agent-sources/plugins/skill-creator/LICENSE.txt", + "agent-sources/skills/skill-test/SKILL.md", + "workspace/CLAUDE.md", + "workspace/prompts/workflow-step.txt", + ]; + + for (const file of files) { + const path = join(root, file); + mkdirSync(path.slice(0, path.lastIndexOf("/")), { recursive: true }); + writeFileSync(path, "fixture\n"); + } + + return root; +} + +test("verifyReleaseStage accepts a complete Windows stage", () => { + const root = makeStage(); + try { + assert.deepEqual(verifyReleaseStage(root, "windows"), []); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); + +test("verifyReleaseStage reports every missing required path", () => { + const root = mkdtempSync(join(tmpdir(), "skill-builder-release-missing-")); + try { + const missing = verifyReleaseStage(root, "windows"); + assert.ok(missing.includes("skill-builder.exe")); + assert.ok(missing.includes("sidecar/dist/bootstrap.js")); + assert.ok(missing.includes("agent-sources/plugins/skill-creator/LICENSE.txt")); + assert.ok(missing.includes("workspace/prompts/workflow-step.txt")); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); +``` + +- [ ] **Step 2: Run the release verifier tests and confirm they fail** + +Run: + +```bash +node --test scripts/verify-release-stage.test.mjs +``` + +Expected: FAIL with an import error because `scripts/verify-release-stage.mjs` does not exist yet. + +- [ ] **Step 3: Implement the release verifier** + +Create `scripts/verify-release-stage.mjs`: + +```javascript +#!/usr/bin/env node +import { existsSync } from "node:fs"; +import { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const REQUIRED_BY_PLATFORM = { + windows: [ + "skill-builder.exe", + "sidecar/dist/package.json", + "sidecar/dist/bootstrap.js", + "sidecar/dist/agent-runner.js", + "sidecar/dist/sdk/manifest.json", + "agent-sources/plugins/skill-creator/LICENSE.txt", + "agent-sources/skills/skill-test/SKILL.md", + "workspace/CLAUDE.md", + "workspace/prompts/workflow-step.txt", + ], + macos: [ + "Skill Builder.app", + "run.sh", + ], +}; + +export function verifyReleaseStage(stageDir, platform) { + const required = REQUIRED_BY_PLATFORM[platform]; + if (!required) { + throw new Error(`Unknown release platform: ${platform}`); + } + + return required.filter((relativePath) => !existsSync(resolve(stageDir, relativePath))); +} + +function main() { + const [stageDir, platform] = process.argv.slice(2); + if (!stageDir || !platform) { + console.error("Usage: node scripts/verify-release-stage.mjs "); + process.exit(2); + } + + const missing = verifyReleaseStage(stageDir, platform); + if (missing.length > 0) { + console.error(`Release stage is missing ${missing.length} required path(s):`); + for (const path of missing) { + console.error(`- ${path}`); + } + process.exit(1); + } + + console.log(`Release stage verified for ${platform}: ${stageDir}`); +} + +if (process.argv[1] === fileURLToPath(import.meta.url)) { + main(); +} +``` + +- [ ] **Step 4: Run the release verifier tests and confirm they pass** + +Run: + +```bash +node --test scripts/verify-release-stage.test.mjs +``` + +Expected: PASS with two passing tests. + +- [ ] **Step 5: Commit the release verifier** + +Run: + +```bash +git add scripts/verify-release-stage.mjs scripts/verify-release-stage.test.mjs +git commit -m "VU-1134: add release stage verifier" +``` + +## Task 2: Release Workflow Packaging Repair + +**Files:** + +- Modify: `.github/workflows/release.yml` +- Test: `scripts/verify-release-stage.test.mjs` + +- [ ] **Step 1: Replace stale Windows resource staging** + +In `.github/workflows/release.yml`, update the `Package Windows release` step so the staging block copies the Tauri resource contract instead of old `agents` and `references` folders: + +```bash + # Copy sidecar JS files. The Rust exe-relative fallback looks for + # {exe_dir}/sidecar/dist/... + mkdir -p "$STAGE/sidecar/dist/sdk" + cp "app/sidecar/dist/package.json" "$STAGE/sidecar/dist/" + cp "app/sidecar/dist/bootstrap.js" "$STAGE/sidecar/dist/" + cp "app/sidecar/dist/agent-runner.js" "$STAGE/sidecar/dist/" + cp "app/sidecar/dist/sdk/cli.js" "$STAGE/sidecar/dist/sdk/" + cp "app/sidecar/dist/sdk/manifest.json" "$STAGE/sidecar/dist/sdk/" + cp app/sidecar/dist/sdk/*.wasm "$STAGE/sidecar/dist/sdk/" 2>/dev/null || true + if [ -d "app/sidecar/dist/sdk/vendor" ]; then + cp -r "app/sidecar/dist/sdk/vendor" "$STAGE/sidecar/dist/sdk/" + fi + + mkdir -p "$STAGE/agent-sources" "$STAGE/workspace" + cp -r "agent-sources/plugins" "$STAGE/agent-sources/plugins" + cp -r "agent-sources/skills" "$STAGE/agent-sources/skills" + cp -r "agent-sources/workspace/." "$STAGE/workspace/" + + node scripts/verify-release-stage.mjs "$STAGE" windows +``` + +- [ ] **Step 2: Add macOS stage verification** + +In the `Package macOS release` step, run the verifier before zipping: + +```bash + chmod +x "$STAGE/run.sh" + node scripts/verify-release-stage.mjs "$STAGE" macos + zip -r "${STAGE}.zip" "$STAGE" +``` + +- [ ] **Step 3: Run YAML and verifier checks** + +Run: + +```bash +python3 - <<'PY' +from pathlib import Path +import yaml +for path in Path(".github/workflows").glob("*.yml"): + yaml.safe_load(path.read_text()) +print("workflow yaml ok") +PY +node --test scripts/verify-release-stage.test.mjs +``` + +Expected: `workflow yaml ok` and the release verifier tests pass. + +- [ ] **Step 4: Commit release workflow repair** + +Run: + +```bash +git add .github/workflows/release.yml +git commit -m "VU-1134: repair release resource packaging" +``` + +## Task 3: Help Docs Freshness Checker + +**Files:** + +- Create: `scripts/check-help-docs.mjs` +- Create: `scripts/check-help-docs.test.mjs` +- Modify: `docs/.vitepress/config.ts` + +- [ ] **Step 1: Write the failing help checker tests** + +Create `scripts/check-help-docs.test.mjs`: + +```javascript +import test from "node:test"; +import assert from "node:assert/strict"; +import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs"; +import { join } from "node:path"; +import { tmpdir } from "node:os"; +import { helpLinkToMarkdownPath, findMissingHelpDocs } from "./check-help-docs.mjs"; + +test("helpLinkToMarkdownPath resolves root and nested guide links", () => { + const root = "/repo/docs/user-guide"; + assert.equal(helpLinkToMarkdownPath(root, "/"), "/repo/docs/user-guide/index.md"); + assert.equal( + helpLinkToMarkdownPath(root, "/workflow/step-1-research"), + "/repo/docs/user-guide/workflow/step-1-research.md", + ); +}); + +test("findMissingHelpDocs reports missing sidebar and app help links", () => { + const root = mkdtempSync(join(tmpdir(), "skill-builder-help-")); + try { + mkdirSync(join(root, "docs/user-guide/workflow"), { recursive: true }); + mkdirSync(join(root, "docs/.vitepress"), { recursive: true }); + mkdirSync(join(root, "app/src/lib"), { recursive: true }); + writeFileSync(join(root, "docs/user-guide/index.md"), "# Home\n"); + writeFileSync(join(root, "app/src/lib/help-urls.ts"), "const BASE = \"https://hbanerjee74.github.io/skill-builder\";\nexport const x = `${BASE}/workflow/missing`;\n"); + writeFileSync(join(root, "docs/.vitepress/config.ts"), "export default { themeConfig: { sidebar: [{ items: [{ text: 'Missing', link: '/missing' }] }] } };\n"); + + const missing = findMissingHelpDocs(root); + assert.ok(missing.includes("/workflow/missing -> docs/user-guide/workflow/missing.md")); + assert.ok(missing.includes("/missing -> docs/user-guide/missing.md")); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); +``` + +- [ ] **Step 2: Run the help checker tests and confirm they fail** + +Run: + +```bash +node --test scripts/check-help-docs.test.mjs +``` + +Expected: FAIL with an import error because `scripts/check-help-docs.mjs` does not exist yet. + +- [ ] **Step 3: Implement the help checker** + +Create `scripts/check-help-docs.mjs`: + +```javascript +#!/usr/bin/env node +import { existsSync, readFileSync } from "node:fs"; +import { relative, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const BASE_URL = "https://hbanerjee74.github.io/skill-builder"; + +export function helpLinkToMarkdownPath(docsRoot, link) { + const clean = link.replace(BASE_URL, "").replace(/#.*$/, "") || "/"; + if (clean === "/") return resolve(docsRoot, "index.md"); + return resolve(docsRoot, `${clean.replace(/^\/+/, "")}.md`); +} + +function collectLinksFromText(text) { + const links = new Set(); + const patterns = [ + /https:\/\/hbanerjee74\.github\.io\/skill-builder(\/[^`"'\s)]*)?/g, + /\$\{BASE\}(\/[^`"'\s)]*)/g, + /link:\s*["'](\/[^"']*)["']/g, + ]; + + for (const pattern of patterns) { + for (const match of text.matchAll(pattern)) { + const value = match[1] ?? match[0]; + if (value.startsWith("${")) continue; + links.add(value.replace(/[`"',)]*$/, "")); + } + } + + return [...links]; +} + +export function findMissingHelpDocs(repoRoot = process.cwd()) { + const docsRoot = resolve(repoRoot, "docs/user-guide"); + const sources = [ + "app/src/lib/help-urls.ts", + "docs/.vitepress/config.ts", + ]; + const missing = []; + + for (const source of sources) { + const sourcePath = resolve(repoRoot, source); + if (!existsSync(sourcePath)) continue; + + const links = collectLinksFromText(readFileSync(sourcePath, "utf8")); + for (const link of links) { + const markdownPath = helpLinkToMarkdownPath(docsRoot, link); + if (!existsSync(markdownPath)) { + missing.push(`${link.replace(BASE_URL, "") || "/"} -> ${relative(repoRoot, markdownPath)}`); + } + } + } + + return [...new Set(missing)].sort(); +} + +function main() { + const missing = findMissingHelpDocs(process.cwd()); + if (missing.length > 0) { + console.error("Missing help documentation targets:"); + for (const item of missing) { + console.error(`- ${item}`); + } + process.exit(1); + } + + console.log("Help documentation links verified."); +} + +if (process.argv[1] === fileURLToPath(import.meta.url)) { + main(); +} +``` + +- [ ] **Step 4: Run the help checker tests and live checker** + +Run: + +```bash +node --test scripts/check-help-docs.test.mjs +node scripts/check-help-docs.mjs +``` + +Expected: tests pass and live checker prints `Help documentation links verified.` + +- [ ] **Step 5: Commit help checker** + +Run: + +```bash +git add scripts/check-help-docs.mjs scripts/check-help-docs.test.mjs +git commit -m "VU-1134: add help docs freshness checker" +``` + +## Task 4: Docs Workflow and Help Page Refresh + +**Files:** + +- Modify: `.github/workflows/docs.yml` +- Modify: `.github/workflows/pr-policy.yml` +- Modify: `docs/user-guide/**/*.md` +- Test: `scripts/check-help-docs.mjs` + +- [ ] **Step 1: Make docs deploy deterministic** + +In `.github/workflows/docs.yml`, add `docs/package-lock.json` to the trigger and replace `npm install` with `npm ci`: + +```yaml + paths: + - "docs/user-guide/**" + - "docs/.vitepress/**" + - "docs/package.json" + - "docs/package-lock.json" +``` + +```yaml + - name: Install dependencies + run: npm ci + working-directory: docs + + - name: Check help documentation links + run: node scripts/check-help-docs.mjs +``` + +The checker step runs from the repository root, so do not set `working-directory` for that step. + +- [ ] **Step 2: Path-filter docs policy build** + +In `.github/workflows/pr-policy.yml`, update `docs-build` to detect docs changes before installing dependencies: + +```yaml + - name: Detect relevant changes + id: changes + uses: dorny/paths-filter@v4 + with: + filters: | + docs: + - 'docs/user-guide/**' + - 'docs/.vitepress/**' + - 'docs/package.json' + - 'docs/package-lock.json' + - 'scripts/check-help-docs.mjs' +``` + +Add `if: steps.changes.outputs.docs == 'true'` to the Node setup, install, checker, and build steps. Add this skip step: + +```yaml + - name: Skip (no docs changes) + if: steps.changes.outputs.docs != 'true' + run: echo "No docs changes detected — skipping." +``` + +- [ ] **Step 3: Refresh stale user guide pages** + +Read the current pages under `docs/user-guide/` and update any stale references to removed UI or old page names. Keep each page product-facing and concise. At minimum, confirm these pages match the current app navigation: + +```bash +sed -n '1,220p' docs/user-guide/index.md +sed -n '1,220p' docs/user-guide/dashboard.md +sed -n '1,220p' docs/user-guide/refine.md +sed -n '1,220p' docs/user-guide/settings.md +sed -n '1,220p' docs/user-guide/test.md +sed -n '1,220p' docs/user-guide/usage.md +``` + +If edits are needed, make surgical markdown changes only. Do not add implementation details, internal file paths, or agent runtime architecture to the user guide. + +- [ ] **Step 4: Run docs checks** + +Run: + +```bash +node scripts/check-help-docs.mjs +cd docs && npm ci && npm run build +cd .. && npx markdownlint-cli2 "docs/user-guide/**/*.md" +``` + +Expected: help links verified, VitePress build passes, and markdownlint reports `0 error(s)`. + +- [ ] **Step 5: Commit docs workflow and guide updates** + +Run: + +```bash +git add .github/workflows/docs.yml .github/workflows/pr-policy.yml docs/user-guide scripts/check-help-docs.mjs scripts/check-help-docs.test.mjs +git commit -m "VU-1134: make help docs checks deterministic" +``` + +If Task 3 was already committed, omit `scripts/check-help-docs.mjs` and `scripts/check-help-docs.test.mjs` from this commit. + +## Task 5: Cheap PR CI Restructure + +**Files:** + +- Modify: `.github/workflows/pr-ci.yml` +- Modify: `.github/workflows/pr-policy.yml` +- Test: workflow YAML parser + +- [ ] **Step 1: Keep heavyweight platform CI off ordinary PRs** + +In `.github/workflows/pr-ci.yml`, change the `pull_request` trigger to a manual/main-oriented workflow by removing the PR trigger or making each heavyweight job skip PR events. The preferred minimal change is to remove this block: + +```yaml + pull_request: + branches: + - main + paths-ignore: + - '**/*.md' + - 'LICENSE' +``` + +Keep `workflow_dispatch` and `push` to `main`. This makes multi-platform cargo, clippy, full frontend tests, and integration tests available on demand and on main without making every PR pay for them. + +- [ ] **Step 2: Expand repo-map audit coverage in PR policy** + +In `.github/workflows/pr-policy.yml`, add structural areas introduced by this branch to `STRUCTURAL_DIRS`: + +```bash + STRUCTURAL_DIRS=( + ".github/" + "scripts/" + "tests/evals/" + "app/src-tauri/src/commands/" + "app/src/stores/" + "app/src/pages/" + "app/src/components/" + "app/src/lib/" + "app/src/hooks/" + ) +``` + +This keeps the cheap PR policy job honest when workflow, script, or eval harness structure changes. + +- [ ] **Step 3: Ensure policy jobs cover the new deterministic scripts** + +In `.github/workflows/pr-policy.yml`, add a lightweight script-tests job: + +```yaml + script-tests: + name: script-tests + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Detect relevant changes + id: changes + uses: dorny/paths-filter@v4 + with: + filters: | + scripts: + - 'scripts/*.mjs' + + - name: Run script tests + if: steps.changes.outputs.scripts == 'true' + run: node --test scripts/*.test.mjs + + - name: Skip (no script changes) + if: steps.changes.outputs.scripts != 'true' + run: echo "No script changes detected — skipping." +``` + +- [ ] **Step 4: Run workflow syntax checks** + +Run: + +```bash +python3 - <<'PY' +from pathlib import Path +import yaml +for path in Path(".github/workflows").glob("*.yml"): + yaml.safe_load(path.read_text()) +print("workflow yaml ok") +PY +node --test scripts/*.test.mjs +``` + +Expected: YAML parses and script tests pass. + +- [ ] **Step 5: Commit cheap CI restructure** + +Run: + +```bash +git add .github/workflows/pr-ci.yml .github/workflows/pr-policy.yml +git commit -m "VU-1134: keep PR CI cheap and targeted" +``` + +## Task 6: Final Verification and Push + +**Files:** + +- Verify: all changed files +- Modify only if required by verification: `AGENTS.md`, `repo-map.json`, `TEST_MANIFEST.md` + +- [ ] **Step 1: Run all deterministic checks for this implementation** + +Run: + +```bash +node --test scripts/*.test.mjs +node scripts/check-help-docs.mjs +node scripts/verify-release-stage.mjs "$(mktemp -d)" windows || true +python3 - <<'PY' +from pathlib import Path +import yaml +for path in Path(".github/workflows").glob("*.yml"): + yaml.safe_load(path.read_text()) +print("workflow yaml ok") +PY +cd docs && npm ci && npm run build +cd .. && npx markdownlint-cli2 "docs/user-guide/**/*.md" "docs/superpowers/**/*.md" +``` + +Expected: + +- `node --test scripts/*.test.mjs` passes. +- `node scripts/check-help-docs.mjs` prints `Help documentation links verified.` +- The intentionally empty release-stage command exits non-zero and prints missing required paths; this confirms the CLI failure path. +- YAML parser prints `workflow yaml ok`. +- Docs build succeeds. +- Markdownlint reports `0 error(s)`. + +- [ ] **Step 2: Audit repo-map and manifest requirements** + +Run: + +```bash +git diff --name-status origin/main...HEAD +``` + +If files were added or removed under `app/src-tauri/src/commands/`, `app/src/stores/`, `app/src/pages/`, `app/src/components/`, `app/src/lib/`, `app/src/hooks/`, `.github/`, `scripts/`, or `tests/evals/`, update `repo-map.json` in the same branch before final push. If Rust command files or E2E specs changed, update `TEST_MANIFEST.md`. + +- [ ] **Step 3: Review final diff** + +Run: + +```bash +git diff --stat origin/main...HEAD +git diff --check +``` + +Expected: diff is scoped to release/docs/CI planning and implementation, and `git diff --check` reports no whitespace errors. + +- [ ] **Step 4: Commit any verification-driven doc metadata updates** + +If Step 2 required metadata updates, run: + +```bash +git add AGENTS.md repo-map.json TEST_MANIFEST.md +git commit -m "VU-1134: update repository metadata for CI checks" +``` + +If no metadata updates were needed, do not create an empty commit. + +- [ ] **Step 5: Push the branch** + +Run: + +```bash +git status --short --branch +git push +``` + +Expected: branch pushes cleanly to `origin/feature/vu-1134-replace-agent-eval-harness-with-migration-utility-tiered`. diff --git a/docs/superpowers/plans/2026-05-01-vu-1134-eval-harness.md b/docs/superpowers/plans/2026-05-01-vu-1134-eval-harness.md new file mode 100644 index 000000000..15141045d --- /dev/null +++ b/docs/superpowers/plans/2026-05-01-vu-1134-eval-harness.md @@ -0,0 +1,91 @@ +# VU-1134 Eval Harness Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace the app-local Promptfoo harness with a root `tests/evals` harness patterned after Migration Utility's tiered runner, and prove it with one OpenCode-backed smoke eval. + +**Architecture:** The new harness owns its own npm package, repo-local Promptfoo state, config-resolution scripts, tier config, OpenCode provider config, and package-level eval configs. Skill Builder eval packages run through the Migration Utility-style `opencode-cli-provider.js` and suite-level OpenCode agents; deterministic Node tests validate the harness itself without calling an LLM. + +**Tech Stack:** Node.js test runner, Promptfoo, OpenCode CLI, JavaScript provider scripts, JSON package configs, TOML tier config. + +--- + +## Manual Test Scope + +No manual UI or exploratory tests are required. + +Live/model-backed smoke evals are automated OpenCode CLI scenarios, but they remain human-triggered because they make live model/API calls. Coding agents must not run them autonomously. The implementation will document the exact manual commands. + +## Files + +- Create: `tests/evals/package.json` +- Create: `tests/evals/package-lock.json` +- Create: `tests/evals/.gitignore` +- Create: `tests/evals/config/eval-tiers.toml` +- Create: `tests/evals/opencode.json` +- Create: `tests/evals/scripts/promptfoo.sh` +- Create: `tests/evals/scripts/run-promptfoo-with-guard.js` +- Create: `tests/evals/scripts/eval-tier-config.js` +- Create: `tests/evals/scripts/resolve-promptfoo-config.js` +- Create: `tests/evals/scripts/opencode-cli-provider.js` +- Create: `tests/evals/scripts/*.test.js` +- Create: `tests/evals/assertions/check-json-contract.js` +- Create: `tests/evals/assertions/check-scope-advisor-contract.js` +- Create: `tests/evals/packages/harness-smoke/promptfooconfig.json` +- Modify: `app/package.json` +- Delete: `app/agent-tests/promptfoo/*` +- Modify: `.gitignore` +- Modify: `repo-map.json` +- Modify: `TEST_MANIFEST.md` +- Modify: `AGENTS.md` + +## Tasks + +### Task 1: Add Harness Contract Tests + +- [ ] Create `tests/evals/package.json` with `node --test` scripts. +- [ ] Add failing tests for tier config validation, config materialization, repo-local artifact guard, and package contract checks. +- [ ] Run `cd tests/evals && npm test` and verify the tests fail because scripts/configs do not exist yet. + +### Task 2: Port Migration Utility Harness Scripts + +- [ ] Copy and adapt the Migration Utility scripts into `tests/evals/scripts`. +- [ ] Add `tests/evals/config/eval-tiers.toml` with light/standard/high/x_high tiers that all resolve to OpenCode agents. +- [ ] Add `tests/evals/opencode.json` with `eval_light`, `eval_standard`, `eval_high`, and `eval_x_high` agents and provider timeouts disabled. +- [ ] Keep Promptfoo state under `tests/evals/.promptfoo`, cache under `tests/evals/.cache`, temp configs under `tests/evals/.tmp`, and outputs under `tests/evals/results` or `tests/evals/output`. +- [ ] Run `cd tests/evals && npm test` and verify deterministic harness tests pass. +- [ ] Commit the harness infrastructure. + +### Task 3: Add One OpenCode Harness Smoke Eval + +- [ ] Add one minimal package-level JSON config with `metadata.eval_tier` and no package-local providers. +- [ ] Use a prompt that asks OpenCode to return a tiny JSON payload proving the provider ran. +- [ ] Keep real agent and scope-advisor scenario conversion out of this issue; VU-1135 owns eval content repair. +- [ ] Delete the old `app/agent-tests/promptfoo` directory. +- [ ] Run `cd tests/evals && npm test`. +- [ ] Commit the package migration. + +### Task 4: Wire Repo Scripts And Docs + +- [ ] Update `app/package.json` so `test:agents:smoke` and `test:scope-advisor:smoke` delegate to `tests/evals`. +- [ ] Add root eval scripts if needed for convenient direct execution. +- [ ] Update `.gitignore`, `repo-map.json`, `TEST_MANIFEST.md`, and `AGENTS.md` with the new harness path, commands, and manual live-smoke policy. +- [ ] Run `cd app && npm run test:agents:structural`. +- [ ] Run `cd tests/evals && npm test`. +- [ ] Commit script and docs wiring. + +### Task 5: Final Verification And Linear Update + +- [ ] Run deterministic verification: + - `cd tests/evals && npm test` + - `cd app && npm run test:agents:structural` + - `cd app && npm run test:unit` +- [ ] Do not run live smoke evals autonomously. +- [ ] Post Linear implementation evidence with completed automation and the manual live-smoke commands. +- [ ] Leave the worktree clean with local commits only; do not push or raise PR. + +## Self-Review + +- The plan covers the VU-1134 harness acceptance criteria and leaves real eval scenario migration/redesign to VU-1135. +- The only human-triggered step is live/model-backed OpenCode smoke execution; the scenarios themselves are automated CLI runs. +- The plan keeps deterministic harness validation separate from live eval behavior. diff --git a/docs/superpowers/specs/2026-05-01-release-docs-ci-design.md b/docs/superpowers/specs/2026-05-01-release-docs-ci-design.md new file mode 100644 index 000000000..9f60ec148 --- /dev/null +++ b/docs/superpowers/specs/2026-05-01-release-docs-ci-design.md @@ -0,0 +1,115 @@ +# Release, Help Docs, and Cheap CI Design + +## Context + +Skill Builder already runs repository-aware validation in the `raising-linear-pr` +workflow before a branch is pushed for review. GitHub CI should therefore stay +fast and cheap on ordinary PRs, while release and docs workflows should provide +targeted confidence for artifacts that cannot be fully validated locally. + +The current release workflow also has a packaging mismatch: Tauri declares +runtime resources under `agent-sources/**`, `workspace`, and `sidecar/dist`, +while the Windows release staging step still copies old `agents` and +`references` directories. That can produce a release archive that builds +successfully but lacks the files needed by the app at runtime. + +## Goals + +- Fix release packaging so Windows and macOS artifacts include the same runtime + resources the app expects. +- Add deterministic release artifact checks that fail before upload when a + staged archive is missing required files. +- Regenerate or refresh user help files where they are stale, then make docs CI + deterministic. +- Keep PR CI cheap by making GitHub enforce structural, freshness, and targeted + checks instead of duplicating the heavier local PR-raising validation. +- Preserve manual or release-only confidence checks for expensive platform work. + +## Non-Goals + +- Replace the release toolchain or move away from Tauri packaging. +- Add live LLM evals to GitHub CI. +- Make GitHub CI the source of truth for all validation. The `raising-linear-pr` + flow remains responsible for changed-area validation before PR creation. +- Redesign the docs site information architecture beyond the fixes needed for + correct help output and deterministic deployment. + +## Release Pipeline Design + +The release workflow should treat `app/src-tauri/tauri.conf.json` as the source +of truth for bundled resources. The implementation should replace stale +Windows-only staging paths with paths matching the Tauri resource contract: + +- `app/sidecar/dist/` staged as `sidecar/dist` +- `agent-sources/plugins/` staged as `agent-sources/plugins` +- `agent-sources/skills/` staged as `agent-sources/skills` +- `agent-sources/workspace/` staged as `workspace` + +The packaging steps should share a small verification script or shell block that +asserts the staged artifact contains the required executable, sidecar entry +files, SDK manifest, plugin sources, skill sources, and workspace content. This +check should run before `upload-artifact`. + +Release notes generation can continue to attempt Anthropic-generated notes when +`ANTHROPIC_API_KEY` is available, but that path must remain non-blocking. Any +API, `curl`, or response parsing failure should fall back to commit-list release +notes. + +## Help Docs Design + +The generated help surface is `docs/user-guide/**`, with the docs site built by +VitePress from `docs/.vitepress`. The repair should do two things: + +- Refresh stale user-guide pages so the published help reflects the current app. +- Add a cheap freshness check that verifies route/help URL references and + VitePress sidebar links resolve to existing guide files. + +The docs deployment workflow should become deterministic by using `npm ci` and +triggering when `docs/package-lock.json` changes. It should remain scoped to +published docs inputs: guide pages, VitePress config, and docs package files. + +## PR CI Design + +GitHub PR CI should move toward fast policy and freshness checks: + +- Keep docs-build checks only for docs-related changes. +- Keep agent structural checks path-scoped to `agent-sources/**`, `app/sidecar/**`, + and agent response fixtures. +- Keep eval harness self-tests path-scoped to `tests/evals/**`. +- Expand repo-map audit path coverage for structural areas introduced in this + branch, including `.github/**`, `scripts/**`, and `tests/evals/**` where + relevant. +- Keep test-manifest audit focused on Rust command and E2E surface changes. + +The expensive multi-platform `cargo test`, `clippy`, full frontend unit tests, +and integration tests should not be mandatory for every PR when the changed area +does not need them. They should either be path-filtered, run on `main`, run on +manual dispatch, or run in release validation. This keeps GitHub cheap while the +PR-raising flow continues to run the changed-area validation from +`repo-map.json`. + +## Testing Strategy + +The implementation should be testable without manual release publication: + +- Run the release package verification logic against a staged fixture or a dry + staging directory. +- Run docs build locally with `cd docs && npm ci && npm run build` when docs + package files or VitePress config change. +- Run any new help-link checker directly and in the policy workflow. +- Validate workflow YAML syntax locally after edits. +- Run the existing eval harness unit tests only when `tests/evals/**` changes. + +Manual release execution may still be needed before an actual public release, +but correctness of resource selection and docs freshness should be covered by +automation. + +## Open Decisions + +- Whether expensive platform jobs should be removed from PRs entirely or kept as + manual/label-triggered jobs. The recommended first step is manual or + main/release-only execution so required PR checks stay predictable. +- Whether help regeneration should be a pure checker plus refreshed markdown, or + a command that rewrites guide files from an app-owned source. The recommended + first step is refreshed markdown plus link/freshness checks, because there is + no current canonical generator to preserve. diff --git a/docs/user-guide/dashboard.md b/docs/user-guide/dashboard.md index ab861830b..5280560c7 100644 --- a/docs/user-guide/dashboard.md +++ b/docs/user-guide/dashboard.md @@ -89,8 +89,9 @@ The menu is grouped into sections: **Skill** - **Overview** — open the workspace Overview tab -- **Eval** — open the workspace Evals tab - **Refine** — open the workspace Refine tab +- **Eval** — open the workspace Evals tab +- **Optimize Description** — update the skill's displayed description - **Restore version** — restore an earlier saved version - **Export as .skill** — save the skill as a `.skill` package @@ -118,6 +119,7 @@ Uploaded skills use the same workspace shell. Their menu can include: - **Overview** - **Refine** - **Eval** +- **Optimize Description** - **Restore version** - **Export as .skill** - **Create plugin** when the skill is still in the default **Skills** plugin @@ -132,6 +134,7 @@ Marketplace skills also use the workspace shell. Their menu can include: - **Overview** - **Refine** - **Eval** +- **Optimize Description** - **Restore version** - **Delete** when the skill is in the default plugin diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md index 57bf38a8a..d1e0ba366 100644 --- a/docs/user-guide/index.md +++ b/docs/user-guide/index.md @@ -52,7 +52,7 @@ The app has three primary surfaces: |---|---| | [Dashboard](dashboard.md) | Shows the skill list and, when a skill is selected, its workspace tabs | | [Workflow](workflow/overview.md) | Runs the 4-step builder flow for Skill Builder skills | -| [Settings](settings.md) | Holds app configuration, plugins, marketplace settings, GitHub, and usage | +| [Settings](settings.md) | Holds app configuration, plugins, marketplace settings, GitHub, documents, and usage | Two important areas are embedded inside those surfaces rather than being standalone routes: diff --git a/docs/user-guide/refine.md b/docs/user-guide/refine.md index ca12c2304..378d5280d 100644 --- a/docs/user-guide/refine.md +++ b/docs/user-guide/refine.md @@ -28,7 +28,7 @@ There is no standalone Refine route with a top-bar skill picker in the current a `Shift+Enter` inserts a newline. -When the agent is running, the send button turns into a square **Cancel** button. +When the agent is running, the send button turns into a cancel icon button. --- diff --git a/docs/user-guide/settings.md b/docs/user-guide/settings.md index 40e07d3c7..7637a4fc1 100644 --- a/docs/user-guide/settings.md +++ b/docs/user-guide/settings.md @@ -72,7 +72,7 @@ The action bar provides: - **Marketplace** — browse and install plugins from configured registries (disabled until at least one enabled registry exists in **Marketplace**) - **Upload** — import a skill package from a `.skill` or `.zip` file -Below the actions, a table lists installed non-default plugins with their display name, slug, version, and source. Click the trash icon on a row to delete a plugin. +Below the actions, a table lists installed non-default plugins with their display name, slug, version, source, status, and whether upgrades are locked. Click the trash icon on a row to delete a plugin. The default **Skills** plugin is managed automatically and does not appear as a row in this table. diff --git a/docs/user-guide/workflow/overview.md b/docs/user-guide/workflow/overview.md index 953722418..cda0d84e3 100644 --- a/docs/user-guide/workflow/overview.md +++ b/docs/user-guide/workflow/overview.md @@ -66,7 +66,7 @@ Use this when you want to re-run a step from scratch. 1. Click a completed step in the sidebar (in update mode) **or** click **Re-run** at the bottom of the clarifications editor. 2. The **Reset to Earlier Step** dialog appears. It lists every file that will be deleted from that step onward. -3. Click **Delete N file(s) & Reset** to confirm. All steps from that point forward reset to Pending. +3. Click **Delete N files & Reset** to confirm. All steps from that point forward reset to Pending. > Resetting Step 2 (Detailed Research) also resets Step 1 (Research) because they share the same clarifications file. @@ -102,5 +102,5 @@ The toggle is disabled while an agent is running or a gate evaluation is in prog ## Navigation guard If you try to leave the workflow while an agent is running, a dialog appears: -*"An agent is still running. Leaving will stop the agent and you may lose progress."* +*"An agent is still running. Leaving will abandon it and you may lose progress."* Click **Stay** to remain, or **Leave** to exit. diff --git a/docs/user-guide/workflow/step-1-research.md b/docs/user-guide/workflow/step-1-research.md index 096c1c154..a39416200 100644 --- a/docs/user-guide/workflow/step-1-research.md +++ b/docs/user-guide/workflow/step-1-research.md @@ -43,37 +43,25 @@ Some questions have nested **Refinements** — follow-up sub-questions inside th 1. Answer all questions marked **must**. 2. Click **Continue** at the bottom right. The button shows **Evaluating answers...** while the gate check runs. -3. A transition gate dialog appears — see [Gate 1](#gate-1-transition-dialog) below. +3. The screen shows **Analyzing Responses** while the app evaluates answer quality. +4. If the answers are strong enough, the workflow advances. If anything needs attention, the editor stays open with review feedback and the app shows a toast. --- -## Gate 1 transition dialog +## Answer review -After you click Continue, the app evaluates your answers and shows one of these dialogs: +After you click Continue, the app evaluates answer completeness, specificity, and consistency. -**"Skip Detailed Research?"** — your answers are thorough +Possible outcomes: -- **Run Research Anyway** — proceeds to Step 2 (Detailed Research) -- **Skip to Decisions** — skips Step 2 and jumps directly to Step 3 +- Step 2 runs when more detailed research is useful. +- Step 2 is skipped when the Step 1 answers are already strong enough for decisions. +- The editor remains open when required answers are missing, vague, or contradictory. -**"Some Answers Need Deeper Research"** — a few answers need more detail - -- **Let Me Revise** — returns to the editor so you can improve your answers -- **Continue to Research** — proceeds to Step 2 anyway - -**"Review Answer Quality"** — some answers are missing or too vague - -- **Let Me Answer** — returns to the editor -- **Continue Anyway** — proceeds to Step 2 despite incomplete answers - -**"Contradictory Answers"** — some answers conflict with each other - -- **Let Me Answer** — returns to the editor (the only option; you must resolve the contradiction before continuing) - -Each dialog shows a per-question breakdown: OK, Missing, Vague, Needs refinement, and Contradictory counts. +Use the highlighted feedback to revise answers before continuing again. --- ## Re-run Step 1 -Click **Re-run** at the bottom left of the editor. This opens the Reset Step dialog, which shows which files will be deleted. Click **Delete & Reset** to confirm. The agent re-runs from the beginning. +Click **Re-run** at the bottom left of the editor. This opens the Reset Step dialog, which shows which files will be deleted. Click **Delete N files & Reset** to confirm. The agent re-runs from the beginning. diff --git a/docs/user-guide/workflow/step-2-detailed-research.md b/docs/user-guide/workflow/step-2-detailed-research.md index 0e267cde1..419573b6d 100644 --- a/docs/user-guide/workflow/step-2-detailed-research.md +++ b/docs/user-guide/workflow/step-2-detailed-research.md @@ -16,35 +16,23 @@ The toolbar shows answer progress, review state, and the continue action. ## Answer and continue -Same pattern as Step 1 — expand a card, select a choice or type freely, answer any nested **Refinements** inside the card. Answer all **must** questions, then click **Continue**. The button shows **Evaluating answers...** while the gate check runs. +Same pattern as Step 1 — expand a card, select a choice or type freely, answer any nested **Refinements** inside the card. Answer all **must** questions, then click **Continue**. The button shows **Evaluating answers...** while the gate check runs, and the screen shows **Analyzing Responses** while answers are reviewed. --- -## Gate 2 transition dialog +## Answer review -**"Refinement Answers Complete"** — all answers look good +After you click Continue, the app evaluates answer completeness, specificity, and consistency. -- **Back to Review** — returns to the editor -- **Continue to Decisions** — advances to Step 3 +Possible outcomes: -**"Some Refinements Unanswered"** — one or more questions were left blank +- The workflow advances to Step 3 when answers are good enough. +- The editor remains open when required answers are missing, vague, or contradictory. -- **Let Me Answer** — returns to the editor -- **Continue Anyway** — advances to Step 3 with incomplete answers - -**"Refinements Need Attention"** — answers are present but insufficient - -- **Let Me Answer** — returns to the editor -- **Continue Anyway** — advances to Step 3 - -**"Contradictory Answers"** — answers conflict with each other - -- **Let Me Answer** — returns to the editor (the only option; resolve the contradiction first) - -The dialog shows a per-question breakdown so you can identify exactly what needs revision. +Use the inline feedback and toast message to revise answers before continuing again. --- ## Re-run Step 2 -Click **Re-run** at the bottom left. The Reset Step dialog warns that resetting Step 2 also resets Step 1, because both steps share the same clarifications file. Click **Delete & Reset** to confirm. +Click **Re-run** at the bottom left. The Reset Step dialog warns that resetting Step 2 also resets Step 1, because both steps share the same clarifications file. Click **Delete N files & Reset** to confirm. diff --git a/docs/user-guide/workflow/step-3-confirm-decisions.md b/docs/user-guide/workflow/step-3-confirm-decisions.md index 04f237ab7..264736521 100644 --- a/docs/user-guide/workflow/step-3-confirm-decisions.md +++ b/docs/user-guide/workflow/step-3-confirm-decisions.md @@ -46,4 +46,4 @@ When a decision needs review, the card is editable in update mode and changes au Click **Next Step** at the bottom right. You can continue regardless of decision status. -> To change your original answers instead of editing decisions here, go back to an earlier step via the sidebar. See [How to reset a step](overview.md#how-to-reset-a-step). +> To change your original answers instead of editing decisions here, go back to an earlier step via the sidebar. See [Reset a step](overview.md#reset-a-step). diff --git a/docs/user-guide/workflow/step-4-generate-skill.md b/docs/user-guide/workflow/step-4-generate-skill.md index 6c858d900..2b85cc0ae 100644 --- a/docs/user-guide/workflow/step-4-generate-skill.md +++ b/docs/user-guide/workflow/step-4-generate-skill.md @@ -18,7 +18,7 @@ You get a file viewer that renders the generated markdown. 1. Review `SKILL.md` — this is the main skill file. It contains the instructions Claude will follow. 2. If a dropdown is shown, open each reference file to review supplementary content. -3. If something looks wrong, go back to an earlier step and correct your answers. See [How to reset a step](overview.md#how-to-reset-a-step). +3. If something looks wrong, go back to an earlier step and correct your answers. See [Reset a step](overview.md#reset-a-step). --- diff --git a/repo-map.json b/repo-map.json index 84554101d..89ec7998b 100644 --- a/repo-map.json +++ b/repo-map.json @@ -14,6 +14,11 @@ "lockfile": "app/sidecar/package-lock.json", "manifest": "app/sidecar/package.json" }, + { + "name": "npm (evals)", + "lockfile": "tests/evals/package-lock.json", + "manifest": "tests/evals/package.json" + }, { "name": "cargo", "lockfile": "app/src-tauri/Cargo.lock", @@ -27,7 +32,7 @@ "notes": "Bundles frontend (Vite), Rust backend, sidecar dist, and agent-sources as app resources. Identifier: com.vibedata.skill-builder. CSP allows Anthropic API + GitHub API. Dev port: DEV_PORT (default 1420), HMR on DEV_PORT+1." }, { - "name": "Vite 7", + "name": "Vite 8", "config_files": ["app/vite.config.ts", "app/tsconfig.json"], "notes": "React + Tailwind plugin. Path alias `@/` → `./src/`. E2E mock path alias via TAURI_E2E env var." }, @@ -47,7 +52,7 @@ ".github/workflows/sync-skill-creator.yml", ".github/workflows/sync-vd-agent.yml" ], - "notes": "pr-ci.yml: platform CI (Linux/Windows/macOS) + frontend unit/integration. pr-policy.yml: docs build, agents-structural, instruction-docs-lint, repo-map-audit, test-manifest-audit. security.yml: dependency-review, CodeQL, cargo-audit. docs.yml: VitePress GitHub Pages deploy. release.yml: multi-platform Tauri build + publish." + "notes": "pr-ci.yml: heavy platform CI (Linux/Windows/macOS) + frontend unit/integration on main push or manual dispatch. pr-policy.yml: cheap PR checks for docs build/help links, script tests, agents-structural, eval-harness, instruction-docs-lint, repo-map-audit, test-manifest-audit. security.yml: dependency-review, CodeQL, cargo-audit. docs.yml: deterministic VitePress GitHub Pages deploy. release.yml: multi-platform Tauri build, release-stage verification, and publish." } ], "test_frameworks": [ @@ -63,7 +68,7 @@ }, { "name": "Promptfoo", - "scope": "Agent smoke tests (live API calls — manual only, do not run autonomously)" + "scope": "Agent smoke tests via the root tests/evals OpenCode harness (live model calls — manual unless explicitly requested)" }, { "name": "cargo test", @@ -74,7 +79,7 @@ { "name": "Skill Builder Desktop", "type": "Tauri v2 desktop app", - "description": "Multi-agent workflow for creating domain-specific Claude skills. React frontend + Rust backend + Node.js agent sidecar.", + "description": "Desktop workflow for creating domain-specific Claude Code-compatible skills. React frontend + Rust backend + Node.js agent sidecar.", "identifier": "com.vibedata.skill-builder" } ], @@ -135,8 +140,8 @@ "description": "Mock mode: replays bundled templates with no API calls. Activated via MOCK_AGENTS=true." }, "agent_prompts": { - "path": "agent-sources/agents/", - "description": "Flat directory of .md agent prompts: answer-evaluator. Plugin-hosted agents: generate-skill and rewrite-skill under agent-sources/plugins/skill-creator/agents/; skill-builder, research-orchestrator, detailed-research, and confirm-decisions under agent-sources/plugins/skill-content-researcher/agents/. Plugin-hosted skills: skill-evaluator and skill-validator under agent-sources/plugins/skill-creator/skills/" + "path": "agent-sources/plugins/*/agents/", + "description": "Plugin-hosted agent prompts: generate-skill and rewrite-skill under agent-sources/plugins/skill-creator/agents/; skill-builder, research-orchestrator, detailed-research, confirm-decisions, and answer-evaluator under agent-sources/plugins/skill-content-researcher/agents/. Plugin-hosted skills include skill-evaluator and skill-validator under agent-sources/plugins/skill-creator/skills/" }, "agent_plugins": { "path": "agent-sources/plugins/", @@ -172,15 +177,15 @@ "app/sidecar/": "Node.js/TypeScript agent sidecar (JSONL protocol, SDK invocation, mock mode)", "app/sidecar/__tests__/": "Sidecar unit tests (one test file per sidecar module)", "app/e2e/": "Playwright E2E tests. Sub-directories: dashboard, workflow, refine, evals, settings, usage, skill-tester, skills-library, integration, desktop-smoke, fixtures, helpers, setup", - "agent-sources/agents/": "Agent prompt .md files — flat directory, structurally validated by test:agents:structural", + "tests/evals/": "Root Promptfoo/OpenCode eval harness. Contains suite-owned tier config, OpenCode provider config, package-level eval configs, deterministic harness tests, repo-local Promptfoo state ignores, and live model smoke commands.", "agent-sources/workspace/": "Workspace agent instructions: CLAUDE.md (full), CLAUDE-MINIMAL.md (lightweight), prompts/ (shared fragments). Deployed to workspace .claude/ at app startup.", "agent-sources/plugins/": "Plugin definitions: skill-content-researcher, skill-creator, vd-agent", "docs/design/": "Architecture decision records and design specs: agent-specs, backend-design, startup-recon, workflow-state, clarifications-rendering, skill-tester, skills-marketplace, and more. Primary reference for non-obvious design decisions.", "docs/user-guide/": "VitePress user documentation, deployed via docs.yml to GitHub Pages", "docs/references/": "Vendored external reference docs (e.g. Anthropic API snapshots)", ".claude/rules/": "Shared agent rules (agent-agnostic, detailed policy). Referenced from AGENTS.md.", - ".claude/skills/": "Workflow playbooks for Claude Code CLI skills", - "scripts/": "Developer and automation scripts" + ".claude/repo-map.schema.json": "Schema for repo-map.json", + "scripts/": "Developer and automation scripts. worktree.sh is the canonical maintainer helper for creating development worktrees; it bootstraps app/eval dependencies and symlinks worktree Promptfoo state back to the source checkout. check-help-docs.mjs verifies app/VitePress help links against docs/user-guide. verify-release-stage.mjs verifies staged release archives include required runtime resources." }, "dependencies_internal": { "frontend → rust": "Via Tauri IPC (`invoke()` from @tauri-apps/api/core)", @@ -198,7 +203,7 @@ "db": "rusqlite (bundled SQLite)" }, "dev": { - "vite": "Vite 7 + @vitejs/plugin-react", + "vite": "Vite 8 + @vitejs/plugin-react", "vitest": "Vitest (unit + structural agent tests)", "playwright": "Playwright (E2E)", "promptfoo": "Promptfoo (agent smoke tests, manual only)", @@ -215,7 +220,13 @@ "test_unit": "cd app && npm run test:unit", "test_changed": "cd app && npm run test:changed", "test_agents_structural": "cd app && npm run test:agents:structural", - "test_agents_smoke": "cd app && npm run test:agents:smoke # MANUAL ONLY — makes live API calls", + "test_agents_smoke": "cd app && npm run test:agents:smoke # live OpenCode/Promptfoo model call", + "test_eval_harness": "cd tests/evals && npm test", + "test_eval_harness_smoke": "cd tests/evals && npm run eval:harness-smoke # live OpenCode/Promptfoo model call", + "test_release_docs_ci_scripts": "node --test scripts/*.test.mjs", + "check_help_docs": "node scripts/check-help-docs.mjs", + "verify_release_stage": "node scripts/verify-release-stage.mjs ", + "create_worktree": "./scripts/worktree.sh feature/", "test_sidecar": "cd app/sidecar && npx vitest run", "test_e2e": "cd app && npm run test:e2e", "test_all": "cd app && bash tests/run.sh", @@ -236,7 +247,7 @@ "commits": "Granular — one concern per commit. Stage specific files (`git add `, not `git add .`).", "pr_title": "VU-XXX: short description", "pr_body": "Fixes VU-XXX", - "worktrees": "../worktrees/ relative to repo root", + "worktrees": "Use ./scripts/worktree.sh ; worktrees live at ../worktrees/ relative to repo root and share Promptfoo DB/state through a tests/evals/.promptfoo symlink to the source checkout", "linear_project": "All issues for this repo go under Skill Builder", "file_size_and_responsibility": "Keep files focused on one concern. Split when a file exceeds ~300 lines (frontend TS/TSX) or ~400 lines (Rust command file). Rust: extract sub-module directories when a command group combines API surface, orchestration, persistence, and filesystem ops. Frontend: extract sub-components, custom hooks, or lib utilities rather than growing a component or page inline.", "no_monoliths": "A Tauri command file should define commands and delegate to helpers — not own query logic, filesystem ops, and business rules simultaneously. A React component should render — not own a state machine, data fetching, and complex transformations inline. When in doubt, split." @@ -247,16 +258,16 @@ "startup_recon_design": "docs/design/startup-recon/ — reconciliation scenario matrix (scenarios 1–12), used by reconciliation/", "coding_conventions": ".claude/rules/coding-conventions.md — naming, error handling", "frontend_rules": ".claude/rules/frontend-design.md — AD brand, component constraints, state indicators", - "rust_rules": ".claude/rules/rust-backend.md — command conventions, error types, Rust testing", - "sidecar_rules": ".claude/rules/agent-sidecar.md — JSONL protocol, sidecar constraints", - "db_change_protocol": ".claude/rules/db-schema-change.md — mandatory protocol for any schema, migration, or persistence change", + "codegen_rules": ".claude/rules/codegen.md — generated contract freshness requirements", + "path_conventions": ".claude/rules/path-conventions.md — skill builder path vs workspace path rules", + "state_management": ".claude/rules/state-management.md — frontend local-state vs Zustand boundaries", "windows_compat": ".claude/rules/windows-compat.md — path separators, CRLF, env-var syntax, Rust toolchain. Read before writing path assertions, regex, package.json scripts, or CI config.", "logging_policy": ".claude/rules/logging-policy.md — log levels, sensitive data redaction, structured logging, correlation IDs", "test_manifest": "TEST_MANIFEST.md — Rust command → E2E tag mappings, shared infra blast radius, cross-boundary format compliance. Read before choosing tests for Rust or cross-layer changes." }, "notes_for_agents": { "startup": "Read this file before exploring code. It is the primary startup context for structure, entrypoints, modules, and commands. Skip repo-wide rediscovery if it covers your task.", - "test_autonomy": "Only `test:agents:structural` may be run autonomously — no API calls. Never run `test:agents:smoke` autonomously.", + "test_autonomy": "`cd tests/evals && npm test` and `test:agents:structural` are deterministic. `test:agents:smoke` and `tests/evals` eval scripts make live model calls; run them only when explicitly requested.", "db_location": "Database is at Tauri app_data_dir()/skill-builder.db. macOS: ~/Library/Application Support/com.vibedata.skill-builder/skill-builder.db", "migrations": "DB migrations are code-only in db/migrations.rs NUMBERED_MIGRATIONS constant — no separate migration files directory.", "workspace_path": "Workspace: /workspace (not user-configurable). Resolved from Tauri app_local_data_dir() by resolve_workspace_path() in commands/workspace.rs. Legacy ~/.vibedata/ path is cleaned up automatically on startup.", diff --git a/scripts/check-help-docs.mjs b/scripts/check-help-docs.mjs new file mode 100644 index 000000000..5c3b484bb --- /dev/null +++ b/scripts/check-help-docs.mjs @@ -0,0 +1,83 @@ +#!/usr/bin/env node +import { existsSync, readFileSync } from "node:fs"; +import { relative, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const BASE_URL = "https://hbanerjee74.github.io/skill-builder"; + +export function helpLinkToMarkdownPath(docsRoot, link) { + const normalized = normalizeHelpLink(link); + if (normalized === "/") { + return resolve(docsRoot, "index.md"); + } + + return resolve(docsRoot, `${normalized.replace(/^\/+/, "")}.md`); +} + +export function findMissingHelpDocs(repoRoot = process.cwd()) { + const docsRoot = resolve(repoRoot, "docs/user-guide"); + const sources = [ + "app/src/lib/help-urls.ts", + "docs/.vitepress/config.ts", + ]; + const missing = new Set(); + + for (const source of sources) { + const sourcePath = resolve(repoRoot, source); + if (!existsSync(sourcePath)) { + continue; + } + + const links = collectLinksFromText(readFileSync(sourcePath, "utf8")); + for (const link of links) { + const markdownPath = helpLinkToMarkdownPath(docsRoot, link); + if (!existsSync(markdownPath)) { + missing.add(`${normalizeHelpLink(link)} -> ${relative(repoRoot, markdownPath)}`); + } + } + } + + return [...missing].sort(); +} + +function normalizeHelpLink(link) { + const withoutBase = link.startsWith(BASE_URL) ? link.slice(BASE_URL.length) : link; + const withoutHash = withoutBase.replace(/#.*$/, ""); + const withoutQuery = withoutHash.replace(/\?.*$/, ""); + return withoutQuery || "/"; +} + +function collectLinksFromText(text) { + const links = new Set(); + const patterns = [ + /https:\/\/hbanerjee74\.github\.io\/skill-builder(\/[^`"'\s)]*)?/g, + /\$\{BASE\}(\/[^`"'\s)]*)/g, + /link:\s*["'](\/[^"']*)["']/g, + ]; + + for (const pattern of patterns) { + for (const match of text.matchAll(pattern)) { + const link = match[1] ?? match[0]; + links.add(link.replace(/[`"',)]*$/, "") || "/"); + } + } + + return [...links]; +} + +function main() { + const missing = findMissingHelpDocs(process.cwd()); + if (missing.length > 0) { + console.error("Missing help documentation targets:"); + for (const target of missing) { + console.error(`- ${target}`); + } + process.exit(1); + } + + console.log("Help documentation links verified."); +} + +if (process.argv[1] === fileURLToPath(import.meta.url)) { + main(); +} diff --git a/scripts/check-help-docs.test.mjs b/scripts/check-help-docs.test.mjs new file mode 100644 index 000000000..7bb9926a0 --- /dev/null +++ b/scripts/check-help-docs.test.mjs @@ -0,0 +1,48 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs"; +import { join, resolve } from "node:path"; +import { tmpdir } from "node:os"; +import { helpLinkToMarkdownPath, findMissingHelpDocs } from "./check-help-docs.mjs"; + +test("helpLinkToMarkdownPath resolves root and nested guide links", () => { + const root = resolve("/repo/docs/user-guide"); + + assert.equal(helpLinkToMarkdownPath(root, "/"), resolve("/repo/docs/user-guide/index.md")); + assert.equal( + helpLinkToMarkdownPath(root, "/workflow/step-1-research"), + resolve("/repo/docs/user-guide/workflow/step-1-research.md"), + ); + assert.equal( + helpLinkToMarkdownPath( + root, + "https://hbanerjee74.github.io/skill-builder/workflow/step-1-research#details", + ), + resolve("/repo/docs/user-guide/workflow/step-1-research.md"), + ); +}); + +test("findMissingHelpDocs reports missing sidebar and app help links", () => { + const root = mkdtempSync(join(tmpdir(), "skill-builder-help-")); + try { + mkdirSync(join(root, "docs/user-guide/workflow"), { recursive: true }); + mkdirSync(join(root, "docs/.vitepress"), { recursive: true }); + mkdirSync(join(root, "app/src/lib"), { recursive: true }); + writeFileSync(join(root, "docs/user-guide/index.md"), "# Home\n"); + writeFileSync( + join(root, "app/src/lib/help-urls.ts"), + 'const BASE = "https://hbanerjee74.github.io/skill-builder";\nexport const x = `${BASE}/workflow/missing`;\n', + ); + writeFileSync( + join(root, "docs/.vitepress/config.ts"), + "export default { themeConfig: { sidebar: [{ items: [{ text: 'Missing', link: '/missing' }] }] } };\n", + ); + + const missing = findMissingHelpDocs(root); + + assert.ok(missing.includes("/workflow/missing -> docs/user-guide/workflow/missing.md")); + assert.ok(missing.includes("/missing -> docs/user-guide/missing.md")); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); diff --git a/scripts/verify-release-stage.mjs b/scripts/verify-release-stage.mjs new file mode 100644 index 000000000..dd9300d9e --- /dev/null +++ b/scripts/verify-release-stage.mjs @@ -0,0 +1,65 @@ +#!/usr/bin/env node +import { existsSync } from "node:fs"; +import { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const REQUIRED_BY_PLATFORM = { + windows: [ + "skill-builder.exe", + "sidecar/dist/package.json", + "sidecar/dist/bootstrap.js", + "sidecar/dist/agent-runner.js", + "sidecar/dist/sdk/claude.exe", + "agent-sources/plugins/skill-creator/LICENSE.txt", + "agent-sources/skills/skill-test/SKILL.md", + "workspace/CLAUDE.md", + "workspace/prompts/workflow-step.txt", + ], + macos: [ + "Skill Builder.app", + "run.sh", + "Skill Builder.app/Contents/Resources/sidecar/dist/package.json", + "Skill Builder.app/Contents/Resources/sidecar/dist/bootstrap.js", + "Skill Builder.app/Contents/Resources/sidecar/dist/agent-runner.js", + "Skill Builder.app/Contents/Resources/sidecar/dist/sdk/claude", + "Skill Builder.app/Contents/Resources/agent-sources/plugins/skill-creator/LICENSE.txt", + "Skill Builder.app/Contents/Resources/agent-sources/skills/skill-test/SKILL.md", + "Skill Builder.app/Contents/Resources/workspace/CLAUDE.md", + "Skill Builder.app/Contents/Resources/workspace/prompts/workflow-step.txt", + ], +}; + +export function verifyReleaseStage(stageDir, platform) { + const requiredPaths = REQUIRED_BY_PLATFORM[platform]; + if (!requiredPaths) { + throw new Error(`Unknown release platform: ${platform}`); + } + + return requiredPaths.filter((relativePath) => { + return !existsSync(resolve(stageDir, relativePath)); + }); +} + +function main() { + const [stageDir, platform] = process.argv.slice(2); + + if (!stageDir || !platform) { + console.error("Usage: node scripts/verify-release-stage.mjs "); + process.exit(2); + } + + const missingPaths = verifyReleaseStage(stageDir, platform); + if (missingPaths.length > 0) { + console.error(`Release stage is missing ${missingPaths.length} required path(s):`); + for (const relativePath of missingPaths) { + console.error(`- ${relativePath}`); + } + process.exit(1); + } + + console.log(`Release stage verified for ${platform}: ${stageDir}`); +} + +if (process.argv[1] === fileURLToPath(import.meta.url)) { + main(); +} diff --git a/scripts/verify-release-stage.test.mjs b/scripts/verify-release-stage.test.mjs new file mode 100644 index 000000000..24639c0f3 --- /dev/null +++ b/scripts/verify-release-stage.test.mjs @@ -0,0 +1,139 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { + mkdtempSync, + mkdirSync, + writeFileSync, + rmSync, +} from "node:fs"; +import { tmpdir } from "node:os"; +import { dirname, join } from "node:path"; +import { spawnSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; +import { verifyReleaseStage } from "./verify-release-stage.mjs"; + +const WINDOWS_REQUIRED_PATHS = [ + "skill-builder.exe", + "sidecar/dist/package.json", + "sidecar/dist/bootstrap.js", + "sidecar/dist/agent-runner.js", + "sidecar/dist/sdk/claude.exe", + "agent-sources/plugins/skill-creator/LICENSE.txt", + "agent-sources/skills/skill-test/SKILL.md", + "workspace/CLAUDE.md", + "workspace/prompts/workflow-step.txt", +]; + +const MACOS_REQUIRED_PATHS = [ + "Skill Builder.app", + "run.sh", + "Skill Builder.app/Contents/Resources/sidecar/dist/package.json", + "Skill Builder.app/Contents/Resources/sidecar/dist/bootstrap.js", + "Skill Builder.app/Contents/Resources/sidecar/dist/agent-runner.js", + "Skill Builder.app/Contents/Resources/sidecar/dist/sdk/claude", + "Skill Builder.app/Contents/Resources/agent-sources/plugins/skill-creator/LICENSE.txt", + "Skill Builder.app/Contents/Resources/agent-sources/skills/skill-test/SKILL.md", + "Skill Builder.app/Contents/Resources/workspace/CLAUDE.md", + "Skill Builder.app/Contents/Resources/workspace/prompts/workflow-step.txt", +]; + +const scriptPath = fileURLToPath(new URL("./verify-release-stage.mjs", import.meta.url)); + +function makeStage(requiredPaths) { + const root = mkdtempSync(join(tmpdir(), "skill-builder-release-")); + + for (const relativePath of requiredPaths) { + const path = join(root, relativePath); + if (relativePath.endsWith(".app")) { + mkdirSync(path, { recursive: true }); + continue; + } + mkdirSync(dirname(path), { recursive: true }); + writeFileSync(path, "fixture\n"); + } + + return root; +} + +test("verifyReleaseStage accepts a complete Windows stage", () => { + const root = makeStage(WINDOWS_REQUIRED_PATHS); + + try { + assert.deepEqual(verifyReleaseStage(root, "windows"), []); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); + +test("verifyReleaseStage reports every missing Windows required path", () => { + const root = mkdtempSync(join(tmpdir(), "skill-builder-release-missing-")); + + try { + assert.deepEqual(verifyReleaseStage(root, "windows"), WINDOWS_REQUIRED_PATHS); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); + +test("verifyReleaseStage accepts a complete macOS stage", () => { + const root = makeStage(MACOS_REQUIRED_PATHS); + + try { + assert.deepEqual(verifyReleaseStage(root, "macos"), []); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); + +test("verifyReleaseStage throws for an unknown platform", () => { + assert.throws( + () => verifyReleaseStage("/tmp/release-stage", "linux"), + /Unknown release platform: linux/, + ); +}); + +test("CLI prints missing paths and exits 1 when the stage is incomplete", () => { + const root = mkdtempSync(join(tmpdir(), "skill-builder-release-cli-missing-")); + + try { + const result = spawnSync(process.execPath, [scriptPath, root, "macos"], { + encoding: "utf8", + }); + + assert.equal(result.status, 1); + assert.match(result.stderr, /Release stage is missing 10 required path\(s\):/); + assert.match(result.stderr, /- Skill Builder\.app/); + assert.match(result.stderr, /- run\.sh/); + assert.match(result.stderr, /- Skill Builder\.app\/Contents\/Resources\/sidecar\/dist\/sdk\/claude/); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); + +test("CLI exits 2 for bad usage", () => { + const result = spawnSync(process.execPath, [scriptPath], { + encoding: "utf8", + }); + + assert.equal(result.status, 2); + assert.match( + result.stderr, + /Usage: node scripts\/verify-release-stage\.mjs /, + ); +}); + +test("CLI prints success and exits 0 when the stage is complete", () => { + const root = makeStage(MACOS_REQUIRED_PATHS); + + try { + const result = spawnSync(process.execPath, [scriptPath, root, "macos"], { + encoding: "utf8", + }); + + assert.equal(result.status, 0); + assert.match(result.stdout, /Release stage verified for macos:/); + assert.match(result.stdout, new RegExp(root.replaceAll("\\", "\\\\"))); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); diff --git a/scripts/worktree.sh b/scripts/worktree.sh new file mode 100755 index 000000000..b6bf171e3 --- /dev/null +++ b/scripts/worktree.sh @@ -0,0 +1,250 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Maintainer helper for this repository only. +# Use this from the Skill Builder repo root to create contributor development +# worktrees. It keeps Promptfoo state in the source checkout by symlinking +# tests/evals/.promptfoo from each worktree back to this repo root. + +if [[ $# -ne 1 ]]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +branch="$1" + +script_dir="$(cd "$(dirname "$0")" && pwd)" +repo_root="$(cd "$script_dir/.." && pwd)" +worktree_base="${WORKTREE_BASE_DIR:-$repo_root/../worktrees}" +worktree_path="$worktree_base/$branch" + +retry_command() { + printf '%s %s' "$0" "$branch" +} + +json_error() { + local code="$1" + local step="$2" + local message="$3" + local can_retry="$4" + local retry_command="$5" + local suggested_fix="$6" + local existing_worktree_path="${7:-}" + BRANCH="$branch" \ + REQUESTED_WORKTREE_PATH="$worktree_path" \ + CODE="$code" \ + STEP="$step" \ + MESSAGE="$message" \ + CAN_RETRY="$can_retry" \ + RETRY_COMMAND="$retry_command" \ + SUGGESTED_FIX="$suggested_fix" \ + EXISTING_WORKTREE_PATH="$existing_worktree_path" \ + python3 - <<'PY' >&2 +import json +import os + +payload = { + "code": os.environ["CODE"], + "step": os.environ["STEP"], + "message": os.environ["MESSAGE"], + "branch": os.environ["BRANCH"], + "requested_worktree_path": os.environ["REQUESTED_WORKTREE_PATH"], + "can_retry": os.environ["CAN_RETRY"].lower() == "true", + "retry_command": os.environ["RETRY_COMMAND"], + "suggested_fix": os.environ["SUGGESTED_FIX"], +} +existing = os.environ.get("EXISTING_WORKTREE_PATH") +if existing: + payload["existing_worktree_path"] = existing +print(json.dumps(payload)) +PY + exit 1 +} + +run_in_dir() { + local dir="$1" + shift + ( + cd "$dir" && + "$@" + ) +} + +link_env_file() { + local env_src="$repo_root/.env" + local env_dst="$worktree_path/.env" + + if [[ ! -f "$env_src" ]]; then + echo "ENV: skipped (no .env in $repo_root)" + return + fi + + rm -f "$env_dst" + ln -s "$env_src" "$env_dst" + echo "ENV: symlink $env_dst -> $env_src" +} + +link_promptfoo_state() { + local promptfoo_src="$repo_root/tests/evals/.promptfoo" + local promptfoo_dst="$worktree_path/tests/evals/.promptfoo" + + if [[ ! -d "$worktree_path/tests/evals" ]]; then + echo "PROMPTFOO_DB: skipped (no tests/evals in worktree)" + return + fi + + mkdir -p "$promptfoo_src" + rm -rf "$promptfoo_dst" + ln -s "$promptfoo_src" "$promptfoo_dst" + echo "PROMPTFOO_DB: symlink $promptfoo_dst -> $promptfoo_src" +} + +bootstrap_app_dependencies() { + local app_dir="$worktree_path/app" + local npm_command=( + install + --no-audit + --no-fund + ) + local npm_command_str="npm install --no-audit --no-fund" + + if [[ ! -f "$app_dir/package.json" ]]; then + echo "npm: skipped app dependencies (no package.json in app)" + return + fi + + if [[ -f "$app_dir/package-lock.json" ]]; then + npm_command=( + ci + --no-audit + --no-fund + ) + npm_command_str="npm ci --no-audit --no-fund" + fi + + echo "npm: ensuring app dependencies in $app_dir with $npm_command_str" + run_in_dir "$app_dir" npm "${npm_command[@]}" || json_error \ + "WORKTREE_APP_NPM_INSTALL_FAILED" \ + "app_npm_install" \ + "npm dependency bootstrap failed for app dependencies." \ + "true" \ + "$(retry_command)" \ + "Run 'cd $app_dir && $npm_command_str' to repair app dependencies, then rerun the worktree command." +} + +bootstrap_eval_dependencies() { + local evals_dir="$worktree_path/tests/evals" + local npm_command=( + install + --no-audit + --no-fund + ) + local npm_command_str="npm install --no-audit --no-fund" + + if [[ ! -f "$evals_dir/package.json" ]]; then + echo "npm: skipped eval dependencies (no package.json in tests/evals)" + return + fi + + if [[ -f "$evals_dir/package-lock.json" ]]; then + npm_command=( + ci + --no-audit + --no-fund + ) + npm_command_str="npm ci --no-audit --no-fund" + fi + + echo "npm: ensuring eval dependencies in $evals_dir with $npm_command_str" + run_in_dir "$evals_dir" npm "${npm_command[@]}" || json_error \ + "WORKTREE_EVAL_NPM_INSTALL_FAILED" \ + "eval_npm_install" \ + "npm dependency bootstrap failed for eval dependencies." \ + "true" \ + "$(retry_command)" \ + "Run 'cd $evals_dir && $npm_command_str' to repair eval dependencies, then rerun the worktree command." +} + +existing_branch_worktree() { + local target_branch="$1" + local current_path="" + local current_branch="" + while IFS= read -r line || [[ -n "$line" ]]; do + if [[ -z "$line" ]]; then + if [[ "$current_branch" == "refs/heads/$target_branch" ]]; then + printf '%s\n' "$current_path" + return 0 + fi + current_path="" + current_branch="" + continue + fi + case "$line" in + worktree\ *) current_path="${line#worktree }" ;; + branch\ *) current_branch="${line#branch }" ;; + esac + done < <(git worktree list --porcelain) + + if [[ "$current_branch" == "refs/heads/$target_branch" ]]; then + printf '%s\n' "$current_path" + fi +} + +bootstrap_worktree() { + link_env_file + link_promptfoo_state + bootstrap_app_dependencies + bootstrap_eval_dependencies +} + +ensure_worktree_base() { + mkdir -p "$(dirname "$worktree_path")" +} + +branch_exists() { + git show-ref --verify --quiet "refs/heads/$branch" +} + +handle_existing_worktree() { + local checked_out_path="$1" + + if [[ -n "$checked_out_path" && "$checked_out_path" != "$worktree_path" ]]; then + json_error \ + "WORKTREE_BRANCH_ALREADY_CHECKED_OUT" \ + "branch_conflict" \ + "Branch is already checked out in another worktree." \ + "false" \ + "" \ + "Use the existing worktree or remove it before requesting a new worktree for this branch." \ + "$checked_out_path" + fi + + if [[ -n "$checked_out_path" ]]; then + echo "worktree: branch already attached at $worktree_path; rerunning bootstrap" + bootstrap_worktree + echo "worktree: ready $worktree_path" + exit 0 + fi +} + +main() { + local checked_out_path="" + local branch_present=false + + ensure_worktree_base + if branch_exists; then + branch_present=true + fi + checked_out_path="$(existing_branch_worktree "$branch")" + handle_existing_worktree "$checked_out_path" + if $branch_present; then + git worktree add "$worktree_path" "$branch" + else + git worktree add -b "$branch" "$worktree_path" HEAD + fi + echo "worktree: created worktree at $worktree_path" + bootstrap_worktree + echo "worktree: ready $worktree_path" +} + +main "$@" diff --git a/tests/evals/.gitignore b/tests/evals/.gitignore new file mode 100644 index 000000000..8a5363d04 --- /dev/null +++ b/tests/evals/.gitignore @@ -0,0 +1,9 @@ +node_modules/ +.cache/ +.tmp/ +output/ +results/ +.promptfoo/ +fixtures/**/.staging/ +fixtures/migration-test/test-review-results/ +fixtures/migration-test/model-review-results/ diff --git a/tests/evals/config/eval-tiers.toml b/tests/evals/config/eval-tiers.toml new file mode 100644 index 000000000..4033c3d4f --- /dev/null +++ b/tests/evals/config/eval-tiers.toml @@ -0,0 +1,20 @@ +[runtime] +provider_id = "file://scripts/opencode-cli-provider.js" +opencode_config = "opencode.json" +project_dir = "../.." +format = "default" +log_level = "ERROR" +print_logs = false +empty_output_retries = 1 + +[tiers.light] +agent = "eval_light" + +[tiers.standard] +agent = "eval_standard" + +[tiers.high] +agent = "eval_high" + +[tiers.x_high] +agent = "eval_x_high" diff --git a/tests/evals/opencode.json b/tests/evals/opencode.json new file mode 100644 index 000000000..c8f2fc89e --- /dev/null +++ b/tests/evals/opencode.json @@ -0,0 +1,80 @@ +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "opencode": { + "options": { + "timeout": false + } + } + }, + "agent": { + "eval_light": { + "description": "Promptfoo eval agent for light-cost scenarios.", + "mode": "primary", + "model": "opencode/qwen3.6-plus", + "temperature": 0.1, + "steps": 60, + "permission": { + "read": "allow", + "write": "allow", + "edit": "allow", + "bash": "allow", + "grep": "allow", + "glob": "allow", + "list": "allow", + "webfetch": "deny" + } + }, + "eval_standard": { + "description": "Promptfoo eval agent for standard scenarios.", + "mode": "primary", + "model": "opencode/qwen3.6-plus", + "temperature": 0.1, + "steps": 100, + "permission": { + "read": "allow", + "write": "allow", + "edit": "allow", + "bash": "allow", + "grep": "allow", + "glob": "allow", + "list": "allow", + "webfetch": "deny" + } + }, + "eval_high": { + "description": "Promptfoo eval agent for high-cost scenarios.", + "mode": "primary", + "model": "opencode/qwen3.6-plus", + "temperature": 0.1, + "steps": 120, + "permission": { + "read": "allow", + "write": "allow", + "edit": "allow", + "bash": "allow", + "grep": "allow", + "glob": "allow", + "list": "allow", + "webfetch": "deny" + } + }, + "eval_x_high": { + "description": "Promptfoo eval agent for extra-high-cost scenarios.", + "mode": "primary", + "model": "opencode/qwen3.6-plus", + "temperature": 0.1, + "steps": 200, + "permission": { + "read": "allow", + "write": "allow", + "edit": "allow", + "bash": "allow", + "grep": "allow", + "glob": "allow", + "list": "allow", + "webfetch": "deny" + } + } + } +} diff --git a/tests/evals/package-lock.json b/tests/evals/package-lock.json new file mode 100644 index 000000000..1106ed18d --- /dev/null +++ b/tests/evals/package-lock.json @@ -0,0 +1,12798 @@ +{ + "name": "@skill-builder/evals", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@skill-builder/evals", + "dependencies": { + "js-yaml": "^4.1.1", + "promptfoo": "0.121.9", + "smol-toml": "^1.6.1" + } + }, + "node_modules/@ai-sdk/gateway": { + "version": "3.0.107", + "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-3.0.107.tgz", + "integrity": "sha512-JwODLcuTe8rWXJwQcNPE5fiadjCOKHxNGtL5pHqEhFQSuWs6x47oVRkLs/Zw6eUhTsuXiZbyJ3QJHVIyLKX5hg==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "3.0.10", + "@ai-sdk/provider-utils": "4.0.25", + "@vercel/oidc": "3.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/provider": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-3.0.10.tgz", + "integrity": "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw==", + "license": "Apache-2.0", + "dependencies": { + "json-schema": "^0.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ai-sdk/provider-utils": { + "version": "4.0.25", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-4.0.25.tgz", + "integrity": "sha512-yjGPZPiJm79ZOYk0anXn2LkVqUFgStZqEOdyoynhkaAg+yOCuv6PJwf+1gUW0eSIUnYEboT2TPbPX/bxZpx4gw==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "3.0.10", + "@standard-schema/spec": "^1.1.0", + "eventsource-parser": "^3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/provider-utils/node_modules/eventsource-parser": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.8.tgz", + "integrity": "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@ai-zen/node-fetch-event-source": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@ai-zen/node-fetch-event-source/-/node-fetch-event-source-2.1.4.tgz", + "integrity": "sha512-OHFwPJecr+qwlyX5CGmTvKAKPZAdZaxvx/XDqS1lx4I2ZAk9riU0XnEaRGOOAEFrdcLZ98O5yWqubwjaQc0umg==", + "license": "MIT", + "optional": true, + "dependencies": { + "cross-fetch": "^4.0.0" + } + }, + "node_modules/@alcalzone/ansi-tokenize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.2.5.tgz", + "integrity": "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@anthropic-ai/claude-agent-sdk": { + "version": "0.2.126", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.2.126.tgz", + "integrity": "sha512-4ZrVu0XUEwNG6wxvsLgppRAmSfAf3oeEMEUPhgazb0AXUUe/7W8MxwZKJWOffqSLWaNYzOt3ZCIL7NJY6toqWw==", + "license": "SEE LICENSE IN README.md", + "optional": true, + "dependencies": { + "@anthropic-ai/sdk": "^0.81.0", + "@modelcontextprotocol/sdk": "^1.29.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.2.126", + "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.2.126", + "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.2.126", + "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.2.126", + "@anthropic-ai/claude-agent-sdk-linux-x64": "0.2.126", + "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.2.126", + "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.2.126", + "@anthropic-ai/claude-agent-sdk-win32-x64": "0.2.126" + }, + "peerDependencies": { + "zod": "^4.0.0" + } + }, + "node_modules/@anthropic-ai/claude-agent-sdk-darwin-arm64": { + "version": "0.2.126", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.2.126.tgz", + "integrity": "sha512-JFlJBbeAlx7Ic5s4lGUN9SppobryXk/lIqPCvhp6KrJTQIerh3MIBzxsVIJ0MaDut7jVni/oYgsvDni7NIyqHA==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-darwin-x64": { + "version": "0.2.126", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.2.126.tgz", + "integrity": "sha512-J8BpMj16NK9FUaG3HnHSivyp4Xww9DKWHiC8QSHT9oiT8pH5IG7nl0jxyjIq/lY79evlTY+ubgDVWlMUhUAN/g==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64": { + "version": "0.2.126", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.2.126.tgz", + "integrity": "sha512-LM+mnfQsgI+1i5mYZwIPDDf14NGBu5wbhzm5U8P11dCa2p8sXmKoWpkbO16BFM2NxeW44I/RXCxE5qFsbz4zcg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64-musl": { + "version": "0.2.126", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.2.126.tgz", + "integrity": "sha512-GO0BnIUw3LQ3XAy+nipAabkN0GwQGPhHB6ITI4XLoR99fLHB3TA6WfyvTf0fnpxd25A+c/+UsAoxz4zBQaHlhA==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64": { + "version": "0.2.126", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.2.126.tgz", + "integrity": "sha512-yaOTDcYCdscxC0LKg9w8IwSa5g+993WggFZJBTZpqvflA2+WMQeTarDnKlsFTCw9XUZkL8XZeBALYJGx0HutuA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl": { + "version": "0.2.126", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.2.126.tgz", + "integrity": "sha512-ByJGO0+mu7EplxSFSCIHd7QWsXdrF3qgtzQ177o/j+oSppLoqR1ot5ktf8aw5oR3CC5lFHg4tqd6TnneQpEoIg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-win32-arm64": { + "version": "0.2.126", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.2.126.tgz", + "integrity": "sha512-gv3MOsOBkCx3LajOOIjD7AKsOtz/qNHsS2oshGt2GVoy7JA3XbCDeCetDjM6SorV4SE+7F/IH0UJdXe5ejI/Zg==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-win32-x64": { + "version": "0.2.126", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.2.126.tgz", + "integrity": "sha512-oRV75HwyoOd1/t5+kipAM2g62CaElpKGvSBx3Ys4lCwCiFUyOnmet/O+hRXENsY6ShDeQZEcJL2UWljr2d5NQw==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.92.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.92.0.tgz", + "integrity": "sha512-l653JFC83wCglH8H83t1xpgDurCyPyslYW1maPRdCsfuNuGbLvQjQ81sWd3Go3LWRm0jNspzAhuqAYV8r9joSw==", + "license": "MIT", + "dependencies": { + "json-schema-to-ts": "^3.1.1" + }, + "bin": { + "anthropic-ai-sdk": "bin/cli" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "15.3.5", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-15.3.5.tgz", + "integrity": "sha512-orNOYXw3hYXxxisXMldjzjBzqqTLBPbwOtHg7ovBPvfBHDue1qM9YJENZ3W2BQuS+7z4ThogMbEzEsov57Itkg==", + "license": "MIT", + "dependencies": { + "js-yaml": "^4.1.1" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@types/json-schema": "^7.0.15" + } + }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/crc32c": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", + "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", + "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-agent-runtime": { + "version": "3.1040.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-agent-runtime/-/client-bedrock-agent-runtime-3.1040.0.tgz", + "integrity": "sha512-XbrlQBdD9XbuvyEU0KdgKX4RNQRJ4bkOzb1PnPJowCaVP+1MnUVMywfq9tKua/cGHJvBTQDbjQP9L38+W3RgDg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/credential-provider-node": "^3.972.38", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.37", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.23", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/eventstream-serde-config-resolver": "^4.3.14", + "@smithy/eventstream-serde-node": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.7", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-runtime": { + "version": "3.1040.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1040.0.tgz", + "integrity": "sha512-tFCqtci1gVGIRwgK3tmv2DV2EawXjBIQgwM/7KaeL4wHUMhNMUA+POUw6vGowtQb51ZaSDjK3KzI3MaQskOyuw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/credential-provider-node": "^3.972.38", + "@aws-sdk/eventstream-handler-node": "^3.972.14", + "@aws-sdk/middleware-eventstream": "^3.972.10", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.37", + "@aws-sdk/middleware-websocket": "^3.972.16", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/token-providers": "3.1040.0", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.23", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/eventstream-serde-config-resolver": "^4.3.14", + "@smithy/eventstream-serde-node": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.7", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.1040.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1040.0.tgz", + "integrity": "sha512-Ldfby1xDrlZwNY2NxP9pwdVrf8sqHbGBKP1UkoG/oWcePGlGhjY8iVwy8hRy9f1EQfHVFWIFunwHaPQxhYTnWQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/sha1-browser": "5.2.0", + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/credential-provider-node": "^3.972.38", + "@aws-sdk/middleware-bucket-endpoint": "^3.972.10", + "@aws-sdk/middleware-expect-continue": "^3.972.10", + "@aws-sdk/middleware-flexible-checksums": "^3.974.15", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-location-constraint": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-sdk-s3": "^3.972.36", + "@aws-sdk/middleware-ssec": "^3.972.10", + "@aws-sdk/middleware-user-agent": "^3.972.37", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/signature-v4-multi-region": "^3.996.24", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.23", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/eventstream-serde-config-resolver": "^4.3.14", + "@smithy/eventstream-serde-node": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-blob-browser": "^4.2.15", + "@smithy/hash-node": "^4.2.14", + "@smithy/hash-stream-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/md5-js": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.7", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sagemaker-runtime": { + "version": "3.1040.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sagemaker-runtime/-/client-sagemaker-runtime-3.1040.0.tgz", + "integrity": "sha512-PzGidXbFyq1Ei/graGw6EKgsDhzi75AqSpiwMLaHAQjdybSnDNk07MOAbrsUIzBlc7qjS7zA6z99BkoE9VBdLQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/credential-provider-node": "^3.972.38", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.37", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.23", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/eventstream-serde-config-resolver": "^4.3.14", + "@smithy/eventstream-serde-node": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.7", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.974.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.7.tgz", + "integrity": "sha512-YhRC90ofz5oolTJZlA8voU/oUrCB2azi8Usx51k8hhB5LpWbYQMMXKUqSqkoL0Cru+RQJgWTHpAfEDDIwfUhJw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/xml-builder": "^3.972.22", + "@smithy/core": "^3.23.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/crc64-nvme": { + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.7.tgz", + "integrity": "sha512-QUagVVBbC8gODCF6e1aV0mE2TXWB9Opz4k8EJFdNrujUVQm5R4AjJa1mpOqzwOuROBzqJU9zawzig7M96L8Ejg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.972.33", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.33.tgz", + "integrity": "sha512-bJV7eViSJV6GSuuN+VIdNVPdwPsNSf75BiC2v5alPrjR/OCcqgKwSZInKbDFz9mNeizldsyf67jt6YSIiv53Cw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.972.35", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.35.tgz", + "integrity": "sha512-x/BQGEIdq0oI+4WxLjKmnQvT7CnF9r8ezdGt7wXwxb7ckHXQz0Zmgxt8v3Ne0JaT3R5YefmuybHX6E8EnsDXyA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/types": "^3.973.8", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-stream": "^4.5.25", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.37.tgz", + "integrity": "sha512-eUTpmWfd/BKsq9medhCRcu+GRAhFP2Zrn7/2jKDHHOOjCkhrMoTp/t4cEthqFoG7gE0VGp5wUxrXTdvBCmSmJg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/credential-provider-env": "^3.972.33", + "@aws-sdk/credential-provider-http": "^3.972.35", + "@aws-sdk/credential-provider-login": "^3.972.37", + "@aws-sdk/credential-provider-process": "^3.972.33", + "@aws-sdk/credential-provider-sso": "^3.972.37", + "@aws-sdk/credential-provider-web-identity": "^3.972.37", + "@aws-sdk/nested-clients": "^3.997.5", + "@aws-sdk/types": "^3.973.8", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.37.tgz", + "integrity": "sha512-Ty68y8ISSC+g5Q3D0K8uAaoINwvfaOslnNpsF/LgVUxyosYXHawcK2yV4HLXDVugiTTYLQfJfcw0ce5meAGkKw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/nested-clients": "^3.997.5", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.972.38", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.38.tgz", + "integrity": "sha512-BQ9XYnBDVxR2HuV5huXYQYF/PZMTsY+EnwfGnCU2cA8Zw63XpkOtPY8WqiMIZMQCrKPQQEiFURS/o9CIolRLqg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/credential-provider-env": "^3.972.33", + "@aws-sdk/credential-provider-http": "^3.972.35", + "@aws-sdk/credential-provider-ini": "^3.972.37", + "@aws-sdk/credential-provider-process": "^3.972.33", + "@aws-sdk/credential-provider-sso": "^3.972.37", + "@aws-sdk/credential-provider-web-identity": "^3.972.37", + "@aws-sdk/types": "^3.973.8", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.972.33", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.33.tgz", + "integrity": "sha512-yfjGksI9WQbdMObb0VeLXqzTLI+a0qXLJT9gCDiv0+X/xjPpI3mTz6a5FibrhpuEKIe0gSgvs3MaoFZy5cx4WA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.37.tgz", + "integrity": "sha512-fpwE+20ntpp3i9Xb9vUuQfXLDKYHH+5I2V+ZG96SX1nBzrruhy10RXDgmN7t1etOz3c55stlA3TeQASUA451NQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/nested-clients": "^3.997.5", + "@aws-sdk/token-providers": "3.1039.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers": { + "version": "3.1039.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1039.0.tgz", + "integrity": "sha512-NMSFL2HwkAOoCeLCQiqoOq5pT3vVbSjww2QZTuYgYknVwhhv125PSDzZIcL5EYnlxuPWjEOdauZK+FspkZDVdw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/nested-clients": "^3.997.5", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.37.tgz", + "integrity": "sha512-aryawqyebf+3WhAFNHfF62rekFpYtVcVN7dQ89qnAWsa4n5hJst8qBG6gXC24WHtW7Nnhkf9ScYnjwo0Brn3bw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/nested-clients": "^3.997.5", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-handler-node": { + "version": "3.972.14", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.14.tgz", + "integrity": "sha512-m4X56gxG76/CKfxNVbOFuYwnAZcHgS6HOH8lgp15HoGHIAVTcZfZrXvcYzJFOMLEJgVn+JHBu6EiNV+xSNXXFg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/eventstream-codec": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-bucket-endpoint": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.10.tgz", + "integrity": "sha512-Vbc2frZH7wXlMNd+ZZSXUEs/l1Sv8Jj4zUnIfwrYF5lwaLdXHZ9xx4U3rjUcaye3HRhFVc+E5DbBxpRAbB16BA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-config-provider": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-eventstream": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.10.tgz", + "integrity": "sha512-QUqLs7Af1II9X4fCRAu+EGHG3KHyOp4RkuLhRKoA3NuFlh6TL8i+zXBl8w2LUxqm44B/Kom45hgSlwA1SpTsXQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-expect-continue": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.10.tgz", + "integrity": "sha512-2Yn0f1Qiq/DjxYR3wfI3LokXnjOhFM7Ssn4LTdFDIxRMCE6I32MAsVnhPX1cUZsuVA9tiZtwwhlSLAtFGxAZlQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.974.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.15.tgz", + "integrity": "sha512-j4Zp7rA1HfhDTteICnx/tPax4N/v5wmytgguXExUGyEwQ8Ug4EBA4kjp9puFAN1UZoBVpxoiXMiuTFvjaHjeEw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@aws-crypto/crc32c": "5.2.0", + "@aws-crypto/util": "5.2.0", + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/crc64-nvme": "^3.972.7", + "@aws-sdk/types": "^3.973.8", + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.10.tgz", + "integrity": "sha512-IJSsIMeVQ8MMCPbuh1AbltkFhLBLXn7aejzfX5YKT/VLDHn++Dcz8886tXckE+wQssyPUhaXrJhdakO2VilRhg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.10.tgz", + "integrity": "sha512-rI3NZvJcEvjoD0+0PI0iUAwlPw2IlSlhyvgBK/3WkKJQE/YiKFedd9dMN2lVacdNxPNhxL/jzQaKQdrGtQagjQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.10.tgz", + "integrity": "sha512-OOuGvvz1Dm20SjZo5oEBePFqxt5nf8AwkNDSyUHvD9/bfNASmstcYxFAHUowy4n6Io7mWUZ04JURZwSBvyQanQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.11.tgz", + "integrity": "sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.972.36", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.36.tgz", + "integrity": "sha512-YhPix+0x/MdQrb1Ug1GDKeS5fqylIy+naz800asX8II4jqfTk2KY2KhmmYCwZcky8YWtRQQwWCGdoqeAnip8Uw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/core": "^3.23.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.10.tgz", + "integrity": "sha512-Gli9A0u8EVVb+5bFDGS/QbSVg28w/wpEidg1ggVcSj65BDTdGR6punsOcVjqdiu1i42WHWo51MCvARPIIz9juw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.37.tgz", + "integrity": "sha512-N1oNpdiLoVAWYD3WFBnUi3LlfoDA06ZHo4ozyjbsJNLvILzvt//0CnR8N+CZ0NWeYgVB/5V59ivixHCWCx2ALw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@smithy/core": "^3.23.17", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-retry": "^4.3.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-websocket": { + "version": "3.972.16", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.16.tgz", + "integrity": "sha512-86+S9oCyRVGzoMRpQhxkArp7kD2K75GPmaNevd9B6EyNhWoNvnCZZ3WbgN4j7ZT+jvtvBCGZvI2XHsWZJ+BRIg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-format-url": "^3.972.10", + "@smithy/eventstream-codec": "^4.2.14", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.997.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.5.tgz", + "integrity": "sha512-jGFr6DxtcMTmzOkG/a0jCZYv4BBDmeNYVeO+/memSoDkYCJu4Y58xviYmzwJfYyIVSts+X/BVjJm1uGBnwHEMg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.37", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/signature-v4-multi-region": "^3.996.24", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.23", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.7", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.972.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.13.tgz", + "integrity": "sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/config-resolver": "^4.4.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.996.24", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.24.tgz", + "integrity": "sha512-amP7tLikppN940wbBFISYqiuzVmpzMS9U3mcgtmVLjX4fdWI/SNCvrXv6ZxfVzTT4cT0rPKOLhFah2xLwzREWw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "^3.972.36", + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.1040.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1040.0.tgz", + "integrity": "sha512-0KTpz2KqASQwzLOywV1bS2TX6Su0bARkATgpSu236BDM/D/6cMQ2EPiFwoRYwwvXsWSDn8KkKp9NV2ZWWA53Xw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/core": "^3.974.7", + "@aws-sdk/nested-clients": "^3.997.5", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.973.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz", + "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.3.tgz", + "integrity": "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.996.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.8.tgz", + "integrity": "sha512-oOZHcRDihk5iEe5V25NVWg45b3qEA8OpHWVdU/XQh8Zj4heVPAJqWvMphQnU7LkufmUo10EpvFPZuQMiFLJK3g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-endpoints": "^3.4.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-format-url": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.10.tgz", + "integrity": "sha512-DEKiHNJVtNxdyTeQspzY+15Po/kHm6sF0Cs4HV9Q2+lplB63+DrvdeiSoOSdWEWAoO2RcY1veoXVDz2tWxWCgQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/querystring-builder": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz", + "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.10.tgz", + "integrity": "sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.973.23", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.23.tgz", + "integrity": "sha512-gGwq8L2Euw0aNG6Ey4EktiAo3fSCVoDy1CaBIthd+oeaKHPXUrNaApMewQ6La5Hv0lcznOtECZaNvYyc5LXXfA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-sdk/middleware-user-agent": "^3.972.37", + "@aws-sdk/types": "^3.973.8", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-config-provider": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.972.22", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.22.tgz", + "integrity": "sha512-PMYKKtJd70IsSG0yHrdAbxBr+ZWBKLvzFZfD3/urxgf6hXVMzuU5M+3MJ5G67RpOmLBu1fAUN65SbWuKUCOlAA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@nodable/entities": "2.1.0", + "@smithy/types": "^4.14.1", + "fast-xml-parser": "5.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", + "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure-rest/core-client": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@azure-rest/core-client/-/core-client-2.6.0.tgz", + "integrity": "sha512-iuFKDm8XPzNxPfRjhyU5/xKZmcRDzSuEghXDHHk4MjBV/wFL34GmYVBZnn9wmuoLBeS1qAw9ceMdaeJBPcB1QQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0", + "@azure/core-tracing": "^1.3.0", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/ai-projects": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@azure/ai-projects/-/ai-projects-2.1.0.tgz", + "integrity": "sha512-1NWxmcfAqa9xBS+RcekdT6FRVcTlPdw5VMLXq+tJxZo1jGtJghiuXa7tsriReA42pAjUHJ4N2fYL/JIZAeCizg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure-rest/core-client": "^2.1.0", + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.6.0", + "@azure/core-lro": "^3.1.0", + "@azure/core-paging": "^1.5.0", + "@azure/core-rest-pipeline": "^1.5.0", + "@azure/core-sse": "^2.1.3", + "@azure/core-tracing": "^1.2.0", + "@azure/core-util": "^1.9.0", + "@azure/identity": "^4.13.0", + "@azure/logger": "^1.1.4", + "@azure/storage-blob": "^12.26.0", + "openai": "^6.16.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", + "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz", + "integrity": "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-http-compat": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.4.0.tgz", + "integrity": "sha512-f1P96IB399YiN2ARYHP7EpZi3Bf3wH4SN2lGzrw7JVwm7bbsVYtf2iKSBwTywD2P62NOPZGHFSZi+6jjb75JuA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.1.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@azure/core-client": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0" + } + }, + "node_modules/@azure/core-lro": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-3.3.1.tgz", + "integrity": "sha512-bulm3klLqIAhzI3iQMYQ42i+V9EnevScsHdI9amFfjaw6OJqPBK1038cq5qachoKV3yt/iQQEDittHmZW2aSuA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-paging": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.6.2.tgz", + "integrity": "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.23.0.tgz", + "integrity": "sha512-Evs1INHo+jUjwHi1T6SG6Ua/LHOQBCLuKEEE6efIpt4ZOoNonaT1kP32GoOcdNDbfqsD2445CPri3MubBy5DEQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "@typespec/ts-http-runtime": "^0.3.4", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-sse": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-sse/-/core-sse-2.3.0.tgz", + "integrity": "sha512-jKhPpdDbVS5GlpadSKIC7V6Q4P2vEcwXi1c4CLTXs01Q/PAITES9v5J/S73+RtCMqQpsX0jGa2yPWwXi9JzdgA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz", + "integrity": "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", + "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-xml": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.5.1.tgz", + "integrity": "sha512-xcNRHqCoSp4AunOALEae6A8f3qATb83gSrm31Iqb01OzblvC3/W/bfXozcq78EzIdzZzuH1bZ2NvRR0TdX709w==", + "license": "MIT", + "optional": true, + "dependencies": { + "fast-xml-parser": "^5.5.9", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.13.1.tgz", + "integrity": "sha512-5C/2WD5Vb1lHnZS16dNQRPMjN6oV/Upba+C9nBIs15PmOi6A3ZGs4Lr2u60zw4S04gi+u3cEXiqTVP7M4Pz3kw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^5.5.0", + "@azure/msal-node": "^5.1.0", + "open": "^10.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/logger": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz", + "integrity": "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/msal-browser": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-5.9.0.tgz", + "integrity": "sha512-CzE+4PefDSJWj26zU7G1bKchlGRRHMBFreG4tAlGuzyI8hAPiYGobaJvZBgZBf6L63iphX7VH+ityL8VgEQz9Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/msal-common": "16.5.2" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "16.5.2", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.5.2.tgz", + "integrity": "sha512-GkDEL6TYo3HgT3UuqakdgE9PZfc1hMki6+Hwgy1uddb/EauvAKfu85vVhuofRSo22D1xTnWt8Ucwfg4vSCVwvA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-5.1.5.tgz", + "integrity": "sha512-ObTeMoNPmq19X3z40et9Xvs4ZoWVeJg43PZMRLG5iwVL+2nCtAerG3YTDItqPp1CfXNwmCXBbg8jn1DOx65c3g==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/msal-common": "16.5.2", + "jsonwebtoken": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@azure/openai-assistants": { + "version": "1.0.0-beta.6", + "resolved": "https://registry.npmjs.org/@azure/openai-assistants/-/openai-assistants-1.0.0-beta.6.tgz", + "integrity": "sha512-gINKKcqTpR0neF+36Owe0Q1u1JO3IK6clBzWTfZ+9V/TkQq+LoUgp5F8dKvSv/YChfwEpZA2r1DWCwNE07eYIQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure-rest/core-client": "^1.1.4", + "@azure/core-auth": "^1.5.0", + "@azure/core-client": "^1.7.3", + "@azure/core-rest-pipeline": "^1.13.0", + "@azure/core-util": "^1.6.1", + "@azure/logger": "^1.0.4", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/openai-assistants/node_modules/@azure-rest/core-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@azure-rest/core-client/-/core-client-1.4.0.tgz", + "integrity": "sha512-ozTDPBVUDR5eOnMIwhggbnVmOrka4fXCs8n8mvUo4WLLc38kki6bAOByDoVZZPz/pZy2jMt2kwfpvy/UjALj6w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-rest-pipeline": "^1.5.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/storage-blob": { + "version": "12.31.0", + "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.31.0.tgz", + "integrity": "sha512-DBgNv10aCSxopt92DkTDD0o9xScXeBqPKGmR50FPZQaEcH4JLQ+GEOGEDv19V5BMkB7kxr+m4h6il/cCDPvmHg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.3", + "@azure/core-http-compat": "^2.2.0", + "@azure/core-lro": "^2.2.0", + "@azure/core-paging": "^1.6.2", + "@azure/core-rest-pipeline": "^1.19.1", + "@azure/core-tracing": "^1.2.0", + "@azure/core-util": "^1.11.0", + "@azure/core-xml": "^1.4.5", + "@azure/logger": "^1.1.4", + "@azure/storage-common": "^12.3.0", + "events": "^3.0.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/storage-blob/node_modules/@azure/core-lro": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.7.2.tgz", + "integrity": "sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.2.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/storage-common": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@azure/storage-common/-/storage-common-12.3.0.tgz", + "integrity": "sha512-/OFHhy86aG5Pe8dP5tsp+BuJ25JOAl9yaMU3WZbkeoiFMHFtJ7tu5ili7qEdBXNW9G5lDB19trwyI6V49F/8iQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.9.0", + "@azure/core-http-compat": "^2.2.0", + "@azure/core-rest-pipeline": "^1.19.1", + "@azure/core-tracing": "^1.2.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.1.4", + "events": "^3.3.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@borewit/text-codec": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz", + "integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==", + "license": "MIT", + "optional": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@cacheable/utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.4.1.tgz", + "integrity": "sha512-eiFgzCbIneyMlLOmNG4g9xzF7Hv3Mga4LjxjcSC/ues6VYq2+gUbQI8JqNuw/ZM8tJIeIaBGpswAsqV2V7ApgA==", + "license": "MIT", + "dependencies": { + "hashery": "^1.5.1", + "keyv": "^5.6.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz", + "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==", + "license": "MIT", + "dependencies": { + "@so-ric/colorspace": "^1.1.6", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fal-ai/client": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@fal-ai/client/-/client-1.10.0.tgz", + "integrity": "sha512-sQWnBc6cdIzK8nFybrVKal0rLeJS2vqrrNxx4Hcc0SorndkfkMXL3TIAiIfiF/AlZuVoRpazpNg6n8K81WHzOQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@msgpack/msgpack": "^3.0.0-beta2", + "eventsource-parser": "^1.1.2", + "robot3": "^0.4.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@googleapis/sheets": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@googleapis/sheets/-/sheets-13.0.1.tgz", + "integrity": "sha512-XTYObncN5Rqexc0uITZIN9OWTEyE/ZR2S6c7wAniqHe2oGXW9gcHR9f9hQwPMHFUTHjH7Jkj8SLdt0O0u37y2A==", + "license": "Apache-2.0", + "dependencies": { + "googleapis-common": "^8.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@hono/node-server": { + "version": "1.19.14", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", + "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@huggingface/jinja": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.5.8.tgz", + "integrity": "sha512-ZdElB7DPS7QQS8ZnFc5RPPtkg+eN11z8AmIZWAyes6pSbwXqiFB/POVevvm01begdSX1ho9Gxln/F6qlQMsuaA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@huggingface/tokenizers": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@huggingface/tokenizers/-/tokenizers-0.1.3.tgz", + "integrity": "sha512-8rF/RRT10u+kn7YuUbUg0OF30K8rjTc78aHpxT+qJ1uWSqxT1MHi8+9ltwYfkFYJzT/oS+qw3JVfHtNMGAdqyA==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@huggingface/transformers": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@huggingface/transformers/-/transformers-4.2.0.tgz", + "integrity": "sha512-8BRCoBMH0XsWaEIamuR0LrJGAfftgHAfb2Vrffy0VKlSAE/MnUJ5/h/zTfEP3fDIft+nk7TqB8xXEyABGitBjQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@huggingface/jinja": "^0.5.6", + "@huggingface/tokenizers": "^0.1.3", + "onnxruntime-node": "1.24.3", + "onnxruntime-web": "1.26.0-dev.20260416-b7804b056c", + "sharp": "^0.34.5" + } + }, + "node_modules/@ibm-cloud/watsonx-ai": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@ibm-cloud/watsonx-ai/-/watsonx-ai-1.7.11.tgz", + "integrity": "sha512-sBMj/YhV5qvJdBpvgutmX6vLUUnSwvhFaJk7r3hiMh5aB7BQWQ+5zyzvSPLywOwTWZbgy4v8jxTUhR6jb+kguw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@types/node": "^18.0.0", + "extend": "3.0.2", + "form-data": "^4.0.4", + "ibm-cloud-sdk-core": "^5.4.9", + "ts-node": "^10.9.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@ibm-generative-ai/node-sdk": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@ibm-generative-ai/node-sdk/-/node-sdk-3.2.4.tgz", + "integrity": "sha512-HvJSYql3lOPYZcGb23mBw0kcWLlCX+n7EDRgJQxz7gIzx9WafUuDyl1IlTCXGfxolm0EhNIub79u9v7owtks0w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@ai-zen/node-fetch-event-source": "^2.1.2", + "fetch-retry": "^5.0.6", + "http-status-codes": "^2.3.0", + "openapi-fetch": "^0.8.2", + "p-queue-compat": "1.0.225", + "yaml": "^2.3.3" + }, + "peerDependencies": { + "@langchain/core": ">=0.1.0" + }, + "peerDependenciesMeta": { + "@langchain/core": { + "optional": true + } + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@inquirer/ansi": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.5.tgz", + "integrity": "sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw==", + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.1.4.tgz", + "integrity": "sha512-w6KF8ZYRvqHhROkOTHXYC3qIV/KYEu5o12oLqQySvch61vrYtRxNSHTONSdJqWiFJPlCUQAHT5OgOIyuTr+MHQ==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.5", + "@inquirer/core": "^11.1.9", + "@inquirer/figures": "^2.0.5", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.0.12.tgz", + "integrity": "sha512-h9FgGun3QwVYNj5TWIZZ+slii73bMoBFjPfVIGtnFuL4t8gBiNDV9PcSfIzkuxvgquJKt9nr1QzszpBzTbH8Og==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "11.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.1.9.tgz", + "integrity": "sha512-BDE4fG22uYh1bGSifcj7JSx119TVYNViMhMu85usp4Fswrzh6M0DV3yld64jA98uOAa2GSQ4Bg4bZRm2d2cwSg==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.5", + "@inquirer/figures": "^2.0.5", + "@inquirer/type": "^4.0.5", + "cli-width": "^4.1.0", + "fast-wrap-ansi": "^0.2.0", + "mute-stream": "^3.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.1.1.tgz", + "integrity": "sha512-6y11LgmNpmn5D2aB5FgnCfBUBK8ZstwLCalyJmORcJZ/WrhOjm16mu6eSqIx8DnErxDqSLr+Jkp+GP8/Nwd5tA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/external-editor": "^3.0.0", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-3.0.0.tgz", + "integrity": "sha512-lDSwMgg+M5rq6JKBYaJwSX6T9e/HK2qqZ1oxmOwn4AQoJE5D+7TumsxLGC02PWS//rkIVqbZv3XA3ejsc9FYvg==", + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.5.tgz", + "integrity": "sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ==", + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + } + }, + "node_modules/@inquirer/input": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.0.12.tgz", + "integrity": "sha512-uiMFBl4LqFzJClh80Q3f9hbOFJ6kgkDWI4LjAeBuyO6EanVVMF69AgOvpi1qdqjDSjDN6578B6nky9ceEpI+1Q==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.1.4.tgz", + "integrity": "sha512-2kWcGKPMLAXAWRp1AH1SLsQmX+j0QjeljyXMUji9WMZC8nRDO0b7qquIGr6143E7KMLt3VAIGNXzwa/6PXQs4Q==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.5", + "@inquirer/core": "^11.1.9", + "@inquirer/figures": "^2.0.5", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.5.tgz", + "integrity": "sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==", + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT", + "optional": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "license": "MIT" + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "license": "MIT" + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz", + "integrity": "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/eventsource-parser": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.8.tgz", + "integrity": "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.10.tgz", + "integrity": "sha512-DDb3OAw8ezai9p2i1F7R5wMVmyrMIuT8ixjV56R4Hl4cazCo2tOMTDyPR5rrCUcHiMbWHzCXOdife5OD6H1C8w==", + "license": "MIT", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@msgpack/msgpack": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.1.3.tgz", + "integrity": "sha512-47XIizs9XZXvuJgoaJUIE2lFoID8ugvc0jzSHP+Ptfk8nTbnR8g788wv48N03Kx0UkAv559HWRQ3yzOgzlRNUA==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@napi-rs/canvas": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.80.tgz", + "integrity": "sha512-DxuT1ClnIPts1kQx8FBmkk4BQDTfI5kIzywAaMjQSXfNnra5UFU9PwurXrl+Je3bJ6BGsp/zmshVVFbCmyI+ww==", + "license": "MIT", + "optional": true, + "workspaces": [ + "e2e/*" + ], + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@napi-rs/canvas-android-arm64": "0.1.80", + "@napi-rs/canvas-darwin-arm64": "0.1.80", + "@napi-rs/canvas-darwin-x64": "0.1.80", + "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.80", + "@napi-rs/canvas-linux-arm64-gnu": "0.1.80", + "@napi-rs/canvas-linux-arm64-musl": "0.1.80", + "@napi-rs/canvas-linux-riscv64-gnu": "0.1.80", + "@napi-rs/canvas-linux-x64-gnu": "0.1.80", + "@napi-rs/canvas-linux-x64-musl": "0.1.80", + "@napi-rs/canvas-win32-x64-msvc": "0.1.80" + } + }, + "node_modules/@napi-rs/canvas-android-arm64": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.80.tgz", + "integrity": "sha512-sk7xhN/MoXeuExlggf91pNziBxLPVUqF2CAVnB57KLG/pz7+U5TKG8eXdc3pm0d7Od0WreB6ZKLj37sX9muGOQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-darwin-arm64": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.80.tgz", + "integrity": "sha512-O64APRTXRUiAz0P8gErkfEr3lipLJgM6pjATwavZ22ebhjYl/SUbpgM0xcWPQBNMP1n29afAC/Us5PX1vg+JNQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-darwin-x64": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.80.tgz", + "integrity": "sha512-FqqSU7qFce0Cp3pwnTjVkKjjOtxMqRe6lmINxpIZYaZNnVI0H5FtsaraZJ36SiTHNjZlUB69/HhxNDT1Aaa9vA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm-gnueabihf": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.80.tgz", + "integrity": "sha512-eyWz0ddBDQc7/JbAtY4OtZ5SpK8tR4JsCYEZjCE3dI8pqoWUC8oMwYSBGCYfsx2w47cQgQCgMVRVTFiiO38hHQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-gnu": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.80.tgz", + "integrity": "sha512-qwA63t8A86bnxhuA/GwOkK3jvb+XTQaTiVML0vAWoHyoZYTjNs7BzoOONDgTnNtr8/yHrq64XXzUoLqDzU+Uuw==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-musl": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.80.tgz", + "integrity": "sha512-1XbCOz/ymhj24lFaIXtWnwv/6eFHXDrjP0jYkc6iHQ9q8oXKzUX1Lc6bu+wuGiLhGh2GS/2JlfORC5ZcXimRcg==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-riscv64-gnu": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.80.tgz", + "integrity": "sha512-XTzR125w5ZMs0lJcxRlS1K3P5RaZ9RmUsPtd1uGt+EfDyYMu4c6SEROYsxyatbbu/2+lPe7MPHOO/0a0x7L/gw==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-gnu": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.80.tgz", + "integrity": "sha512-BeXAmhKg1kX3UCrJsYbdQd3hIMDH/K6HnP/pG2LuITaXhXBiNdh//TVVVVCBbJzVQaV5gK/4ZOCMrQW9mvuTqA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-musl": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.80.tgz", + "integrity": "sha512-x0XvZWdHbkgdgucJsRxprX/4o4sEed7qo9rCQA9ugiS9qE2QvP0RIiEugtZhfLH3cyI+jIRFJHV4Fuz+1BHHMg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-win32-x64-msvc": { + "version": "0.1.80", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.80.tgz", + "integrity": "sha512-Z8jPsM6df5V8B1HrCHB05+bDiCxjE9QA//3YrkKIdVDEwn5RKaqOxCJDRJkl48cJbylcrJbW4HxZbTte8juuPg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, + "node_modules/@openai/agents": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@openai/agents/-/agents-0.8.5.tgz", + "integrity": "sha512-OFA7XVV1qXE8lzatvQj080KdSArt8utBExFXRfD5B/R7KT0D+AVaKwg6nLoW3Gxb30vRkIUQf+MaW/Wz+gO3Yg==", + "license": "MIT", + "dependencies": { + "@openai/agents-core": "0.8.5", + "@openai/agents-openai": "0.8.5", + "@openai/agents-realtime": "0.8.5", + "debug": "^4.4.0", + "openai": "^6.26.0" + }, + "peerDependencies": { + "zod": "^4.0.0" + } + }, + "node_modules/@openai/agents-core": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@openai/agents-core/-/agents-core-0.8.5.tgz", + "integrity": "sha512-qs9mmN+D+UmqEZo3qrvhhIIXIOgSvJPic0v4a+ruq+eYgcQMk3PY8lLcsdQwJit6zf2Wyfv1q2cX5m3jzWZpKw==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "openai": "^6.26.0" + }, + "optionalDependencies": { + "@modelcontextprotocol/sdk": "^1.26.0" + }, + "peerDependencies": { + "zod": "^4.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@openai/agents-openai": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@openai/agents-openai/-/agents-openai-0.8.5.tgz", + "integrity": "sha512-cGYmyiVy8ecgf2Vch0L/ekeNo3xuZsuWnRsxyv+w9ai9dgxUifdEQ6G3dtsjMLtmXVHRVGoO7mVBr+tKcilntw==", + "license": "MIT", + "dependencies": { + "@openai/agents-core": "0.8.5", + "debug": "^4.4.0", + "openai": "^6.26.0" + }, + "peerDependencies": { + "zod": "^4.0.0" + } + }, + "node_modules/@openai/agents-realtime": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@openai/agents-realtime/-/agents-realtime-0.8.5.tgz", + "integrity": "sha512-JqKVsR33OvKtTxRp5Ylhw8WfNvJ49ZIhlhMZlSVKqwR2Ks6JuxqFJ0zM9p7JIbTQDSlAZnmnZJv1qlItaildiQ==", + "license": "MIT", + "dependencies": { + "@openai/agents-core": "0.8.5", + "@types/ws": "^8.18.1", + "debug": "^4.4.0", + "ws": "^8.18.1" + }, + "peerDependencies": { + "zod": "^4.0.0" + } + }, + "node_modules/@openai/codex": { + "version": "0.125.0", + "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.125.0.tgz", + "integrity": "sha512-GiE9wlgL95u/5BRirY5d3EaRLU1tu7Y1R09R8lCHHVmcQdSmhS809FdPDWH3gIYHS7ZriAPqXwJ3aLA0WKl40Q==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "codex": "bin/codex.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@openai/codex-darwin-arm64": "npm:@openai/codex@0.125.0-darwin-arm64", + "@openai/codex-darwin-x64": "npm:@openai/codex@0.125.0-darwin-x64", + "@openai/codex-linux-arm64": "npm:@openai/codex@0.125.0-linux-arm64", + "@openai/codex-linux-x64": "npm:@openai/codex@0.125.0-linux-x64", + "@openai/codex-win32-arm64": "npm:@openai/codex@0.125.0-win32-arm64", + "@openai/codex-win32-x64": "npm:@openai/codex@0.125.0-win32-x64" + } + }, + "node_modules/@openai/codex-darwin-arm64": { + "name": "@openai/codex", + "version": "0.125.0-darwin-arm64", + "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.125.0-darwin-arm64.tgz", + "integrity": "sha512-Gn2fHiSO0XgyHp1OSd5DWUTm66Bv9UEuipW5pVEj1E+hWZCOrdqnYttllKFWtRGj5yiKefNX3JIxONgh/ZwlOQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@openai/codex-darwin-x64": { + "name": "@openai/codex", + "version": "0.125.0-darwin-x64", + "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.125.0-darwin-x64.tgz", + "integrity": "sha512-TZ5Lek2X/UXTI9LXFxzarvQaJeuTrqVh4POc7soO/8RclVnCxADnCf15sivxLd5eiFW4t0myGoeVoM4lciRiRg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@openai/codex-linux-arm64": { + "name": "@openai/codex", + "version": "0.125.0-linux-arm64", + "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.125.0-linux-arm64.tgz", + "integrity": "sha512-pPnJoJD6rZ2Iin0zNt/up36bO2/EOp2B+1/rPHu/lSq3PJbT3Fmnfut2kJy5LylXb7bGA2XQbtqOogZzIbnlkA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@openai/codex-linux-x64": { + "name": "@openai/codex", + "version": "0.125.0-linux-x64", + "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.125.0-linux-x64.tgz", + "integrity": "sha512-K2NTTEeBpz/G+N2x17UGWfauRt3So+ir4f+U/60l5PPnYEJB/w3YZrlXo2G9og8Dm9BqtoBAjoPV74sRv9tWWQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@openai/codex-sdk": { + "version": "0.125.0", + "resolved": "https://registry.npmjs.org/@openai/codex-sdk/-/codex-sdk-0.125.0.tgz", + "integrity": "sha512-1xCIHdSbQVF880nJ2aVWdPIsWZbSpKODwuP9y/gvtChDYhYfYEW0DKp2H8ZlctkzIjlzS/WzYmP6ZZPHIvs2Dg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@openai/codex": "0.125.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@openai/codex-win32-arm64": { + "name": "@openai/codex", + "version": "0.125.0-win32-arm64", + "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.125.0-win32-arm64.tgz", + "integrity": "sha512-zxoUakw9oIHIFrAyk400XkkLBJFA6nOym0NDq6sQ/jhdcYraKqNSRCII2nsBwZHk+/4zgUvuk52iuutgysY/rQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@openai/codex-win32-x64": { + "name": "@openai/codex", + "version": "0.125.0-win32-x64", + "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.125.0-win32-x64.tgz", + "integrity": "sha512-ofpOK+OWH5QFuUZ9pTM0d/PcXUXiIP5z5DpRcE9MlucJoyOl4Zy4Nu3NcuHF4YzCkZMQb6x3j0tjDEPHKqNQzw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@opencode-ai/sdk": { + "version": "1.14.30", + "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.14.30.tgz", + "integrity": "sha512-OgPEDvALekHZIjByo/okJ699aLPn+XtsVxgZxUqE8TlzAG7TtskMGFl0fro8O0T2p+nkOT/LstnKGbECvc0+YA==", + "license": "MIT", + "dependencies": { + "cross-spawn": "7.0.6" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", + "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.215.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.215.0.tgz", + "integrity": "sha512-xrFlqhdhUyO8wSRn6DjE0145/HPWSJ5Nm0C7vWua6TdL/FSEAZvEyvdsa9CRXuxo9ebb7j/NEPhEcO62IJ0qUA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.7.1.tgz", + "integrity": "sha512-OPFBYuXEn1E4ja3Y6eeA7O+ZnLBNcXTV5Cgsn1VaqBZ6hC5FnpZPLBNme1LJY8ZtF4aOujPKFoeWN4ik487KuQ==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.1.tgz", + "integrity": "sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.215.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.215.0.tgz", + "integrity": "sha512-k4J9ISeGpb0Bm/wCrlcrbroMFTkiWMrdhNxQGrlktxLy127Yzd4/7nrTawn5d/ApktYTknvdixsE6++34Qfi1w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.0", + "@opentelemetry/otlp-exporter-base": "0.215.0", + "@opentelemetry/otlp-transformer": "0.215.0", + "@opentelemetry/resources": "2.7.0", + "@opentelemetry/sdk-trace-base": "2.7.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/core": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.0.tgz", + "integrity": "sha512-DT12SXVwV2eoJrGf4nnsvZojxxeQo+LlNAsoYGRRObPWTeN6APiqZ2+nqDCQDvQX40eLi1AePONS0onoASp3yQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/resources": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.0.tgz", + "integrity": "sha512-K+oi0hNMv94EpZbnW3eyu2X6SGVpD3O5DhG2NIp65Hc7lhAj9brRXTAVzh3wB82+q3ThakEf7Zd7RsFUqcTc7A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.7.0.tgz", + "integrity": "sha512-Yg9zEXJB50DLVLpsKPk7NmNqlPlS+OvqhJGh0A8oawIOTPOwlm4eXs9BMJV7L79lvEwI+dWtAj+YjTyddV336A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.0", + "@opentelemetry/resources": "2.7.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.215.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.215.0.tgz", + "integrity": "sha512-lHrfbmeLSmesGSkkHiqDwOzfaEMSWXdc7q6UoLfbW8byONCb+bE/zkAr0kapN4US1baT/2nbpNT7Cn9XoB96Vg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.0", + "@opentelemetry/otlp-transformer": "0.215.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/core": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.0.tgz", + "integrity": "sha512-DT12SXVwV2eoJrGf4nnsvZojxxeQo+LlNAsoYGRRObPWTeN6APiqZ2+nqDCQDvQX40eLi1AePONS0onoASp3yQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.215.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.215.0.tgz", + "integrity": "sha512-cWwBvaV+vkXHkSoTYR8hGw+AW03UlgTr6xtrUKOMeum3T+8vffYXIfXu6KY5MLu8O9QtoBKqaKWw9I5xoOepng==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.215.0", + "@opentelemetry/core": "2.7.0", + "@opentelemetry/resources": "2.7.0", + "@opentelemetry/sdk-logs": "0.215.0", + "@opentelemetry/sdk-metrics": "2.7.0", + "@opentelemetry/sdk-trace-base": "2.7.0", + "protobufjs": "^8.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/core": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.0.tgz", + "integrity": "sha512-DT12SXVwV2eoJrGf4nnsvZojxxeQo+LlNAsoYGRRObPWTeN6APiqZ2+nqDCQDvQX40eLi1AePONS0onoASp3yQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/resources": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.0.tgz", + "integrity": "sha512-K+oi0hNMv94EpZbnW3eyu2X6SGVpD3O5DhG2NIp65Hc7lhAj9brRXTAVzh3wB82+q3ThakEf7Zd7RsFUqcTc7A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.7.0.tgz", + "integrity": "sha512-Yg9zEXJB50DLVLpsKPk7NmNqlPlS+OvqhJGh0A8oawIOTPOwlm4eXs9BMJV7L79lvEwI+dWtAj+YjTyddV336A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.0", + "@opentelemetry/resources": "2.7.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.1.tgz", + "integrity": "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.215.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.215.0.tgz", + "integrity": "sha512-y3ucOmphzc4vgBTyIGchs+N/1rkACmoka8QalT2z1LBNM232Z17zMYayHcMl+dgMoOadZ0b72UZv7mDtqy1cFA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.215.0", + "@opentelemetry/core": "2.7.0", + "@opentelemetry/resources": "2.7.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/core": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.0.tgz", + "integrity": "sha512-DT12SXVwV2eoJrGf4nnsvZojxxeQo+LlNAsoYGRRObPWTeN6APiqZ2+nqDCQDvQX40eLi1AePONS0onoASp3yQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/resources": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.0.tgz", + "integrity": "sha512-K+oi0hNMv94EpZbnW3eyu2X6SGVpD3O5DhG2NIp65Hc7lhAj9brRXTAVzh3wB82+q3ThakEf7Zd7RsFUqcTc7A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.7.0.tgz", + "integrity": "sha512-Vd7h95av/LYRsAVN7wbprvvJnHkq7swMXAo7Uad0Uxf9jl6NSReLa0JNivrcc5BVIx/vl2t+cgdVQQbnVhsR9w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.0", + "@opentelemetry/resources": "2.7.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/core": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.0.tgz", + "integrity": "sha512-DT12SXVwV2eoJrGf4nnsvZojxxeQo+LlNAsoYGRRObPWTeN6APiqZ2+nqDCQDvQX40eLi1AePONS0onoASp3yQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/resources": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.0.tgz", + "integrity": "sha512-K+oi0hNMv94EpZbnW3eyu2X6SGVpD3O5DhG2NIp65Hc7lhAj9brRXTAVzh3wB82+q3ThakEf7Zd7RsFUqcTc7A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.7.1.tgz", + "integrity": "sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.1", + "@opentelemetry/resources": "2.7.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.7.1.tgz", + "integrity": "sha512-pCpQxU68lV+I9s9svqMyVu5iHdDDUnqUpSxqwyCU8A9ejEsSnMPCbearwsUO4yk08ZJzAIUCFuReMdVQvHrdvg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "2.7.1", + "@opentelemetry/core": "2.7.1", + "@opentelemetry/sdk-trace-base": "2.7.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.40.0.tgz", + "integrity": "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@playwright/browser-chromium": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/@playwright/browser-chromium/-/browser-chromium-1.59.1.tgz", + "integrity": "sha512-XDwr0qOrzLXAuBAzg4WO/xctVMb+ldJ54yz9KCpFu8G8MVJzUVFO6BvK1tBtBl4DIoFcoFRKHgUGZT+8wOC8BQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "playwright-core": "1.59.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@posthog/core": { + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.23.1.tgz", + "integrity": "sha512-GViD5mOv/mcbZcyzz3z9CS0R79JzxVaqEz4sP5Dsea178M/j3ZWe6gaHDZB9yuyGfcmIMQ/8K14yv+7QrK4sQQ==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.6" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.1.tgz", + "integrity": "sha512-mnzgDV26ueAvk7rsbt9L7bE0SuAoqyuys/sMMrmVcN5x9VsxpcG3rqAUSgDyLp0UZlmNfIbQ4fHfCtreVBk8Ew==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz", + "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@redis/bloom": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.12.1.tgz", + "integrity": "sha512-PUUfv+ms7jgPSBVoo/DN4AkPHj4D5TZSd6SbJX7egzBplkYUcKmHRE8RKia7UtZ8bSQbLguLvxVO+asKtQfZWA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 18.19.0" + }, + "peerDependencies": { + "@redis/client": "^5.12.1" + } + }, + "node_modules/@redis/client": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.12.1.tgz", + "integrity": "sha512-7aPGWeqA3uFm43o19umzdl16CEjK/JQGtSXVPevplTaOU3VJA/rseBC1QvYUz9lLDIMBimc4SW/zrW4S89BaCA==", + "license": "MIT", + "optional": true, + "dependencies": { + "cluster-key-slot": "1.1.2" + }, + "engines": { + "node": ">= 18.19.0" + }, + "peerDependencies": { + "@node-rs/xxhash": "^1.1.0", + "@opentelemetry/api": ">=1 <2" + }, + "peerDependenciesMeta": { + "@node-rs/xxhash": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + } + } + }, + "node_modules/@redis/json": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-5.12.1.tgz", + "integrity": "sha512-eOze75esLve4vfqDel7aMX08CNaiLLQS2fV8mpRN9NxPe1rVR4vQyYiW/OgtGUysF6QOr9ANhfxABKNOJfXdKg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 18.19.0" + }, + "peerDependencies": { + "@redis/client": "^5.12.1" + } + }, + "node_modules/@redis/search": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-5.12.1.tgz", + "integrity": "sha512-ItlxbxC9cKI6IU1TLWoczwJCRb6TdmkEpWv05UrPawqaAnWGRu3rcIqsc5vN483T2fSociuyV1UkWIL5I4//2w==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 18.19.0" + }, + "peerDependencies": { + "@redis/client": "^5.12.1" + } + }, + "node_modules/@redis/time-series": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-5.12.1.tgz", + "integrity": "sha512-c6JL6E3EcZJuNqKFz+KM+l9l5mpcQiKvTwgA3blt5glWJ8hjDk0yeHN3beE/MpqYIQ8UEX44ItQzgkE/gCBELQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 18.19.0" + }, + "peerDependencies": { + "@redis/client": "^5.12.1" + } + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", + "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, + "node_modules/@simple-git/args-pathspec": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@simple-git/args-pathspec/-/args-pathspec-1.0.3.tgz", + "integrity": "sha512-ngJMaHlsWDTfjyq9F3VIQ8b7NXbBLq5j9i5bJ6XLYtD6qlDXT7fdKY2KscWWUF8t18xx052Y/PUO1K1TRc9yKA==", + "license": "MIT" + }, + "node_modules/@simple-git/argv-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@simple-git/argv-parser/-/argv-parser-1.1.1.tgz", + "integrity": "sha512-Q9lBcfQ+VQCpQqGJFHe5yooOS5hGdLFFbJ5R+R5aDsnkPCahtn1hSkMcORX65J2Z5lxSkD0lQorMsncuBQxYUw==", + "license": "MIT", + "dependencies": { + "@simple-git/args-pathspec": "^1.0.3" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@slack/logger": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@slack/logger/-/logger-4.0.1.tgz", + "integrity": "sha512-6cmdPrV/RYfd2U0mDGiMK8S7OJqpCTm7enMLRR3edccsPX8j7zXTLnaEF4fhxxJJTAIOil6+qZrnUPTuaLvwrQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": ">=18" + }, + "engines": { + "node": ">= 18", + "npm": ">= 8.6.0" + } + }, + "node_modules/@slack/types": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/@slack/types/-/types-2.20.1.tgz", + "integrity": "sha512-eWX2mdt1ktpn8+40iiMc404uGrih+2fxiky3zBcPjtXKj6HLRdYlmhrPkJi7JTJm8dpXR6BWVWEDBXtaWMKD6A==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12.13.0", + "npm": ">= 6.12.0" + } + }, + "node_modules/@slack/web-api": { + "version": "7.15.1", + "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-7.15.1.tgz", + "integrity": "sha512-y+TAF7TszcmFzbVtBkFqAdBwKSoD+8shkNxhp4WIfFwXmCKdFje9WD6evROApPa2FTy1v1uc9yBaJs3609PPgg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@slack/logger": "^4.0.1", + "@slack/types": "^2.20.1", + "@types/node": ">=18", + "@types/retry": "0.12.0", + "axios": "^1.15.0", + "eventemitter3": "^5.0.1", + "form-data": "^4.0.4", + "is-electron": "2.2.2", + "is-stream": "^2", + "p-queue": "^6", + "p-retry": "^4", + "retry": "^0.13.1" + }, + "engines": { + "node": ">= 18", + "npm": ">= 8.6.0" + } + }, + "node_modules/@smithy/chunked-blob-reader": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.2.tgz", + "integrity": "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/chunked-blob-reader-native": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.3.tgz", + "integrity": "sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/util-base64": "^4.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.17", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.17.tgz", + "integrity": "sha512-TzDZcAnhTyAHbXVxWZo7/tEcrIeFq20IBk8So3OLOetWpR8EwY/yEqBMBFaJMeyEiREDq4NfEl+qO3OAUD+vbQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.23.17", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.17.tgz", + "integrity": "sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.14.tgz", + "integrity": "sha512-Au28zBN48ZAoXdooGUHemuVBrkE+Ie6RPmGNIAJsFqj33Vhb6xAgRifUydZ2aY+M+KaMAETAlKk5NC5h1G7wpg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/node-config-provider": "^4.3.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.14.tgz", + "integrity": "sha512-erZq0nOIpzfeZdCyzZjdJb4nVSKLUmSkaQUVkRGQTXs30gyUGeKnrYEg+Xe1W5gE3aReS7IgsvANwVPxSzY6Pw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.14.1", + "@smithy/util-hex-encoding": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.14.tgz", + "integrity": "sha512-8IelTCtTctWRbb+0Dcy+C0aICh1qa0qWXqgjcXDmMuCvPJRnv26hiDZoAau2ILOniki65mCPKqOQs/BaWvO4CQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.14.tgz", + "integrity": "sha512-sqHiHpYRYo3FJlaIxD1J8PhbcmJAm7IuM16mVnwSkCToD7g00IBZzKuiLNMGmftULmEUX6/UAz8/NN5uMP8bVA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.14.tgz", + "integrity": "sha512-Ht/8BuGlKfFTy0H3+8eEu0vdpwGztCnaLLXtpXNdQqiR7Hj4vFScU3T436vRAjATglOIPjJXronY+1WxxNLSiw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.14.tgz", + "integrity": "sha512-lWyt4T2XQZUZgK3tQ3Wn0w3XBvZsK/vjTuJl6bXbnGZBHH0ZUSONTYiK9TgjTTzU54xQr3DRFwpjmhp0oLm3gg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/eventstream-codec": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.17", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.17.tgz", + "integrity": "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/querystring-builder": "^4.2.14", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-blob-browser": { + "version": "4.2.15", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.15.tgz", + "integrity": "sha512-0PJ4Al3fg2nM4qKrAIxyNcApgqHAXcBkN8FeizOz69z0rb26uZ6lMESYtxegaTlXB5Hj84JfwMPavMrwDMjucA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/chunked-blob-reader": "^5.2.2", + "@smithy/chunked-blob-reader-native": "^4.2.3", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.14.tgz", + "integrity": "sha512-8ZBDY2DD4wr+GGjTpPtiglEsqr0lUP+KHqgZcWczFf6qeZ/YRjMIOoQWVQlmwu7EtxKTd8YXD8lblmYcpBIA1g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-stream-node": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.14.tgz", + "integrity": "sha512-tw4GANWkZPb6+BdD4Fgucqzey2+r73Z/GRo9zklsCdwrnxxumUV83ZIaBDdudV4Ylazw3EPTiJZhpX42105ruQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.14.tgz", + "integrity": "sha512-c21qJiTSb25xvvOp+H2TNZzPCngrvl5vIPqPB8zQ/DmJF4QWXO19x1dWfMJZ6wZuuWUPPm0gV8C0cU3+ifcWuw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", + "integrity": "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/md5-js": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.14.tgz", + "integrity": "sha512-V2v0vx+h0iUSNG1Alt+GNBMSLGCrl9iVsdd+Ap67HPM9PN479x12V8LkuMoKImNZxn3MXeuyUjls+/7ZACZghA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.14.tgz", + "integrity": "sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.4.32", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.32.tgz", + "integrity": "sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-middleware": "^4.2.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.5.7.tgz", + "integrity": "sha512-bRt6ZImqVSeTk39Nm81K20ObIiAZ3WefY7G6+iz/0tZjs4dgRRjvRX2sgsH+zi6iDCRR/aQvQofLKxxz4rPBZg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/service-error-classification": "^4.3.1", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.2.20", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.20.tgz", + "integrity": "sha512-Lx9JMO9vArPtiChE3wbEZ5akMIDQpWQtlu90lhACQmNOXcGXRbaDywMHDzuDZ2OkZzP+9wQfZi3YJT9F67zTQQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.14.tgz", + "integrity": "sha512-2dvkUKLuFdKsCRmOE4Mn63co0Djtsm+JMh0bYZQupN1pJwMeE8FmQmRLLzzEMN0dnNi7CDCYYH8F0EVwWiPBeA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.14.tgz", + "integrity": "sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.6.1.tgz", + "integrity": "sha512-iB+orM4x3xrr57X3YaXazfKnntl0LHlZB1kcXSGzMV1Tt0+YwEjGlbjk/44qEGtBzXAz6yFDzkYTKSV6Pj2HUg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/querystring-builder": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.14.tgz", + "integrity": "sha512-WuM31CgfsnQ/10i7NYr0PyxqknD72Y5uMfUMVSniPjbEPceiTErb4eIqJQ+pdxNEAUEWrewrGjIRjVbVHsxZiQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.14.tgz", + "integrity": "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.14.tgz", + "integrity": "sha512-XYA5Z0IqTeF+5XDdh4BBmSA0HvbgVZIyv4cmOoUheDNR57K1HgBp9ukUMx3Cr3XpDHHpLBnexPE3LAtDsZkj2A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "@smithy/util-uri-escape": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.14.tgz", + "integrity": "sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.3.1.tgz", + "integrity": "sha512-aUQuDGh760ts/8MU+APjIZhlLPKhIIfqyzZaJikLEIMrdxFvxuLYD0WxWzaYWpmLbQlXDe9p7EWM3HsBe0K6Gw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.9.tgz", + "integrity": "sha512-495/V2I15SHgedSJoDPD23JuSfKAp726ZI1V0wtjB07Wh7q/0tri/0e0DLefZCHgxZonrGKt/OCTpAtP1wE1kQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.14.tgz", + "integrity": "sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-uri-escape": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.12.13", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.13.tgz", + "integrity": "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-stream": "^4.5.25", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.1.tgz", + "integrity": "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.14.tgz", + "integrity": "sha512-p06BiBigJ8bTA3MgnOfCtDUWnAMY0YfedO/GRpmc7p+wg3KW8vbXy1xwSu5ASy0wV7rRYtlfZOIKH4XqfhjSQQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/querystring-parser": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.2.tgz", + "integrity": "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.2.tgz", + "integrity": "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.3.tgz", + "integrity": "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", + "integrity": "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/is-array-buffer": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.2.tgz", + "integrity": "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.3.49", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.49.tgz", + "integrity": "sha512-a5bNrdiONYB/qE2BuKegvUMd/+ZDwdg4vsNuuSzYE8qs2EYAdK9CynL+Rzn29PbPiUqoz/cbpRbcLzD5lEevHw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/property-provider": "^4.2.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.2.54", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.54.tgz", + "integrity": "sha512-g1cvrJvOnzeJgEdf7AE4luI7gp6L8weE0y9a9wQUSGtjb8QRHDbCJYuE4Sy0SD9N8RrnNPFsPltAz/OSoBR9Zw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/config-resolver": "^4.4.17", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.4.2.tgz", + "integrity": "sha512-a55Tr+3OKld4TTtnT+RhKOQHyPxm3j/xL4OR83WBUhLJaKDS9dnJ7arRMOp3t31dcLhApwG9bgvrRXBHlLdIkg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", + "integrity": "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.14.tgz", + "integrity": "sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.3.6.tgz", + "integrity": "sha512-p6/FO1n2KxMeQyna067i0uJ6TSbb165ZhnRtCpWh4Foxqbfc6oW+XITaL8QkFJj3KFnDe2URt4gOhgU06EP9ew==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/service-error-classification": "^4.3.1", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.5.25", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.25.tgz", + "integrity": "sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", + "integrity": "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.3.0.tgz", + "integrity": "sha512-JyjYmLAfS+pdxF92o4yLgEoy0zhayKTw73FU1aofLWwLcJw7iSqIY2exGmMTrl/lmZugP5p/zxdFSippJDfKWA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.2.tgz", + "integrity": "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@so-ric/colorspace": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz", + "integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==", + "license": "MIT", + "dependencies": { + "color": "^5.0.2", + "text-hex": "1.0.x" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/@swc/core": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.32.tgz", + "integrity": "sha512-/eWL0n43D64QWEUHLtTE+jDqjkJhyidjkDhv6f0uJohOUAhywxQ9wXYp845DNNds0JpCdI4Uo0a9bl+vbXf+ew==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.26" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.15.32", + "@swc/core-darwin-x64": "1.15.32", + "@swc/core-linux-arm-gnueabihf": "1.15.32", + "@swc/core-linux-arm64-gnu": "1.15.32", + "@swc/core-linux-arm64-musl": "1.15.32", + "@swc/core-linux-ppc64-gnu": "1.15.32", + "@swc/core-linux-s390x-gnu": "1.15.32", + "@swc/core-linux-x64-gnu": "1.15.32", + "@swc/core-linux-x64-musl": "1.15.32", + "@swc/core-win32-arm64-msvc": "1.15.32", + "@swc/core-win32-ia32-msvc": "1.15.32", + "@swc/core-win32-x64-msvc": "1.15.32" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.32.tgz", + "integrity": "sha512-/YWMvJDPu+AAwuUsM2G+DNQ/7zhodURGzdQyewEqcvgklAdDHs3LwQmLLnyn6SJl8DT8UOxkbzK+D1PmPeelRg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.32.tgz", + "integrity": "sha512-KOTXJXdAhWL+hZ77MYP3z+4pcMFaQhQ74yqyN1uz093q0YnbxpqMtYpPISbYvMHzVRNNx5kN+9RZAXEaadhWVA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.32.tgz", + "integrity": "sha512-oOoxLweljlc0A4X8ybsgxV7cVaYTwBOg2iMDJcFR3Sr48C+lsv9VzSmqdK/IVIXF4W4GjLc3VqTAdSMXlfVLuQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.32.tgz", + "integrity": "sha512-oDzEkdl6D6BAWdMtU5KGO7y3HR5fJcvByNLyEk9+ugj8nP5Ovb7P4kBcStBXc4MPExFGQryehiINMlmY8HlclA==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.32.tgz", + "integrity": "sha512-omcqjoZP/b8D8PuczVoRwJieC6ibj7qIxTftNYokz4/aSmKFHvsd7nIFfPk5ZvtzncbH4AY7+Dkr/Lp2gWxYeA==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.32.tgz", + "integrity": "sha512-KGkTMyz/Tbn3PBNu0AVZ4GTDFKnICrYcTiNPZq8DrvK42pnFsf3GNDrIG9E5AtQlTmC0YigkWKmu0eMcfTrmgA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.32.tgz", + "integrity": "sha512-G3Aa4tVS/3OGZBkoNIwUF9F6RAy+Osb4GOlo62SinLmDiErz/ykmM7KH0wkz6l9kM8jJq1HyAM6atJTUEbBk7g==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.32.tgz", + "integrity": "sha512-ERsjfGcj6CBmj3vJnGDO8m8rTvw6RqMcWo1dogOtNx3/+/0+NNpJiXDobJrr1GwInI/BHAEkvSFIH6d2LqPcUQ==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.32.tgz", + "integrity": "sha512-N4Ggahe/8SUbTX50P6EdhbW9YWcgbZVb52R4cq6MK+zsoMjRq7rGvV5ztA05QnbaCYqMYx8rTY7KAIA3Crdo4Q==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.32.tgz", + "integrity": "sha512-01yN0o9jvo8xBTP12aPK2wW8b41jmOlGbDDlAnoynotc4pO6xA0zby9f1z6j++qXDpGBttLySq1omgVrlQKYcw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.32.tgz", + "integrity": "sha512-fLagI9XZYNpTcmlqAcp3KBtmj7E19WCmYD80Jxj1Kn5tGNa7yxNLd3NNdWxuZGUPl5iC0/KqZru7g08gF6Fsrw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.32.tgz", + "integrity": "sha512-gbc2bQ/T2CiR+w0OvcVKwLOFAcPZBvmWmolbwpg1E8UrpeC03DGtyMUApOHNXNYWA3SHFrYXCQtosrcMza1YFg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@swc/types": { + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.26.tgz", + "integrity": "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@tokenizer/inflate": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "^4.4.3", + "token-types": "^6.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT", + "optional": true + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "license": "MIT", + "optional": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "license": "MIT", + "optional": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "license": "MIT", + "optional": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/node": { + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pegjs": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/@types/pegjs/-/pegjs-0.10.6.tgz", + "integrity": "sha512-eLYXDbZWXh2uxf+w8sXS8d6KSoXTswfps6fvCUuVAGN8eRpfe7h9eSRydxiSJvo9Bf+GzifsDOr9TMQlmJdmkw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", + "license": "MIT" + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/webidl-conversions": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.5.tgz", + "integrity": "sha512-yURCknZhvywvQItHMMmFSo+fq5arCUIyz/CVk7jD89MSai7dkaX8ufjCWp3NttLojoTVbcE72ri+be/TnEbMHw==", + "license": "MIT", + "optional": true, + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@vercel/oidc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.2.0.tgz", + "integrity": "sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==", + "license": "Apache-2.0", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz", + "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14.6" + } + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "license": "MIT" + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "optional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "license": "MIT", + "optional": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.17.tgz", + "integrity": "sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/afinn-165": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/afinn-165/-/afinn-165-2.0.2.tgz", + "integrity": "sha512-mJ/RLUfpXfQA6bzugv+bBsc/QYkVrKaLYeS8fWBpKbTCsonv4iuV9ET0fgReEunm9vKLkaNgnekuSNlTC3WQ1Q==", + "license": "MIT", + "optional": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/afinn-165-financialmarketnews": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/afinn-165-financialmarketnews/-/afinn-165-financialmarketnews-3.0.0.tgz", + "integrity": "sha512-0g9A1S3ZomFIGDTzZ0t6xmv4AuokBvBmpes8htiyHpH7N4xDmvSQL6UxL/Zcs2ypRb3VwgCscaD8Q3zEawKYhw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/ai": { + "version": "6.0.172", + "resolved": "https://registry.npmjs.org/ai/-/ai-6.0.172.tgz", + "integrity": "sha512-o12q2SDlrN4btPU2FkFSVEeZiKfQuSbDFixXH8I7AE/zuCXMbN9ilaPThdoAc8mS9+QnhUGy8cSP0IgT3Q+p0A==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/gateway": "3.0.107", + "@ai-sdk/provider": "3.0.10", + "@ai-sdk/provider-utils": "4.0.25", + "@opentelemetry/api": "1.9.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/ai/node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/apparatus": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/apparatus/-/apparatus-0.0.10.tgz", + "integrity": "sha512-KLy/ugo33KZA7nugtQ7O0E1c8kQ52N3IvD/XgIh4w/Nr28ypfkwDfA67F1ev4N1m5D+BOk1+b2dEJDfpj/VvZg==", + "license": "MIT", + "optional": true, + "dependencies": { + "sylvester": ">= 0.0.8" + }, + "engines": { + "node": ">=0.2.6" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "license": "MIT", + "optional": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "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/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT", + "optional": true + }, + "node_modules/auto-bind": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz", + "integrity": "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/axios": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", + "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/basic-ftp": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz", + "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/better-sqlite3": { + "version": "12.9.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.9.0.tgz", + "integrity": "sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + }, + "engines": { + "node": "20.x || 22.x || 23.x || 24.x || 25.x" + } + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "license": "Unlicense", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-3.1.0.tgz", + "integrity": "sha512-Jvvd9hy1w+xUad8+ckQsWA/V1AoyubOvqn0aygjMOVM4BfIaRav1NFS3LsTSDaV4n4FtcCtQXvzep1E6MboqwQ==", + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/binaryextensions": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-6.11.0.tgz", + "integrity": "sha512-sXnYK/Ij80TO3lcqZVV2YgfKN5QjUWIRk/XSm2J/4bd/lPko3lvk0O4ZppH6m+6hB2/GTu+ptNwVFe1xh+QLQw==", + "license": "Artistic-2.0", + "dependencies": { + "editions": "^6.21.0" + }, + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT", + "optional": true + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT", + "optional": true + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT", + "optional": true + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/bson": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-7.2.0.tgz", + "integrity": "sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cache-manager": { + "version": "7.2.8", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-7.2.8.tgz", + "integrity": "sha512-0HDaDLBBY/maa/LmUVAr70XUOwsiQD+jyzCBjmUErYZUKdMS9dT59PqW59PpVqfGM7ve6H0J6307JTpkCYefHQ==", + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.3.3", + "keyv": "^5.5.5" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "license": "MIT" + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-progress": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz", + "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-spinners": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", + "integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==", + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-truncate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "license": "MIT", + "dependencies": { + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "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": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/code-excerpt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", + "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", + "license": "MIT", + "dependencies": { + "convert-to-spaces": "^2.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/color": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-5.0.3.tgz", + "integrity": "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==", + "license": "MIT", + "dependencies": { + "color-convert": "^3.1.3", + "color-string": "^2.1.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/color-convert": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz", + "integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==", + "license": "MIT", + "dependencies": { + "color-name": "^2.0.0" + }, + "engines": { + "node": ">=14.6" + } + }, + "node_modules/color-name": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz", + "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==", + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/color-string": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-2.1.4.tgz", + "integrity": "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==", + "license": "MIT", + "dependencies": { + "color-name": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "optional": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/complex.js": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.3.tgz", + "integrity": "sha512-UrQVSUur14tNX6tiP4y8T4w4FeJAX3bi2cIv0pu/DTLFNxoq7z2Yh83Vfzztj6Px3X/lubqQ9IrPp7Bpn6p4MQ==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-to-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", + "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT", + "optional": true + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "license": "MIT", + "optional": true + }, + "node_modules/cross-fetch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "license": "MIT", + "optional": true, + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/csv-parse": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-6.2.1.tgz", + "integrity": "sha512-LRLMV+UCyfMokp8Wb411duBf1gaBKJfOfBWU9eHMJ+b+cJYZsNu3AFmjJf3+yPGd59Exz1TsMjaSFyxnYB9+IQ==", + "license": "MIT" + }, + "node_modules/csv-stringify": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.7.0.tgz", + "integrity": "sha512-UdtziYp5HuTz7e5j8Nvq+a/3HQo+2/aJZ9xntNTpmRRIg/3YYqDVgiS9fvAhtNbnyfbv2ZBe0bqCHqzhE7FqWQ==", + "license": "MIT" + }, + "node_modules/data-uri-to-buffer": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-8.0.0.tgz", + "integrity": "sha512-6UHfyCux51b8PTGDgveqtz1tvphBku5DrMKKJbFAZAJOI2zsjDpDoYE1+QGj7FOMS4BdTFNJsJiR3zEB0xH0yQ==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/debounce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-3.0.0.tgz", + "integrity": "sha512-64byRbF0/AirwbuHqB3/ZpMG9/nckDa6ZA0yd6UnaQNwbbemCOwvz2sL5sjXLHhZHADyiwLm0M5qMhltUUx+TA==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "license": "MIT", + "optional": true, + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/degenerator": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-7.0.1.tgz", + "integrity": "sha512-ABErK0IefDSyHjlPH7WUEenIAX2rPPnrDcDM+TS3z3+zu9TfyKKi07BQM+8rmxpdE2y1v5fjjdoAS/x4D2U60w==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "quickjs-wasi": "^2.2.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT", + "optional": true + }, + "node_modules/diff": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/drizzle-orm": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.2.tgz", + "integrity": "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@aws-sdk/client-rds-data": ">=3", + "@cloudflare/workers-types": ">=4", + "@electric-sql/pglite": ">=0.2.0", + "@libsql/client": ">=0.10.0", + "@libsql/client-wasm": ">=0.10.0", + "@neondatabase/serverless": ">=0.10.0", + "@op-engineering/op-sqlite": ">=2", + "@opentelemetry/api": "^1.4.1", + "@planetscale/database": ">=1.13", + "@prisma/client": "*", + "@tidbcloud/serverless": "*", + "@types/better-sqlite3": "*", + "@types/pg": "*", + "@types/sql.js": "*", + "@upstash/redis": ">=1.34.7", + "@vercel/postgres": ">=0.8.0", + "@xata.io/client": "*", + "better-sqlite3": ">=7", + "bun-types": "*", + "expo-sqlite": ">=14.0.0", + "gel": ">=2", + "knex": "*", + "kysely": "*", + "mysql2": ">=2", + "pg": ">=8", + "postgres": ">=3", + "sql.js": ">=1", + "sqlite3": ">=5" + }, + "peerDependenciesMeta": { + "@aws-sdk/client-rds-data": { + "optional": true + }, + "@cloudflare/workers-types": { + "optional": true + }, + "@electric-sql/pglite": { + "optional": true + }, + "@libsql/client": { + "optional": true + }, + "@libsql/client-wasm": { + "optional": true + }, + "@neondatabase/serverless": { + "optional": true + }, + "@op-engineering/op-sqlite": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@prisma/client": { + "optional": true + }, + "@tidbcloud/serverless": { + "optional": true + }, + "@types/better-sqlite3": { + "optional": true + }, + "@types/pg": { + "optional": true + }, + "@types/sql.js": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/postgres": { + "optional": true + }, + "@xata.io/client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "bun-types": { + "optional": true + }, + "expo-sqlite": { + "optional": true + }, + "gel": { + "optional": true + }, + "knex": { + "optional": true + }, + "kysely": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "postgres": { + "optional": true + }, + "prisma": { + "optional": true + }, + "sql.js": { + "optional": true + }, + "sqlite3": { + "optional": true + } + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT", + "optional": true + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/editions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/editions/-/editions-6.22.0.tgz", + "integrity": "sha512-UgGlf8IW75je7HZjNDpJdCv4cGJWIi6yumFdZ0R7A8/CIhQiWUjyGLCxdHpd8bmyD1gnkfUNK0oeOXqUS2cpfQ==", + "license": "Artistic-2.0", + "dependencies": { + "version-range": "^4.15.0" + }, + "engines": { + "ecmascript": ">= es5", + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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/engine.io": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.7.tgz", + "integrity": "sha512-DgOngfDKM2EviOH3Mr9m7ks1q8roetLy/IMmYthAYzbpInMbYc/GS+fWFA3rl1gvwKVsQrVV61fo5emD1y3OJQ==", + "license": "MIT", + "dependencies": { + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "@types/ws": "^8.5.12", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.4.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.18.3" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.4.tgz", + "integrity": "sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.18.3", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "optional": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-toolkit": { + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.46.1.tgz", + "integrity": "sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "license": "MIT", + "optional": true + }, + "node_modules/es6-promisify": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-7.0.0.tgz", + "integrity": "sha512-ginqzK3J90Rd4/Yz7qRrqUeIpe3TwSXTPPZtPne7tGBPeAaQiU8qt4fpKApnxHcq1AwtUdHVg5P77x/yrggG8Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "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/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/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT", + "optional": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-1.1.2.tgz", + "integrity": "sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/eventsource/node_modules/eventsource-parser": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.8.tgz", + "integrity": "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.4.1.tgz", + "integrity": "sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQCm+rFvLsBH6w4xcXWTcliS8La5EPRN3p9wzItqBwJrfNw==", + "license": "MIT", + "dependencies": { + "ip-address": "10.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/exsolve": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "node_modules/fast-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "license": "MIT" + }, + "node_modules/fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "license": "MIT", + "dependencies": { + "fast-string-truncated-width": "^3.0.2" + } + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-wrap-ansi": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.0.tgz", + "integrity": "sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==", + "license": "MIT", + "dependencies": { + "fast-string-width": "^3.0.2" + } + }, + "node_modules/fast-xml-builder": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz", + "integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "path-expression-matcher": "^1.1.3" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.2.tgz", + "integrity": "sha512-P7oW7tLbYnhOLQk/Gv7cZgzgMPP/XN03K02/Jy6Y/NHzyIAIpxuZIM/YqAkfiXFPxA2CTm7NtCijK9EDu09u2w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.5", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "license": "MIT" + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/fetch-retry": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-5.0.6.tgz", + "integrity": "sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==", + "license": "MIT", + "optional": true + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT", + "optional": true + }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-type": { + "version": "21.3.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz", + "integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/flatbuffers": { + "version": "25.9.23", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz", + "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "optional": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "license": "MIT", + "optional": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gaxios": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", + "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/gaxios/node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/gaxios/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/gcp-metadata": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", + "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/get-uri": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-8.0.0.tgz", + "integrity": "sha512-CqtZlMKvfJeY0Zxv8wazDwXmSKmnMnsmNy8j8+wudi8EyG/pMUB1NqHc+Tv1QaNtpYsK9nOYjb7r7Ufu32RPSw==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.2.0", + "data-uri-to-buffer": "8.0.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/google-auth-library": { + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz", + "integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^7.1.4", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/google-logging-utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/googleapis-common": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-8.0.1.tgz", + "integrity": "sha512-eCzNACUXPb1PW5l0ULTzMHaL/ltPRADoPgjBlT8jWsTbxkCp6siv+qKJ/1ldaybCthGwsYFYallF7u9AkU4L+A==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "gaxios": "^7.0.0-rc.4", + "google-auth-library": "^10.1.0", + "qs": "^6.7.0", + "url-template": "^2.0.8" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC", + "optional": true + }, + "node_modules/guid-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", + "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==", + "license": "ISC", + "optional": true + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "optional": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hashery": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", + "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", + "license": "MIT", + "dependencies": { + "hookified": "^1.15.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hono": { + "version": "4.12.16", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.16.tgz", + "integrity": "sha512-jN0ZewiNAWSe5khM3EyCmBb250+b40wWbwNILNfEvq84VREWwOIkuUsFONk/3i3nqkz7Oe1PcpM2mwQEK2L9Kg==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/hookified": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", + "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "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", + "optional": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-status-codes": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", + "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==", + "license": "MIT", + "optional": true + }, + "node_modules/http-z": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/http-z/-/http-z-8.1.1.tgz", + "integrity": "sha512-4rEIu4SljSAs+lgCzzskyNdYllteGIHdnMBsu9MqafivyPAofSmCsrRjHQgxLs0BoPkUJBa7Ld6rXP32SPI8Fg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "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/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/ibm-cloud-sdk-core": { + "version": "5.4.12", + "resolved": "https://registry.npmjs.org/ibm-cloud-sdk-core/-/ibm-cloud-sdk-core-5.4.12.tgz", + "integrity": "sha512-aBi9U/HENeKOpI1pzFp8/gQY/ao2DeJoCH/KZxP0Vk6864k5e2JYmbU03Jlbc3qxjsCwdNmmCsK8BgSqHzYjSg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@types/debug": "^4.1.12", + "@types/node": "^18.19.80", + "@types/tough-cookie": "^4.0.0", + "axios": "1.15.2", + "camelcase": "^6.3.0", + "debug": "^4.3.4", + "dotenv": "^16.4.5", + "extend": "3.0.2", + "file-type": "^21.3.2", + "form-data": "^4.0.4", + "isstream": "0.1.2", + "jsonwebtoken": "^9.0.3", + "load-esm": "^1.0.3", + "mime-types": "2.1.35", + "retry-axios": "^2.6.0", + "tough-cookie": "^4.1.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/ibm-cloud-sdk-core/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/ibm-cloud-sdk-core/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ibm-cloud-sdk-core/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "optional": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/ink": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/ink/-/ink-6.8.0.tgz", + "integrity": "sha512-sbl1RdLOgkO9isK42WCZlJCFN9hb++sX9dsklOvfd1YQ3bQ2AiFu12Q6tFlr0HvEUvzraJntQCCpfEoUe9DSzA==", + "license": "MIT", + "dependencies": { + "@alcalzone/ansi-tokenize": "^0.2.4", + "ansi-escapes": "^7.3.0", + "ansi-styles": "^6.2.1", + "auto-bind": "^5.0.1", + "chalk": "^5.6.0", + "cli-boxes": "^3.0.0", + "cli-cursor": "^4.0.0", + "cli-truncate": "^5.1.1", + "code-excerpt": "^4.0.0", + "es-toolkit": "^1.39.10", + "indent-string": "^5.0.0", + "is-in-ci": "^2.0.0", + "patch-console": "^2.0.0", + "react-reconciler": "^0.33.0", + "scheduler": "^0.27.0", + "signal-exit": "^3.0.7", + "slice-ansi": "^8.0.0", + "stack-utils": "^2.0.6", + "string-width": "^8.1.1", + "terminal-size": "^4.0.1", + "type-fest": "^5.4.1", + "widest-line": "^6.0.0", + "wrap-ansi": "^9.0.0", + "ws": "^8.18.0", + "yoga-layout": "~3.2.1" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@types/react": ">=19.0.0", + "react": ">=19.0.0", + "react-devtools-core": ">=6.1.2" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react-devtools-core": { + "optional": true + } + } + }, + "node_modules/ink/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ink/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/ink/node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/strip-ansi": { + "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": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT" + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "optional": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-electron": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", + "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==", + "license": "MIT", + "optional": true + }, + "node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-in-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-2.0.0.tgz", + "integrity": "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==", + "license": "MIT", + "bin": { + "is-in-ci": "cli.js" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT", + "optional": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "license": "MIT", + "optional": true + }, + "node_modules/istextorbinary": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-9.5.0.tgz", + "integrity": "sha512-5mbUj3SiZXCuRf9fT3ibzbSSEWiy63gFfksmGfdOzujPjW3k+z8WvIBxcJHBoQNlaZaiyB25deviif2+osLmLw==", + "license": "Artistic-2.0", + "dependencies": { + "binaryextensions": "^6.11.0", + "editions": "^6.21.0", + "textextensions": "^6.11.0" + }, + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "license": "MIT" + }, + "node_modules/jks-js": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/jks-js/-/jks-js-1.1.6.tgz", + "integrity": "sha512-ZZR0n9/mwy4swJuZxCl/NiUfuiNao5SAU7m/TqVnxU6Gs3QrmFsbkUCQh9gb7xb1graX2iuQT3MUVyT8k5SKIQ==", + "license": "MIT", + "dependencies": { + "node-forge": "^1.4.0", + "node-int64": "^0.4.0", + "node-rsa": "^1.1.1" + } + }, + "node_modules/jose": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", + "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-rouge": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/js-rouge/-/js-rouge-3.2.0.tgz", + "integrity": "sha512-2dvY28iFq5NcwxPNzc2zMgLVJED843m6CnKrCy0jYnOKd+QQhdkxI1wmdQspbcOAggo3K3gUZfhTSwmM+lWoBA==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-to-ts": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", + "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "ts-algebra": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC", + "optional": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", + "optional": true, + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kareem": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-3.3.0.tgz", + "integrity": "sha512-kpSuLD3/7RenBnjnJdOHXCKC8dTd1JzeOiJhN0necWWci6cC+qX+VuwPnMVgb+a4+KNJSfgqahpnfWaeDXCimw==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/keyv-file": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/keyv-file/-/keyv-file-5.3.3.tgz", + "integrity": "sha512-uCFUhiVYf+BcA6DP4smhnRLOR4yzUUA15yJSk4/rP5oAPnF3MpfajejwvSV8l+okm+EGiW4IHP3gn+xahpvZcQ==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1", + "tslib": "^1.14.1" + } + }, + "node_modules/keyv-file/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "license": "MIT" + }, + "node_modules/langfuse": { + "version": "3.38.20", + "resolved": "https://registry.npmjs.org/langfuse/-/langfuse-3.38.20.tgz", + "integrity": "sha512-MAmBAASSzJtmK1O9HQegA1mFsQhT8Yf+OJRGvE7FXkyv3g/eiBE0glLD0Ohg3pkxhoPdggM5SejK7ue9ctlaMA==", + "license": "MIT", + "optional": true, + "dependencies": { + "langfuse-core": "^3.38.20" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/langfuse-core": { + "version": "3.38.20", + "resolved": "https://registry.npmjs.org/langfuse-core/-/langfuse-core-3.38.20.tgz", + "integrity": "sha512-zBKVmQN/1oT5VWZUBYlWzvokIlkC/6mnpgr/2atMyTeAm+jR3ia7w2iJMjlrF5/oG8ukO1s8+LDRCzJpF1QeEA==", + "license": "MIT", + "optional": true, + "dependencies": { + "mustache": "^4.2.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/load-esm": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.3.tgz", + "integrity": "sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + }, + { + "type": "buymeacoffee", + "url": "https://buymeacoffee.com/borewit" + } + ], + "license": "MIT", + "optional": true, + "engines": { + "node": ">=13.2.0" + } + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT", + "optional": true + }, + "node_modules/log-symbols": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", + "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/logform": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", + "license": "MIT", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/logform/node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "license": "ISC", + "optional": true + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "license": "MIT", + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mathjs": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-15.2.0.tgz", + "integrity": "sha512-UAQzSVob9rNLdGpqcFMYmSu9dkuLYy7Lr2hBEQS5SHQdknA9VppJz3cy2KkpMzTODunad6V6cNv+5kOLsePLow==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.26.10", + "complex.js": "^2.2.5", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "^5.2.1", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.2.1" + }, + "bin": { + "mathjs": "bin/cli.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "license": "BSD-3-Clause", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/memjs": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/memjs/-/memjs-1.3.2.tgz", + "integrity": "sha512-qUEg2g8vxPe+zPn09KidjIStHPtoBO8Cttm8bgJFWWabbsjQ9Av9Ky+6UcvKx6ue0LLb/LEhtcyQpRyKfzeXcg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT", + "optional": true + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/mongodb-connection-string-url": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-7.0.1.tgz", + "integrity": "sha512-h0AZ9A7IDVwwHyMxmdMXKy+9oNlF0zFoahHiX3vQ8e3KFcSP3VmsmfvtRSuLPxmyv2vjIDxqty8smTgie/SNRQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@types/whatwg-url": "^13.0.0", + "whatwg-url": "^14.1.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", + "optional": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/mongoose": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.6.1.tgz", + "integrity": "sha512-3T8/b0plM3ZJPW3WjlzVMIGJEYYTjgDPQ05Qzru3xu3/wOPSFKWYxdwUF2dl8h3NG5dVkzIuOkZdLacnlLf/sA==", + "license": "MIT", + "optional": true, + "dependencies": { + "kareem": "3.3.0", + "mongodb": "~7.2", + "mpath": "0.9.0", + "mquery": "6.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/mongodb": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.2.0.tgz", + "integrity": "sha512-F/2+BMZtLVhY30ioZp0dAmZ+IRZMBqI+nrv6t5+9/1AIwCa8sMRC3jBf81lpxMhnZgqq8CoUD503Z1oZWq1/sw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@mongodb-js/saslprep": "^1.3.0", + "bson": "^7.2.0", + "mongodb-connection-string-url": "^7.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.806.0", + "@mongodb-js/zstd": "^7.0.0", + "gcp-metadata": "^7.0.1", + "kerberos": "^7.0.0", + "mongodb-client-encryption": ">=7.0.0 <7.1.0", + "snappy": "^7.3.2", + "socks": "^2.8.6" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-6.0.0.tgz", + "integrity": "sha512-b2KQNsmgtkscfeDgkYMcWGn9vZI9YoXh802VDEwE6qc50zxBFQ0Oo8ROkawbPAsXCY1/Z1yp0MagqsZStPWJjw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=20.19.0" + } + }, + "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/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", + "optional": true, + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/mute-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", + "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" + }, + "node_modules/natural": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/natural/-/natural-8.1.1.tgz", + "integrity": "sha512-Ucb+lsUcGxUqu3rn8cwHjT6gJQosO63nIX/aBQXB3+IDkNbFV7PuviysO+Rzz3aKn7PZhPj3bNF4PS9gDVjYCQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "afinn-165": "^2.0.2", + "afinn-165-financialmarketnews": "^3.0.0", + "apparatus": "^0.0.10", + "dotenv": "^17.3.1", + "memjs": "^1.3.2", + "mongoose": "^9.2.1", + "pg": "^8.18.0", + "redis": "^5.11.0", + "safe-stable-stringify": "^2.5.0", + "stopwords-iso": "^1.1.0", + "sylvester": "^0.0.21", + "underscore": "^1.13.0", + "uuid": "^13.0.0", + "wordnet-db": "^3.1.14" + }, + "engines": { + "node": ">=0.4.10" + } + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/netmask": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz", + "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/node-abi": { + "version": "3.89.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.89.0.tgz", + "integrity": "sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "license": "MIT" + }, + "node_modules/node-rsa": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz", + "integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==", + "license": "MIT", + "dependencies": { + "asn1": "^0.2.4" + } + }, + "node_modules/node-sql-parser": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/node-sql-parser/-/node-sql-parser-5.4.0.tgz", + "integrity": "sha512-jVe6Z61gPcPjCElPZ6j8llB3wnqGcuQzefim1ERsqIakxnEy5JlzV7XKdO1KmacRG5TKwPc4vJTgSRQ0LfkbFw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@types/pegjs": "^0.10.0", + "big-integer": "^1.6.48" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "license": "BSD-2-Clause", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "license": "MIT", + "dependencies": { + "fn.name": "1.x.x" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onnxruntime-common": { + "version": "1.24.3", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.3.tgz", + "integrity": "sha512-GeuPZO6U/LBJXvwdaqHbuUmoXiEdeCjWi/EG7Y1HNnDwJYuk6WUbNXpF6luSUY8yASul3cmUlLGrCCL1ZgVXqA==", + "license": "MIT", + "optional": true + }, + "node_modules/onnxruntime-node": { + "version": "1.24.3", + "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.24.3.tgz", + "integrity": "sha512-JH7+czbc8ALA819vlTgcV+Q214/+VjGeBHDjX81+ZCD0PCVCIFGFNtT0V4sXG/1JXypKPgScQcB3ij/hk3YnTg==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "win32", + "darwin", + "linux" + ], + "dependencies": { + "adm-zip": "^0.5.16", + "global-agent": "^3.0.0", + "onnxruntime-common": "1.24.3" + } + }, + "node_modules/onnxruntime-web": { + "version": "1.26.0-dev.20260416-b7804b056c", + "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.26.0-dev.20260416-b7804b056c.tgz", + "integrity": "sha512-MD6Ss4GSpQBo6zqoJzyT9LRbKYs7x/JVN23FT24EcEvlqF4VuzPOeH6X38orZPKHQDbprn7K+SBpu0/mj2CQiw==", + "license": "MIT", + "optional": true, + "dependencies": { + "flatbuffers": "^25.1.24", + "guid-typescript": "^1.0.9", + "long": "^5.2.3", + "onnxruntime-common": "1.24.0-dev.20251116-b39e144322", + "platform": "^1.3.6", + "protobufjs": "^7.2.4" + } + }, + "node_modules/onnxruntime-web/node_modules/onnxruntime-common": { + "version": "1.24.0-dev.20251116-b39e144322", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.0-dev.20251116-b39e144322.tgz", + "integrity": "sha512-BOoomdHYmNRL5r4iQ4bMvsl2t0/hzVQ3OM3PHD0gxeXu1PmggqBv3puZicEUVOA3AtHHYmqZtjMj9FOfGrATTw==", + "license": "MIT", + "optional": true + }, + "node_modules/onnxruntime-web/node_modules/protobufjs": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.6.tgz", + "integrity": "sha512-M71sTMB146U3u0di3yup8iM+zv8yPRNQVr1KK4tyBitl3qFvEGucq/rGDRShD2rsJhtN02RJaJ7j5X5hmy8SJg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.1", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "optional": true, + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openai": { + "version": "6.35.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-6.35.0.tgz", + "integrity": "sha512-L/skwIGnt5xQZHb0UfTu9uAUKbis3ehKypOuJKi20QvG7UStV6C8IC3myGYHcdiF4kms/bAvOJ9UqqNWqi8x/Q==", + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/openapi-fetch": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/openapi-fetch/-/openapi-fetch-0.8.2.tgz", + "integrity": "sha512-4g+NLK8FmQ51RW6zLcCBOVy/lwYmFJiiT+ckYZxJWxUxH4XFhsNcX2eeqVMfVOi+mDNFja6qDXIZAz2c5J/RVw==", + "license": "MIT", + "optional": true, + "dependencies": { + "openapi-typescript-helpers": "^0.0.5" + } + }, + "node_modules/openapi-typescript-helpers": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/openapi-typescript-helpers/-/openapi-typescript-helpers-0.0.5.tgz", + "integrity": "sha512-MRffg93t0hgGZbYTxg60hkRIK2sRuEOHEtCUgMuLgbCC33TMQ68AmxskzUlauzZYD47+ENeGV/ElI7qnWqrAxA==", + "license": "MIT", + "optional": true + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/ora": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-9.4.0.tgz", + "integrity": "sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ==", + "license": "MIT", + "dependencies": { + "chalk": "^5.6.2", + "cli-cursor": "^5.0.0", + "cli-spinners": "^3.2.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.1.0", + "log-symbols": "^7.0.1", + "stdin-discarder": "^0.3.2", + "string-width": "^8.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "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": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue-compat": { + "version": "1.0.225", + "resolved": "https://registry.npmjs.org/p-queue-compat/-/p-queue-compat-1.0.225.tgz", + "integrity": "sha512-SdfGSQSJJpD7ZR+dJEjjn9GuuBizHPLW/yarJpXnmrHRruzrq7YM8OqsikSrKeoPv+Pi1YXw9IIBSIg5WveQHA==", + "license": "MIT", + "optional": true, + "dependencies": { + "eventemitter3": "5.x", + "p-timeout-compat": "^1.0.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/p-queue/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT", + "optional": true + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "optional": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout-compat": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/p-timeout-compat/-/p-timeout-compat-1.0.8.tgz", + "integrity": "sha512-+7LpKr1ilnWU0LbV2r+Wz4srwMcFTUysmgL824ZxJcZP3u4Hyi/D/39pbyEs4j0XXCHvbv069+LDPxlCijfVRQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/pac-proxy-agent": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-9.0.1.tgz", + "integrity": "sha512-3ZOSpLboOlpW4yp8Cuv21KlTULRqyJ5Uuad3wXpSKFrxdNgcHEyoa22GRaZ2UlgCVuR6z+5BiavtYVvbajL/Yw==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "get-uri": "8.0.0", + "http-proxy-agent": "9.0.0", + "https-proxy-agent": "9.0.0", + "pac-resolver": "9.0.1", + "quickjs-wasi": "^2.2.0", + "socks-proxy-agent": "10.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-9.0.0.tgz", + "integrity": "sha512-FcF8VhXYLQcxWCnt/cCpT2apKsRDUGeVEeMqGu4HSTu29U8Yw0TLOjdYIlDsYk3IkUh+taX4IDWpPcCqKDhCjA==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.0.0.tgz", + "integrity": "sha512-/MVmHp58WkOypgFhCLk4fzpPcFQvTJ/e6LBI7irpIO2HfxUbpmYoHF+KzipzJpxxzJu7aJNWQ0xojJ/dzV2G5g==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/pac-resolver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-9.0.1.tgz", + "integrity": "sha512-lJbS008tmkj08VhoM8Hzuv/VE5tK9MS0OIQ/7+s0lIF+BYhiQWFYzkSpML7lXs9iBu2jfmzBTLzhe9n6BX+dYw==", + "license": "MIT", + "dependencies": { + "degenerator": "7.0.1", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "quickjs-wasi": "^2.2.0" + } + }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/patch-console": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-2.0.0.tgz", + "integrity": "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-expression-matcher": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/pdf-parse": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-2.4.5.tgz", + "integrity": "sha512-mHU89HGh7v+4u2ubfnevJ03lmPgQ5WU4CxAVmTSh/sxVTEDYd1er/dKS/A6vg77NX47KTEoihq8jZBLr8Cxuwg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@napi-rs/canvas": "0.1.80", + "pdfjs-dist": "5.4.296" + }, + "bin": { + "pdf-parse": "bin/cli.mjs" + }, + "engines": { + "node": ">=20.16.0 <21 || >=22.3.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/mehmet-kozan" + } + }, + "node_modules/pdfjs-dist": { + "version": "5.4.296", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.4.296.tgz", + "integrity": "sha512-DlOzet0HO7OEnmUmB6wWGJrrdvbyJKftI1bhMitK7O2N8W2gc757yyYBbINy9IDafXAV9wmKr9t7xsTaNKRG5Q==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=20.16.0 || >=22.3.0" + }, + "optionalDependencies": { + "@napi-rs/canvas": "^0.1.80" + } + }, + "node_modules/pem": { + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/pem/-/pem-1.14.8.tgz", + "integrity": "sha512-ZpbOf4dj9/fQg5tQzTqv4jSKJQsK7tPl0pm4/pvPcZVjZcJg7TMfr3PBk6gJH97lnpJDu4e4v8UUqEz5daipCg==", + "license": "MIT", + "dependencies": { + "es6-promisify": "^7.0.0", + "md5": "^2.3.0", + "os-tmpdir": "^1.0.2", + "which": "^2.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/pg": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz", + "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", + "license": "MIT", + "optional": true, + "dependencies": { + "pg-connection-string": "^2.12.0", + "pg-pool": "^3.13.0", + "pg-protocol": "^1.13.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.3.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", + "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.12.0.tgz", + "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.13.0.tgz", + "integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==", + "license": "MIT", + "optional": true, + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", + "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "optional": true, + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "optional": true, + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "license": "MIT", + "optional": true + }, + "node_modules/playwright": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz", + "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "playwright-core": "1.59.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz", + "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright-extra": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/playwright-extra/-/playwright-extra-4.3.6.tgz", + "integrity": "sha512-q2rVtcE8V8K3vPVF1zny4pvwZveHLH8KBuVU2MoE3Jw4OKVoBWsHI9CH9zPydovHHOCDxjGN2Vg+2m644q3ijA==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "playwright": "*", + "playwright-core": "*" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "playwright-core": { + "optional": true + } + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/posthog-node": { + "version": "5.24.17", + "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-5.24.17.tgz", + "integrity": "sha512-mdb8TKt+YCRbGQdYar3AKNUPCyEiqcprScF4unYpGALF6HlBaEuO6wPuIqXXpCWkw4VclJYCKbb6lq6pH6bJeA==", + "license": "MIT", + "dependencies": { + "@posthog/core": "1.23.1" + }, + "engines": { + "node": "^20.20.0 || >=22.22.0" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pretty-ms": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", + "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT", + "optional": true + }, + "node_modules/promptfoo": { + "version": "0.121.9", + "resolved": "https://registry.npmjs.org/promptfoo/-/promptfoo-0.121.9.tgz", + "integrity": "sha512-b7BxcNtg7ulGJco67KNUqityciYAGl19hccweBXcqs4nXOSfOhrE8Hk2pwDomdeKODXg6p5jbJzgqq9wBIp7/g==", + "license": "MIT", + "workspaces": [ + "src/app", + "site" + ], + "dependencies": { + "@anthropic-ai/sdk": "^0.91.1", + "@apidevtools/json-schema-ref-parser": "^15.3.1", + "@googleapis/sheets": "^13.0.1", + "@inquirer/checkbox": "^5.1.0", + "@inquirer/confirm": "^6.0.8", + "@inquirer/core": "^11.1.5", + "@inquirer/editor": "^5.0.8", + "@inquirer/input": "^5.0.8", + "@inquirer/select": "^5.1.0", + "@modelcontextprotocol/sdk": "^1.29.0", + "@openai/agents": "^0.8.5", + "@opencode-ai/sdk": "^1.14.22", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/core": "^2.6.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.215.0", + "@opentelemetry/resources": "^2.6.0", + "@opentelemetry/sdk-trace-base": "^2.6.0", + "@opentelemetry/sdk-trace-node": "^2.6.0", + "@opentelemetry/semantic-conventions": "^1.40.0", + "@types/ws": "^8.18.1", + "ai": "^6.0.138", + "ajv": "^8.18.0", + "ajv-formats": "^3.0.1", + "async": "^3.2.6", + "better-sqlite3": "^12.8.0", + "binary-extensions": "^3.1.0", + "cache-manager": "^7.2.8", + "chalk": "^5.6.2", + "chokidar": "5.0.0", + "cli-progress": "^3.12.0", + "cli-table3": "^0.6.5", + "commander": "^14.0.3", + "compression": "^1.8.1", + "cors": "^2.8.6", + "csv-parse": "^6.2.0", + "csv-stringify": "^6.7.0", + "debounce": "^3.0.0", + "dedent": "^1.7.2", + "dotenv": "^17.3.1", + "drizzle-orm": "^0.45.1", + "execa": "^9.6.1", + "express": "^5.2.1", + "exsolve": "^1.0.8", + "fast-deep-equal": "^3.1.3", + "fast-safe-stringify": "^2.1.1", + "fast-xml-parser": "^5.5.5", + "fastest-levenshtein": "^1.0.16", + "gcp-metadata": "^8.1.2", + "glob": "^13.0.6", + "http-z": "^8.1.1", + "ink": "^6.8.0", + "istextorbinary": "^9.5.0", + "jks-js": "^1.1.5", + "js-rouge": "^3.2.0", + "js-yaml": "^4.1.1", + "json5": "^2.2.3", + "keyv": "^5.6.0", + "keyv-file": "^5.3.3", + "lru-cache": "^11.3.0", + "mathjs": "^15.1.1", + "minimatch": "^10.2.4", + "nunjucks": "^3.2.4", + "openai": "^6.34.0", + "opener": "^1.5.2", + "ora": "^9.3.0", + "parse5": "^8.0.0", + "pem": "~1.14.8", + "posthog-node": "~5.24.10", + "protobufjs": "^8.0.0", + "proxy-agent": "^8.0.0", + "proxy-from-env": "^2.1.0", + "python-shell": "^5.0.0", + "react": "^19.2.4", + "rfdc": "^1.4.1", + "rxjs": "^7.8.2", + "semver": "^7.7.4", + "simple-git": "^3.33.0", + "socket.io": "^4.8.3", + "socket.io-client": "^4.8.3", + "text-extensions": "^3.1.0", + "tsx": "^4.21.0", + "undici": "^7.24.5", + "winston": "^3.19.0", + "ws": "^8.19.0", + "zod": "^4.3.6" + }, + "bin": { + "pf": "dist/src/entrypoint.js", + "promptfoo": "dist/src/entrypoint.js" + }, + "engines": { + "node": "^20.20.0 || >=22.22.0" + }, + "optionalDependencies": { + "@anthropic-ai/claude-agent-sdk": "^0.2.119", + "@aws-sdk/client-bedrock-agent-runtime": "^3.1036.0", + "@aws-sdk/client-bedrock-runtime": "^3.1036.0", + "@aws-sdk/client-s3": "^3.1003.0", + "@aws-sdk/client-sagemaker-runtime": "^3.1036.0", + "@aws-sdk/credential-provider-sso": "^3.972.16", + "@azure/ai-projects": "^2.1.0", + "@azure/identity": "^4.13.0", + "@azure/msal-node": "^5.1.0", + "@azure/openai-assistants": "^1.0.0-beta.6", + "@fal-ai/client": "~1.10.0", + "@huggingface/transformers": "^4.0.0", + "@ibm-cloud/watsonx-ai": "^1.7.11", + "@ibm-generative-ai/node-sdk": "^3.2.4", + "@openai/codex-sdk": "^0.125.0", + "@playwright/browser-chromium": "^1.59.1", + "@rollup/rollup-linux-x64-gnu": "^4.59.0", + "@slack/web-api": "^7.15.0", + "@smithy/node-http-handler": "^4.4.14", + "@swc/core": "^1.15.18", + "@swc/core-darwin-arm64": "^1.15.18", + "@swc/core-darwin-x64": "^1.15.18", + "@swc/core-linux-x64-gnu": "^1.15.18", + "@swc/core-linux-x64-musl": "^1.15.18", + "@swc/core-win32-x64-msvc": "^1.15.18", + "google-auth-library": "^10.6.2", + "hono": "^4.12.5", + "ibm-cloud-sdk-core": "^5.4.11", + "langfuse": "^3.38.20", + "natural": "^8.1.1", + "node-sql-parser": "^5.4.0", + "pdf-parse": "^2.4.5", + "playwright": "^1.59.1", + "playwright-extra": "^4.3.6", + "read-excel-file": "^9.0.0", + "sharp": "^0.34.5" + } + }, + "node_modules/promptfoo/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/promptfoo/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/protobufjs": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.0.3.tgz", + "integrity": "sha512-LBYnMWkKLB8fE/ljROPDbCl7mgLSlI+oBe1fAAr5MTqFg4TIi0tYrVVurJvQggOjnUYMQtEZBjrej59ojMNTHQ==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-agent": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-8.0.1.tgz", + "integrity": "sha512-kccqGBqHZXR8onQhY/ganJjoO8QIKKRiFBhPOzbTZK16attzSZ/0XSmp9H7jrRxPKHjhGyx1q32lMPrJ3uLFgA==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "http-proxy-agent": "9.0.0", + "https-proxy-agent": "9.0.0", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "9.0.1", + "proxy-from-env": "^2.0.0", + "socks-proxy-agent": "10.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/proxy-agent/node_modules/http-proxy-agent": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-9.0.0.tgz", + "integrity": "sha512-FcF8VhXYLQcxWCnt/cCpT2apKsRDUGeVEeMqGu4HSTu29U8Yw0TLOjdYIlDsYk3IkUh+taX4IDWpPcCqKDhCjA==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.0.0.tgz", + "integrity": "sha512-/MVmHp58WkOypgFhCLk4fzpPcFQvTJ/e6LBI7irpIO2HfxUbpmYoHF+KzipzJpxxzJu7aJNWQ0xojJ/dzV2G5g==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/proxy-agent/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", + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "optional": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "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/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/python-shell": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/python-shell/-/python-shell-5.0.0.tgz", + "integrity": "sha512-RUOOOjHLhgR1MIQrCtnEqz/HJ1RMZBIN+REnpSUrfft2bXqXy69fwJASVziWExfFXsR1bCY0TznnHooNsCo0/w==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT", + "optional": true + }, + "node_modules/quickjs-wasi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/quickjs-wasi/-/quickjs-wasi-2.2.0.tgz", + "integrity": "sha512-zQxXmQMrEoD3S+jQdYsloq4qAuaxKFHZj6hHqOYGwB2iQZH+q9e/lf5zQPXCKOk0WJuAjzRFbO4KwHIp2D05Iw==", + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/react": { + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", + "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-reconciler": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.33.0.tgz", + "integrity": "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, + "node_modules/read-excel-file": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/read-excel-file/-/read-excel-file-9.0.7.tgz", + "integrity": "sha512-3k95m/FsuCGsssBVdFsREBhEV0vLLqd9q/kmsptHNMfIseXOxx3DyBVoy3QoSYqA8LAEGoW8zPPzNgHumbEz9A==", + "license": "MIT", + "optional": true, + "dependencies": { + "@xmldom/xmldom": "^0.9.9", + "fflate": "^0.8.2", + "unzipper": "^0.12.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/redis": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/redis/-/redis-5.12.1.tgz", + "integrity": "sha512-LDsoVvb/CpoV9EN3FXvgvSHNJWuCIzl9MiO3ppOevuGLpSGJhwfQjpEwfFJcQvNSddHADDdZaWx0HnmMxRXG7g==", + "license": "MIT", + "optional": true, + "dependencies": { + "@redis/bloom": "5.12.1", + "@redis/client": "5.12.1", + "@redis/json": "5.12.1", + "@redis/search": "5.12.1", + "@redis/time-series": "5.12.1" + }, + "engines": { + "node": ">= 18.19.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT", + "optional": true + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-axios": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-2.6.0.tgz", + "integrity": "sha512-pOLi+Gdll3JekwuFjXO3fTq+L9lzMQGcSq7M5gIjExcl3Gu1hd4XXuf5o3+LuSBsaULQH7DiNbsqPd1chVpQGQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=10.7.0" + }, + "peerDependencies": { + "axios": "*" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/robot3": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/robot3/-/robot3-0.4.1.tgz", + "integrity": "sha512-hzjy826lrxzx8eRgv80idkf8ua1JAepRc9Efdtj03N3KNJuznQCPlyCJ7gnUmDFwZCLQjxy567mQVKmdv2BsXQ==", + "license": "BSD-2-Clause", + "optional": true + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "license": "MIT" + }, + "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/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "license": "MIT", + "optional": true + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "license": "MIT", + "optional": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-git": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.36.0.tgz", + "integrity": "sha512-cGQjLjK8bxJw4QuYT7gxHw3/IouVESbhahSsHrX97MzCL1gu2u7oy38W6L2ZIGECEfIBG4BabsWDPjBxJENv9Q==", + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "@simple-git/args-pathspec": "^1.0.3", + "@simple-git/argv-parser": "^1.1.0", + "debug": "^4.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, + "node_modules/slice-ansi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "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/smol-toml": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz", + "integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/socket.io": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.3.tgz", + "integrity": "sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.4.1", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.6.tgz", + "integrity": "sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==", + "license": "MIT", + "dependencies": { + "debug": "~4.4.1", + "ws": "~8.18.3" + } + }, + "node_modules/socket.io-adapter/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/socket.io-client": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.3.tgz", + "integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", + "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io/node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/socket.io/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/socket.io/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/socket.io/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/socks": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.8.tgz", + "integrity": "sha512-NlGELfPrgX2f1TAAcz0WawlLn+0r3FyhhCRpFFK2CemXenPYvzMWWZINv3eDNo9ucdwme7oCHRY0Jnbs4aIkog==", + "license": "MIT", + "dependencies": { + "ip-address": "^10.1.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-10.0.0.tgz", + "integrity": "sha512-pyp2YR3mNxAMu0mGLtzs4g7O3uT4/9sQOLAKcViAkaS9fJWkud7nmaf6ZREFqQEi24IPkBcjfHjXhPTUWjo3uA==", + "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/socks/node_modules/ip-address": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.1.tgz", + "integrity": "sha512-1FMu8/N15Ck1BL551Jf42NYIoin2unWjLQ2Fze/DXryJRl5twqtwNHlO39qERGbIOcKYWHdgRryhOC+NG4eaLw==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "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/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stdin-discarder": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.3.2.tgz", + "integrity": "sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stopwords-iso": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stopwords-iso/-/stopwords-iso-1.1.0.tgz", + "integrity": "sha512-I6GPS/E0zyieHehMRPQcqkiBMJKGgLta+1hREixhoLPqEA0AlVFiC43dl8uPpmkkeRdDMzYRWFWk5/l9x7nmNg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.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==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/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/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strnum": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz", + "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/strtok3": { + "version": "10.3.5", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz", + "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/sylvester": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/sylvester/-/sylvester-0.0.21.tgz", + "integrity": "sha512-yUT0ukFkFEt4nb+NY+n2ag51aS/u9UHXoZw+A4jgD77/jzZsBoSDHuqysrVCBC4CYR4TYvUJq54ONpXgDBH8tA==", + "optional": true, + "engines": { + "node": ">=0.2.6" + } + }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terminal-size": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/terminal-size/-/terminal-size-4.0.1.tgz", + "integrity": "sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/text-extensions": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-3.1.0.tgz", + "integrity": "sha512-anOjtXr8OT5w4vc/2mP4AYTCE0GWc/21icGmaHtBHnI7pN7o01a/oqG9m06/rGzoAsDm/WNzggBpqptuCmRlZQ==", + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", + "license": "MIT" + }, + "node_modules/textextensions": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-6.11.0.tgz", + "integrity": "sha512-tXJwSr9355kFJI3lbCkPpUH5cP8/M0GGy2xLO34aZCjMXBaK3SoPnZwr/oWmo1FdCnELcs4npdCIOFtq9W3ruQ==", + "license": "Artistic-2.0", + "dependencies": { + "editions": "^6.21.0" + }, + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "license": "MIT" + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-types": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", + "license": "MIT", + "optional": true, + "dependencies": { + "@borewit/text-codec": "^0.2.1", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT", + "optional": true + }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/ts-algebra": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", + "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", + "license": "MIT" + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "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/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-fest": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", + "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-function": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.2.tgz", + "integrity": "sha512-VwaXim9Gp1bngi/q3do8hgttYn2uC3MoT/gfuMWylnj1IeZBUAyPddHZlo1K05BDoj8DYPpMdiHqH1dDYdJf2A==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/underscore": { + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", + "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", + "license": "MIT", + "optional": true + }, + "node_modules/undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unzipper": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.12.3.tgz", + "integrity": "sha512-PZ8hTS+AqcGxsaQntl3IRBw65QrBI6lxzqDEL7IAo/XCEqRTKGfOX56Vea5TH9SZczRVxuzk1re04z/YjuYCJA==", + "license": "MIT", + "optional": true, + "dependencies": { + "bluebird": "~3.7.2", + "duplexer2": "~0.1.4", + "fs-extra": "^11.2.0", + "graceful-fs": "^4.2.2", + "node-int64": "^0.4.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==", + "license": "BSD" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.1.tgz", + "integrity": "sha512-9ezox2roIft6ExBVTVqibSd5dc5/47Sw/uY6b4SjQUT2TzQ0tltNquWA46y4xPQmdZYqvnio22SgWd41M86+jw==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "license": "MIT", + "optional": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/version-range": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/version-range/-/version-range-4.15.0.tgz", + "integrity": "sha512-Ck0EJbAGxHwprkzFO966t4/5QkRuzh+/I1RxhLgUKKwEn+Cd8NwM60mE3AqBZg5gYODoXW0EFsQvbZjRlvdqbg==", + "license": "Artistic-2.0", + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause", + "optional": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-6.0.0.tgz", + "integrity": "sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA==", + "license": "MIT", + "dependencies": { + "string-width": "^8.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/widest-line/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/widest-line/node_modules/strip-ansi": { + "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": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/winston": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz", + "integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==", + "license": "MIT", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.8", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.7.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.9.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "license": "MIT", + "dependencies": { + "logform": "^2.7.0", + "readable-stream": "^3.6.2", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston/node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/wordnet-db": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/wordnet-db/-/wordnet-db-3.1.14.tgz", + "integrity": "sha512-zVyFsvE+mq9MCmwXUWHIcpfbrHHClZWZiVOzKSxNJruIcFn2RbY55zkhiAMMxM8zCVSmtNiViq8FsAZSFpMYag==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/wrap-ansi": { + "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": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "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/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/wrap-ansi/node_modules/strip-ansi": { + "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": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-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/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", + "license": "ISC", + "optional": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoga-layout": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz", + "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", + "license": "MIT" + }, + "node_modules/zod": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.1.tgz", + "integrity": "sha512-a6ENMBBGZBsnlSebQ/eKCguSBeGKSf4O7BPnqVPmYGtpBYI7VSqoVqw+QcB7kPRjbqPwhYTpFbVj/RqNz/CT0Q==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } + } + } +} diff --git a/tests/evals/package.json b/tests/evals/package.json new file mode 100644 index 000000000..a188c5581 --- /dev/null +++ b/tests/evals/package.json @@ -0,0 +1,23 @@ +{ + "name": "@skill-builder/evals", + "private": true, + "description": "Promptfoo eval harness for Skill Builder agent behavior", + "scripts": { + "eval:harness-smoke": "./scripts/promptfoo.sh eval --no-cache -c packages/harness-smoke/promptfooconfig.json", + "eval:agents": "npm run eval:harness-smoke", + "eval:scope-advisor": "npm run eval:harness-smoke", + "eval:smoke": "./scripts/promptfoo.sh eval --no-cache --filter-pattern '^\\[smoke\\]' -c packages/harness-smoke/promptfooconfig.json", + "test": "node --test scripts/*.test.js assertions/*.test.js", + "test:harness": "node --test scripts/*.test.js", + "test:assertions": "node --test assertions/*.test.js", + "view": "./scripts/promptfoo.sh view" + }, + "dependencies": { + "js-yaml": "^4.1.1", + "promptfoo": "0.121.9", + "smol-toml": "^1.6.1" + }, + "overrides": { + "@anthropic-ai/sdk": ">=0.81.0" + } +} diff --git a/tests/evals/packages/harness-smoke/promptfooconfig.json b/tests/evals/packages/harness-smoke/promptfooconfig.json new file mode 100644 index 000000000..864c6ccc7 --- /dev/null +++ b/tests/evals/packages/harness-smoke/promptfooconfig.json @@ -0,0 +1,28 @@ +{ + "description": "OpenCode harness smoke test.", + "metadata": { + "eval_tier": "light" + }, + "prompts": [ + "Return JSON only: {\"scenario\":\"harness-smoke\",\"ok\":true,\"failures\":[]}" + ], + "tests": [ + { + "description": "[smoke] harness-smoke", + "assert": [ + { + "type": "contains", + "value": "\"scenario\":\"harness-smoke\"" + }, + { + "type": "contains", + "value": "\"ok\":true" + }, + { + "type": "contains", + "value": "\"failures\":[]" + } + ] + } + ] +} diff --git a/tests/evals/scripts/eval-suite-contract.test.js b/tests/evals/scripts/eval-suite-contract.test.js new file mode 100644 index 000000000..14932b295 --- /dev/null +++ b/tests/evals/scripts/eval-suite-contract.test.js @@ -0,0 +1,162 @@ +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const path = require('node:path'); +const test = require('node:test'); +const yaml = require('js-yaml'); + +const EVAL_ROOT = path.resolve(__dirname, '..'); +const OPENCODE_CONFIG = 'opencode.json'; +const PACKAGE_ROOT = path.join(EVAL_ROOT, 'packages'); +const SCRIPT_ROOT = path.join(EVAL_ROOT, 'scripts'); +const LIVE_CONFIGS = []; +const ALLOWED_TIERS = new Set(['light', 'standard', 'high', 'x_high']); +const EXPECTED_AGENT_STEPS = { + eval_light: 60, + eval_standard: 100, + eval_high: 120, + eval_x_high: 200, +}; +const FORBIDDEN_REFERENCES = [ + 'file://../../providers/', + 'file://../providers/', + 'anthropic:claude-agent-sdk', + 'max_turns', + 'runtime.tools', + 'model_provider_id', + 'working_dir', +]; + +function collectPackageConfigs(rootDir) { + const configs = []; + + for (const entry of fs.readdirSync(rootDir, { withFileTypes: true })) { + const entryPath = path.join(rootDir, entry.name); + if (entry.isDirectory()) { + configs.push(...collectPackageConfigs(entryPath)); + continue; + } + + if (entry.isFile() && (entry.name.endsWith('.yaml') || entry.name.endsWith('.json'))) { + configs.push(path.relative(EVAL_ROOT, entryPath)); + } + } + + return configs.sort(); +} + +function readYaml(relativePath) { + return yaml.load(fs.readFileSync(path.join(EVAL_ROOT, relativePath), 'utf8')); +} + +function readJson(relativePath) { + return JSON.parse(fs.readFileSync(path.join(EVAL_ROOT, relativePath), 'utf8')); +} + +function collectTextFiles(rootDir) { + const textFiles = []; + + for (const entry of fs.readdirSync(rootDir, { withFileTypes: true })) { + const entryPath = path.join(rootDir, entry.name); + if (entry.isDirectory()) { + if (entry.name === 'node_modules' || entry.name === '.tmp') { + continue; + } + textFiles.push(...collectTextFiles(entryPath)); + continue; + } + + if (entry.isFile()) { + textFiles.push(path.relative(EVAL_ROOT, entryPath)); + } + } + + return textFiles.sort(); +} + +function toUtf8(value) { + return Buffer.from(value, 'utf8').toString('utf8'); +} + +test('all eval package configs declare a valid metadata.eval_tier', () => { + const packageConfigs = collectPackageConfigs(PACKAGE_ROOT); + const configPaths = [...packageConfigs, ...LIVE_CONFIGS]; + + assert.ok(packageConfigs.length > 0, 'expected at least one package config'); + for (const relativePath of configPaths) { + const parsed = readYaml(relativePath); + assert.ok(parsed?.metadata, `${relativePath} must define metadata`); + assert.ok(parsed.metadata.eval_tier, `${relativePath} must define metadata.eval_tier`); + assert.ok( + ALLOWED_TIERS.has(parsed.metadata.eval_tier), + `${relativePath} has unsupported eval tier: ${parsed.metadata.eval_tier}`, + ); + } +}); + +test('eval suite no longer references provider files or the Claude agent sdk', () => { + const textFiles = [ + ...collectTextFiles(PACKAGE_ROOT), + ...LIVE_CONFIGS, + path.relative(EVAL_ROOT, path.join(SCRIPT_ROOT, 'promptfoo.sh')), + path.relative(EVAL_ROOT, path.join(SCRIPT_ROOT, 'run-promptfoo-with-guard.js')), + path.relative(EVAL_ROOT, path.join(SCRIPT_ROOT, 'resolve-promptfoo-config.js')), + 'package.json', + ].sort(); + + for (const relativePath of textFiles) { + const contents = fs.readFileSync(path.join(EVAL_ROOT, relativePath), 'utf8'); + for (const forbiddenReference of FORBIDDEN_REFERENCES) { + assert.ok( + !contents.includes(toUtf8(forbiddenReference)), + `${relativePath} still references ${forbiddenReference}`, + ); + } + } +}); + +test('package configs do not declare package-local providers', () => { + const packageConfigs = collectPackageConfigs(PACKAGE_ROOT); + + for (const relativePath of packageConfigs) { + const parsed = readYaml(relativePath); + assert.equal( + Object.prototype.hasOwnProperty.call(parsed, 'providers'), + false, + `${relativePath} must receive providers from scripts/resolve-promptfoo-config.js`, + ); + } +}); + +test('suite OpenCode config disables provider timeouts for long-running evals', () => { + const config = readJson(OPENCODE_CONFIG); + + assert.equal(config.provider?.opencode?.options?.timeout, false); + assert.equal('chunkTimeout' in config.provider.opencode.options, false); +}); + +test('suite OpenCode config defines primary eval agents with enforceable fields', () => { + const config = readJson(OPENCODE_CONFIG); + + for (const [agentName, steps] of Object.entries(EXPECTED_AGENT_STEPS)) { + const agent = config.agent?.[agentName]; + assert.ok(agent, `missing OpenCode eval agent: ${agentName}`); + assert.equal(agent.description.length > 0, true); + assert.equal(agent.mode, 'primary'); + assert.equal(agent.model, 'opencode/qwen3.6-plus'); + if (agent.temperature !== undefined) { + assert.equal(agent.temperature, 0.1); + } + assert.equal(agent.steps, steps); + assert.deepEqual(agent.permission, { + read: 'allow', + write: 'allow', + edit: 'allow', + bash: 'allow', + grep: 'allow', + glob: 'allow', + list: 'allow', + webfetch: 'deny', + }); + assert.equal('tools' in agent, false, `${agentName} must use permission, not tools`); + } +}); diff --git a/tests/evals/scripts/eval-tier-config.js b/tests/evals/scripts/eval-tier-config.js new file mode 100644 index 000000000..3462680b0 --- /dev/null +++ b/tests/evals/scripts/eval-tier-config.js @@ -0,0 +1,213 @@ +const fs = require('node:fs'); +const path = require('node:path'); +const { parse } = require('smol-toml'); + +const EVAL_ROOT = path.resolve(__dirname, '..'); +const REPO_ROOT = path.resolve(EVAL_ROOT, '..', '..'); +const CONFIG_PATH = path.join(EVAL_ROOT, 'config', 'eval-tiers.toml'); +const REQUIRED_TIERS = ['light', 'standard', 'high', 'x_high']; +const REQUIRED_RUNTIME_FIELDS = [ + 'provider_id', + 'opencode_config', + 'project_dir', + 'format', + 'log_level', + 'print_logs', +]; +const ALLOWED_RUNTIME_FIELDS = new Set([ + ...REQUIRED_RUNTIME_FIELDS, + 'empty_output_retries', +]); +const ALLOWED_TIER_FIELDS = new Set(['agent']); +const REQUIRED_AGENT_PERMISSION = { + read: 'allow', + write: 'allow', + edit: 'allow', + bash: 'allow', + grep: 'allow', + glob: 'allow', + list: 'allow', + webfetch: 'deny', +}; + +function loadEvalTierConfig(configPath = CONFIG_PATH) { + const parsed = parse(fs.readFileSync(configPath, 'utf8')); + const runtime = parsed.runtime || {}; + const tiers = parsed.tiers || {}; + const baseDir = configPath === CONFIG_PATH ? EVAL_ROOT : path.dirname(configPath); + const projectRoot = configPath === CONFIG_PATH ? REPO_ROOT : path.resolve(baseDir, '..'); + + validateRuntime(runtime); + + const opencodeConfig = resolveWithinRoot( + baseDir, + runtime.opencode_config, + `Refusing to access OpenCode config outside eval root: ${runtime.opencode_config}`, + ); + const agents = loadOpenCodeAgents(opencodeConfig); + + for (const tier of REQUIRED_TIERS) { + if (!tiers[tier] || typeof tiers[tier].agent !== 'string') { + throw new Error(`Missing required eval tier: ${tier}`); + } + } + + for (const [tierName, tier] of Object.entries(tiers)) { + if (typeof tier.agent !== 'string' || tier.agent.trim() === '') { + throw new Error(`Invalid eval tier field: ${tierName}.agent`); + } + for (const field of Object.keys(tier)) { + if (!ALLOWED_TIER_FIELDS.has(field)) { + throw new Error(`Unexpected eval tier field: ${tierName}.${field}`); + } + } + if (!agents[tier.agent]) { + throw new Error(`Eval tier ${tierName} references missing OpenCode agent: ${tier.agent}`); + } + validateOpenCodeEvalAgent(tier.agent, agents[tier.agent]); + } + + return { + runtime: { + providerId: runtime.provider_id, + opencodeConfig, + projectDir: resolveWithinRoot( + baseDir, + runtime.project_dir, + projectRoot, + `Refusing to use project directory outside eval root: ${runtime.project_dir}`, + ), + format: runtime.format, + logLevel: runtime.log_level, + printLogs: runtime.print_logs, + emptyOutputRetries: normalizeEmptyOutputRetries(runtime.empty_output_retries), + }, + tiers: Object.fromEntries( + Object.entries(tiers).map(([tierName, tier]) => [tierName, { agent: tier.agent }]), + ), + agents, + }; +} + +function resolveEvalTier(config, tierName) { + const tier = config.tiers[tierName]; + if (!tier) { + throw new Error(`Unknown eval tier: ${tierName}`); + } + + return tier; +} + +function validateRuntime(runtime) { + for (const field of REQUIRED_RUNTIME_FIELDS) { + if (field === 'print_logs') { + if (typeof runtime[field] !== 'boolean') { + throw new Error(`Missing required eval runtime field: ${field}`); + } + continue; + } + + if (typeof runtime[field] !== 'string') { + throw new Error(`Missing required eval runtime field: ${field}`); + } + } + + for (const field of Object.keys(runtime)) { + if (!ALLOWED_RUNTIME_FIELDS.has(field)) { + throw new Error(`Unexpected eval runtime field: ${field}`); + } + } + + normalizeEmptyOutputRetries(runtime.empty_output_retries); +} + +function loadOpenCodeAgents(opencodeConfigPath) { + const parsed = JSON.parse(fs.readFileSync(opencodeConfigPath, 'utf8')); + const agents = parsed.agent || {}; + if (!isPlainObject(agents)) { + throw new Error('Missing required OpenCode config field: agent'); + } + + return agents; +} + +function validateOpenCodeEvalAgent(agentName, agent) { + if (!isPlainObject(agent)) { + throw new Error(`Invalid OpenCode eval agent: ${agentName}`); + } + + for (const field of ['description', 'mode', 'model']) { + if (typeof agent[field] !== 'string' || agent[field].trim() === '') { + throw new Error(`Missing required OpenCode eval agent field: ${agentName}.${field}`); + } + } + + if (agent.mode !== 'primary') { + throw new Error(`Invalid OpenCode eval agent field: ${agentName}.mode`); + } + + if (agent.temperature !== undefined && typeof agent.temperature !== 'number') { + throw new Error(`Invalid OpenCode eval agent field: ${agentName}.temperature`); + } + + if (!Number.isInteger(agent.steps) || agent.steps <= 0) { + throw new Error(`Invalid OpenCode eval agent field: ${agentName}.steps`); + } + + if (!isPlainObject(agent.permission)) { + throw new Error(`Missing required OpenCode eval agent field: ${agentName}.permission`); + } + + for (const [permissionName, expectedAction] of Object.entries(REQUIRED_AGENT_PERMISSION)) { + if (agent.permission[permissionName] !== expectedAction) { + throw new Error(`Invalid OpenCode eval agent permission: ${agentName}.${permissionName}`); + } + } + + if (Object.prototype.hasOwnProperty.call(agent, 'tools')) { + throw new Error(`Unexpected OpenCode eval agent field: ${agentName}.tools`); + } +} + +function normalizeEmptyOutputRetries(value) { + if (value === undefined) { + return 0; + } + + if (!Number.isInteger(value) || value < 0) { + throw new Error('Invalid eval runtime field: empty_output_retries'); + } + + return value; +} + +function resolveWithinRoot(root, candidatePath, allowedRootOrErrorMessage, maybeErrorMessage) { + const allowedRoot = maybeErrorMessage ? allowedRootOrErrorMessage : root; + const errorMessage = maybeErrorMessage || allowedRootOrErrorMessage; + const resolvedPath = path.resolve(root, candidatePath); + ensureWithinRoot(resolvedPath, allowedRoot, errorMessage); + return resolvedPath; +} + +function ensureWithinRoot(candidatePath, root, errorMessage) { + const normalizedRoot = path.resolve(root); + const rootWithSeparator = `${normalizedRoot}${path.sep}`; + if (candidatePath !== normalizedRoot && !candidatePath.startsWith(rootWithSeparator)) { + throw new Error(errorMessage); + } +} + +function isPlainObject(value) { + if (value === null || typeof value !== 'object' || Array.isArray(value)) { + return false; + } + + return Object.getPrototypeOf(value) === Object.prototype; +} + +module.exports = { + CONFIG_PATH, + REQUIRED_TIERS, + loadEvalTierConfig, + resolveEvalTier, +}; diff --git a/tests/evals/scripts/eval-tier-config.test.js b/tests/evals/scripts/eval-tier-config.test.js new file mode 100644 index 000000000..ba5d722bf --- /dev/null +++ b/tests/evals/scripts/eval-tier-config.test.js @@ -0,0 +1,339 @@ +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const os = require('node:os'); +const path = require('node:path'); +const test = require('node:test'); + +const { + CONFIG_PATH, + loadEvalTierConfig, + resolveEvalTier, +} = require('./eval-tier-config'); + +const AGENT_PERMISSION = { + read: 'allow', + write: 'allow', + edit: 'allow', + bash: 'allow', + grep: 'allow', + glob: 'allow', + list: 'allow', + webfetch: 'deny', +}; + +test('loadEvalTierConfig returns required suite tiers and OpenCode agents', () => { + const config = loadEvalTierConfig(); + + assert.equal(config.runtime.providerId, 'file://scripts/opencode-cli-provider.js'); + assert.equal(config.runtime.opencodeConfig, path.resolve(path.dirname(CONFIG_PATH), '..', 'opencode.json')); + assert.equal(config.runtime.projectDir, path.resolve(path.dirname(CONFIG_PATH), '..', '..', '..')); + assert.equal(config.runtime.format, 'default'); + assert.equal(config.runtime.logLevel, 'ERROR'); + assert.equal(config.runtime.printLogs, false); + assert.equal(config.runtime.emptyOutputRetries, 1); + assert.deepEqual( + Object.keys(config.tiers).sort(), + ['high', 'light', 'standard', 'x_high'], + ); + assert.deepEqual(config.tiers.light, { agent: 'eval_light' }); + assert.deepEqual(config.tiers.standard, { agent: 'eval_standard' }); + assert.equal(config.agents.eval_light.model, 'opencode/qwen3.6-plus'); + assert.equal(config.agents.eval_light.temperature, 0.1); + assert.equal(config.agents.eval_light.steps, 60); + assert.deepEqual(config.agents.eval_light.permission, AGENT_PERMISSION); +}); + +test('resolveEvalTier returns the expected OpenCode agent', () => { + const config = loadEvalTierConfig(); + + assert.equal(resolveEvalTier(config, 'light').agent, 'eval_light'); + assert.equal(resolveEvalTier(config, 'standard').agent, 'eval_standard'); + assert.equal(resolveEvalTier(config, 'high').agent, 'eval_high'); + assert.equal(resolveEvalTier(config, 'x_high').agent, 'eval_x_high'); +}); + +test('resolveEvalTier rejects unknown tiers', () => { + const config = loadEvalTierConfig(); + + assert.throws(() => resolveEvalTier(config, 'missing'), /Unknown eval tier: missing/); +}); + +test('loadEvalTierConfig rejects missing runtime and tier fields', () => { + const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'eval-tier-config-')); + try { + const writeOpenCodeConfig = (agents) => { + const opencodePath = path.join(tempRoot, 'opencode.json'); + fs.writeFileSync(opencodePath, JSON.stringify({ agent: agents }, null, 2), 'utf8'); + }; + const validAgents = { + eval_light: { + description: 'Light eval agent.', + mode: 'primary', + model: 'opencode/qwen3.6-plus', + temperature: 0.1, + steps: 60, + permission: AGENT_PERMISSION, + }, + eval_standard: { + description: 'Standard eval agent.', + mode: 'primary', + model: 'opencode/qwen3.6-plus', + temperature: 0.1, + steps: 100, + permission: AGENT_PERMISSION, + }, + eval_high: { + description: 'High eval agent.', + mode: 'primary', + model: 'opencode/qwen3.6-plus', + temperature: 0.1, + steps: 120, + permission: AGENT_PERMISSION, + }, + eval_x_high: { + description: 'Extra high eval agent.', + mode: 'primary', + model: 'opencode/qwen3.6-plus', + temperature: 0.1, + steps: 200, + permission: AGENT_PERMISSION, + }, + }; + writeOpenCodeConfig(validAgents); + + const validRuntime = ` +[runtime] +provider_id = "file://scripts/opencode-cli-provider.js" +opencode_config = "opencode.json" +project_dir = "." +format = "default" +log_level = "ERROR" +print_logs = false +empty_output_retries = 1 +`.trimStart(); + const validTiers = ` +[tiers.light] +agent = "eval_light" + +[tiers.standard] +agent = "eval_standard" + +[tiers.high] +agent = "eval_high" + +[tiers.x_high] +agent = "eval_x_high" +`.trimStart(); + + const missingRuntimePath = path.join(tempRoot, 'missing-runtime.toml'); + fs.writeFileSync(missingRuntimePath, ` +[runtime] +provider_id = "file://scripts/opencode-cli-provider.js" +project_dir = "." +format = "default" +log_level = "ERROR" +print_logs = false + +${validTiers} +`.trimStart(), 'utf8'); + + assert.throws( + () => loadEvalTierConfig(missingRuntimePath), + /Missing required eval runtime field: opencode_config/, + ); + + const missingTierPath = path.join(tempRoot, 'missing-tier.toml'); + fs.writeFileSync(missingTierPath, ` +${validRuntime} +[tiers.light] +agent = "eval_light" + +[tiers.standard] +agent = "eval_standard" + +[tiers.high] +agent = "eval_high" +`.trimStart(), 'utf8'); + + assert.throws( + () => loadEvalTierConfig(missingTierPath), + /Missing required eval tier: x_high/, + ); + + const invalidAgentPath = path.join(tempRoot, 'invalid-agent.toml'); + fs.writeFileSync(invalidAgentPath, ` +${validRuntime} +[tiers.light] +agent = "missing_agent" + +[tiers.standard] +agent = "eval_standard" + +[tiers.high] +agent = "eval_high" + +[tiers.x_high] +agent = "eval_x_high" +`.trimStart(), 'utf8'); + + assert.throws( + () => loadEvalTierConfig(invalidAgentPath), + /Eval tier light references missing OpenCode agent: missing_agent/, + ); + + const malformedAgentPath = path.join(tempRoot, 'malformed-agent.toml'); + fs.writeFileSync(malformedAgentPath, ` +${validRuntime} +${validTiers} +`.trimStart(), 'utf8'); + writeOpenCodeConfig({ + ...validAgents, + eval_light: { + description: 'Light eval agent.', + mode: 'primary', + model: 'opencode/qwen3.6-plus', + temperature: 0.1, + steps: 'sixty', + permission: AGENT_PERMISSION, + }, + }); + + assert.throws( + () => loadEvalTierConfig(malformedAgentPath), + /Invalid OpenCode eval agent field: eval_light.steps/, + ); + + writeOpenCodeConfig({ + ...validAgents, + eval_light: { + description: 'Light eval agent.', + mode: 'primary', + model: 'opencode/qwen3.6-plus', + steps: 60, + permission: AGENT_PERMISSION, + }, + }); + + assert.doesNotThrow(() => loadEvalTierConfig(malformedAgentPath)); + + writeOpenCodeConfig({ + ...validAgents, + build: { + mode: 'primary', + }, + }); + const nonEvalAgentPath = path.join(tempRoot, 'non-eval-agent.toml'); + fs.writeFileSync(nonEvalAgentPath, ` +${validRuntime} +[tiers.light] +agent = "build" + +[tiers.standard] +agent = "eval_standard" + +[tiers.high] +agent = "eval_high" + +[tiers.x_high] +agent = "eval_x_high" +`.trimStart(), 'utf8'); + + assert.throws( + () => loadEvalTierConfig(nonEvalAgentPath), + /Missing required OpenCode eval agent field: build.description/, + ); + + writeOpenCodeConfig({ + ...validAgents, + eval_light: { + description: 'Light eval agent.', + mode: 'primary', + model: 'opencode/qwen3.6-plus', + temperature: 0.1, + steps: 60, + permission: { + ...AGENT_PERMISSION, + webfetch: 'allow', + }, + }, + }); + + assert.throws( + () => loadEvalTierConfig(malformedAgentPath), + /Invalid OpenCode eval agent permission: eval_light.webfetch/, + ); + + writeOpenCodeConfig({ + ...validAgents, + eval_light: { + description: 'Light eval agent.', + mode: 'primary', + model: 'opencode/qwen3.6-plus', + temperature: 0.1, + steps: 60, + tools: AGENT_PERMISSION, + }, + }); + + assert.throws( + () => loadEvalTierConfig(malformedAgentPath), + /Missing required OpenCode eval agent field: eval_light.permission/, + ); + + writeOpenCodeConfig(validAgents); + const deprecatedTierPath = path.join(tempRoot, 'deprecated-tier.toml'); + fs.writeFileSync(deprecatedTierPath, ` +${validRuntime} +[tiers.light] +agent = "eval_light" +max_turns = 60 + +[tiers.standard] +agent = "eval_standard" + +[tiers.high] +agent = "eval_high" + +[tiers.x_high] +agent = "eval_x_high" +`.trimStart(), 'utf8'); + + assert.throws( + () => loadEvalTierConfig(deprecatedTierPath), + /Unexpected eval tier field: light.max_turns/, + ); + + const deprecatedRuntimePath = path.join(tempRoot, 'deprecated-runtime.toml'); + fs.writeFileSync(deprecatedRuntimePath, ` +${validRuntime} +model = "qwen3.6-plus" +${validTiers} +`.trimStart(), 'utf8'); + + assert.throws( + () => loadEvalTierConfig(deprecatedRuntimePath), + /Unexpected eval runtime field: model/, + ); + + const negativeRetriesPath = path.join(tempRoot, 'negative-retries.toml'); + fs.writeFileSync(negativeRetriesPath, ` +[runtime] +provider_id = "file://scripts/opencode-cli-provider.js" +opencode_config = "opencode.json" +project_dir = "." +format = "default" +log_level = "ERROR" +print_logs = false +empty_output_retries = -1 + +${validTiers} +`.trimStart(), 'utf8'); + + assert.throws( + () => loadEvalTierConfig(negativeRetriesPath), + /Invalid eval runtime field: empty_output_retries/, + ); + } finally { + fs.rmSync(tempRoot, { recursive: true, force: true }); + } +}); diff --git a/tests/evals/scripts/fixtures/missing-eval-tier.json b/tests/evals/scripts/fixtures/missing-eval-tier.json new file mode 100644 index 000000000..c9b9ebf67 --- /dev/null +++ b/tests/evals/scripts/fixtures/missing-eval-tier.json @@ -0,0 +1,5 @@ +{ + "description": "missing metadata tier", + "prompts": [], + "tests": [] +} diff --git a/tests/evals/scripts/opencode-cli-provider.js b/tests/evals/scripts/opencode-cli-provider.js new file mode 100644 index 000000000..21681f1bc --- /dev/null +++ b/tests/evals/scripts/opencode-cli-provider.js @@ -0,0 +1,130 @@ +const { spawn } = require('node:child_process'); +const path = require('node:path'); + +const EVAL_ROOT = path.resolve(__dirname, '..'); +const DEFAULT_STATE_HOME = path.join(EVAL_ROOT, '.promptfoo', 'opencode-runtime', 'state'); + +class OpenCodeCliProvider { + constructor(options = {}) { + this.config = options.config || {}; + this.providerId = options.id || 'opencode:cli'; + this.runner = options.runner || runOpenCode; + } + + id() { + return this.providerId; + } + + async callApi(prompt, _context, callOptions = {}) { + const missingField = ['agent', 'opencode_config', 'project_dir', 'format', 'log_level'] + .find((field) => typeof this.config[field] !== 'string' || this.config[field].trim() === ''); + if (missingField) { + return { error: 'OpenCode CLI provider requires agent, opencode_config, project_dir, format, and log_level' }; + } + + try { + const output = await this.callWithEmptyOutputRetries(prompt, callOptions); + return { output }; + } catch (error) { + return { error: error instanceof Error ? error.message : String(error) }; + } + } + + async callWithEmptyOutputRetries(prompt, callOptions) { + const maxAttempts = 1 + normalizeRetryCount(this.config.empty_output_retries); + let attempt = 0; + const opencodeConfig = path.resolve(EVAL_ROOT, this.config.opencode_config); + const projectDir = path.resolve(EVAL_ROOT, this.config.project_dir); + const args = [ + 'run', + '--agent', + this.config.agent, + '--dir', + projectDir, + '--format', + this.config.format, + '--log-level', + this.config.log_level, + ]; + if (this.config.print_logs) { + args.push('--print-logs'); + } + + while (attempt < maxAttempts) { + attempt += 1; + const output = await this.runner([...args, prompt], { + cwd: EVAL_ROOT, + env: { + ...process.env, + OPENCODE_CONFIG: opencodeConfig, + XDG_STATE_HOME: process.env.XDG_STATE_HOME || DEFAULT_STATE_HOME, + }, + signal: callOptions.abortSignal, + }); + const trimmedOutput = output.trim(); + if (trimmedOutput) { + return trimmedOutput; + } + } + + throw new Error(`OpenCode CLI returned empty output after ${maxAttempts} attempt(s)`); + } +} + +function normalizeRetryCount(value) { + if (value === undefined) { + return 0; + } + + if (!Number.isInteger(value) || value < 0) { + throw new Error('OpenCode CLI provider requires empty_output_retries to be a non-negative integer'); + } + + return value; +} + +function runOpenCode(args, options) { + return new Promise((resolve, reject) => { + const child = spawn('opencode', args, { + cwd: options.cwd, + env: options.env, + stdio: ['ignore', 'pipe', 'pipe'], + }); + const stdout = []; + const stderr = []; + + const abort = () => { + child.kill('SIGTERM'); + reject(new Error('OpenCode CLI call aborted')); + }; + + if (options.signal) { + if (options.signal.aborted) { + abort(); + return; + } + options.signal.addEventListener('abort', abort, { once: true }); + } + + child.stdout.on('data', (chunk) => stdout.push(chunk)); + child.stderr.on('data', (chunk) => stderr.push(chunk)); + child.on('error', reject); + child.on('close', (code) => { + if (options.signal) { + options.signal.removeEventListener('abort', abort); + } + + const output = Buffer.concat(stdout).toString('utf8'); + const errorOutput = Buffer.concat(stderr).toString('utf8').trim(); + if (code === 0) { + resolve(output); + return; + } + + reject(new Error(errorOutput || `opencode exited with code ${code}`)); + }); + }); +} + +module.exports = OpenCodeCliProvider; +module.exports.runOpenCode = runOpenCode; diff --git a/tests/evals/scripts/opencode-cli-provider.test.js b/tests/evals/scripts/opencode-cli-provider.test.js new file mode 100644 index 000000000..fe5166fe6 --- /dev/null +++ b/tests/evals/scripts/opencode-cli-provider.test.js @@ -0,0 +1,149 @@ +const assert = require('node:assert/strict'); +const path = require('node:path'); +const test = require('node:test'); + +const OpenCodeCliProvider = require('./opencode-cli-provider'); + +test('OpenCodeCliProvider invokes opencode run with the configured eval agent', async () => { + const calls = []; + const provider = new OpenCodeCliProvider({ + config: { + agent: 'eval_light', + opencode_config: '/suite/opencode.json', + project_dir: '/repo', + format: 'default', + log_level: 'ERROR', + }, + runner: async (args, options) => { + calls.push({ args, options }); + return 'status output'; + }, + }); + + const result = await provider.callApi('run status'); + + assert.deepEqual(result, { output: 'status output' }); + assert.deepEqual(calls[0].args, [ + 'run', + '--agent', + 'eval_light', + '--dir', + '/repo', + '--format', + 'default', + '--log-level', + 'ERROR', + 'run status', + ]); + assert.equal(calls[0].options.cwd, path.resolve(__dirname, '..')); + assert.equal(calls[0].options.env.OPENCODE_CONFIG, '/suite/opencode.json'); + assert.match(calls[0].options.env.XDG_STATE_HOME, /\.promptfoo\/opencode-runtime\/state$/); +}); + +test('OpenCodeCliProvider includes --print-logs only when configured', async () => { + const calls = []; + const provider = new OpenCodeCliProvider({ + config: { + agent: 'eval_standard', + opencode_config: '/suite/opencode.json', + project_dir: '/repo', + format: 'json', + log_level: 'DEBUG', + print_logs: true, + }, + runner: async (args, options) => { + calls.push({ args, options }); + return 'status output'; + }, + }); + + await provider.callApi('prompt'); + + assert.deepEqual(calls[0].args, [ + 'run', + '--agent', + 'eval_standard', + '--dir', + '/repo', + '--format', + 'json', + '--log-level', + 'DEBUG', + '--print-logs', + 'prompt', + ]); +}); + +test('OpenCodeCliProvider retries empty CLI output when configured', async () => { + let calls = 0; + const provider = new OpenCodeCliProvider({ + config: { + agent: 'eval_light', + opencode_config: '/suite/opencode.json', + project_dir: '/repo', + format: 'default', + log_level: 'ERROR', + empty_output_retries: 1, + }, + runner: async () => { + calls += 1; + return calls === 1 ? ' ' : 'usable output'; + }, + }); + + const result = await provider.callApi('prompt'); + + assert.deepEqual(result, { output: 'usable output' }); + assert.equal(calls, 2); +}); + +test('OpenCodeCliProvider reports empty output after configured retries', async () => { + const provider = new OpenCodeCliProvider({ + config: { + agent: 'eval_light', + opencode_config: '/suite/opencode.json', + project_dir: '/repo', + format: 'default', + log_level: 'ERROR', + empty_output_retries: 1, + }, + runner: async () => '', + }); + + const result = await provider.callApi('prompt'); + + assert.deepEqual(result, { + error: 'OpenCode CLI returned empty output after 2 attempt(s)', + }); +}); + +test('OpenCodeCliProvider validates required runtime config and retry count', async () => { + const missingAgent = new OpenCodeCliProvider({ + config: { + opencode_config: '/suite/opencode.json', + project_dir: '/repo', + format: 'default', + log_level: 'ERROR', + }, + }); + + assert.deepEqual(await missingAgent.callApi('prompt'), { + error: 'OpenCode CLI provider requires agent, opencode_config, project_dir, format, and log_level', + }); + + const invalidRetries = new OpenCodeCliProvider({ + config: { + agent: 'eval_light', + opencode_config: '/suite/opencode.json', + project_dir: '/repo', + format: 'default', + log_level: 'ERROR', + empty_output_retries: -1, + }, + runner: async () => 'unused', + }); + + assert.deepEqual(await invalidRetries.callApi('prompt'), { + error: 'OpenCode CLI provider requires empty_output_retries to be a non-negative integer', + }); +}); diff --git a/tests/evals/scripts/promptfoo.sh b/tests/evals/scripts/promptfoo.sh new file mode 100755 index 000000000..1e9c74ed4 --- /dev/null +++ b/tests/evals/scripts/promptfoo.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")/.." && pwd) +REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/../.." && pwd) +NODE_BIN="${npm_node_execpath:-$(command -v node)}" +OPENCODE_XDG_ROOT="$SCRIPT_DIR/.promptfoo/opencode-runtime" + +mkdir -p \ + "$SCRIPT_DIR/.promptfoo" \ + "$SCRIPT_DIR/.cache/promptfoo" \ + "$SCRIPT_DIR/.tmp" \ + "$SCRIPT_DIR/results/logs" \ + "$SCRIPT_DIR/output/media" + +mkdir -p "$OPENCODE_XDG_ROOT/state" + +export PROMPTFOO_CONFIG_DIR="$SCRIPT_DIR/.promptfoo" +export PROMPTFOO_CACHE_PATH="$SCRIPT_DIR/.cache/promptfoo" +export PROMPTFOO_LOG_DIR="$SCRIPT_DIR/results/logs" +export PROMPTFOO_MEDIA_PATH="$SCRIPT_DIR/output/media" +export PROMPTFOO_EVAL_TIMEOUT_MS="${PROMPTFOO_EVAL_TIMEOUT_MS:-900000}" +export PROMPTFOO_SCHEDULER_QUEUE_TIMEOUT_MS="${PROMPTFOO_SCHEDULER_QUEUE_TIMEOUT_MS:-900000}" +export CLAUDE_PLUGIN_ROOT="$REPO_ROOT" +export TMPDIR="$SCRIPT_DIR/.tmp" +export TMP="$TMPDIR" +export TEMP="$TMPDIR" +export XDG_STATE_HOME="$OPENCODE_XDG_ROOT/state" + +exec "$NODE_BIN" "$SCRIPT_DIR/scripts/run-promptfoo-with-guard.js" "$@" diff --git a/tests/evals/scripts/resolve-promptfoo-config.js b/tests/evals/scripts/resolve-promptfoo-config.js new file mode 100644 index 000000000..7f58ca983 --- /dev/null +++ b/tests/evals/scripts/resolve-promptfoo-config.js @@ -0,0 +1,161 @@ +const fs = require('node:fs'); +const path = require('node:path'); +const yaml = require('js-yaml'); + +const { loadEvalTierConfig, resolveEvalTier } = require('./eval-tier-config'); + +const EVAL_ROOT = path.resolve(__dirname, '..'); +const TMP_ROOT = path.join(EVAL_ROOT, '.tmp', 'resolved-configs'); + +function readYaml(relativePath) { + const normalizedPath = normalizeConfigPath(relativePath); + return yaml.load(fs.readFileSync(path.join(EVAL_ROOT, normalizedPath), 'utf8')); +} + +function resolveProviderBlock(evalTier) { + const suiteConfig = loadEvalTierConfig(); + const resolvedTier = resolveEvalTier(suiteConfig, evalTier); + + return { + id: resolveProviderId(suiteConfig.runtime.providerId), + config: { + agent: resolvedTier.agent, + opencode_config: suiteConfig.runtime.opencodeConfig, + project_dir: suiteConfig.runtime.projectDir, + format: suiteConfig.runtime.format, + log_level: suiteConfig.runtime.logLevel, + print_logs: suiteConfig.runtime.printLogs, + empty_output_retries: suiteConfig.runtime.emptyOutputRetries, + }, + }; +} + +function resolveProviderId(providerId) { + if (!providerId.startsWith('file://')) { + return providerId; + } + + const providerPath = providerId.slice('file://'.length); + if (path.isAbsolute(providerPath)) { + return providerId; + } + + return `file://${path.join(EVAL_ROOT, providerPath)}`; +} + +function resolveConfigFile(relativePath) { + const normalizedPath = normalizeConfigPath(relativePath); + const parsed = readYaml(normalizedPath); + const evalTier = parsed?.metadata?.eval_tier; + if (!evalTier) { + throw new Error(`${normalizedPath} is missing metadata.eval_tier`); + } + + const sourceConfigDir = path.dirname(path.join(EVAL_ROOT, normalizedPath)); + const targetConfigDir = path.dirname(path.join(TMP_ROOT, normalizedPath)); + + return { + ...rewriteRelativeFileUrls(parsed, sourceConfigDir, targetConfigDir), + providers: [resolveProviderBlock(evalTier)], + }; +} + +function writeResolvedConfig( + relativePath, + { + fsImpl = fs, + outputRoot = TMP_ROOT, + } = {}, +) { + const normalizedPath = normalizeConfigPath(relativePath); + const normalizedOutputRoot = normalizeOutputRoot(outputRoot); + + fsImpl.mkdirSync(normalizedOutputRoot, { recursive: true }); + const resolved = resolveConfigFile(normalizedPath); + const outputPath = resolveWithinRoot( + normalizedOutputRoot, + normalizedPath, + `Refusing to write resolved config outside output root: ${normalizedPath}`, + ); + fsImpl.mkdirSync(path.dirname(outputPath), { recursive: true }); + fsImpl.writeFileSync(outputPath, yaml.dump(resolved), 'utf8'); + return path.relative(EVAL_ROOT, outputPath); +} + +function normalizeConfigPath(relativePath) { + const resolvedPath = resolveWithinRoot( + EVAL_ROOT, + relativePath, + `Refusing to access config outside eval root: ${relativePath}`, + ); + return path.relative(EVAL_ROOT, resolvedPath); +} + +function normalizeOutputRoot(outputRoot) { + const resolvedRoot = path.resolve(outputRoot); + ensureWithinRoot( + resolvedRoot, + TMP_ROOT, + `Refusing to write resolved configs outside ${path.relative(EVAL_ROOT, TMP_ROOT)}`, + ); + return resolvedRoot; +} + +function resolveWithinRoot(root, candidatePath, errorMessage) { + const resolvedPath = path.resolve(root, candidatePath); + ensureWithinRoot(resolvedPath, root, errorMessage); + return resolvedPath; +} + +function ensureWithinRoot(candidatePath, root, errorMessage) { + const normalizedRoot = path.resolve(root); + const rootWithSeparator = `${normalizedRoot}${path.sep}`; + if (candidatePath !== normalizedRoot && !candidatePath.startsWith(rootWithSeparator)) { + throw new Error(errorMessage); + } +} + +function rewriteRelativeFileUrls(value, sourceConfigDir, targetConfigDir) { + if (Array.isArray(value)) { + return value.map((item) => rewriteRelativeFileUrls(item, sourceConfigDir, targetConfigDir)); + } + + if (value && typeof value === 'object') { + return Object.fromEntries( + Object.entries(value).map(([key, entryValue]) => [ + key, + rewriteRelativeFileUrls(entryValue, sourceConfigDir, targetConfigDir), + ]), + ); + } + + if (typeof value !== 'string' || !value.startsWith('file://')) { + return value; + } + + const match = /^file:\/\/([^:]+)(:.*)?$/.exec(value); + if (!match) { + return value; + } + + const [, fileTarget, suffix = ''] = match; + if (path.isAbsolute(fileTarget)) { + return value; + } + + const absoluteTarget = path.resolve(sourceConfigDir, fileTarget); + ensureWithinRoot( + absoluteTarget, + EVAL_ROOT, + `Refusing to rewrite file reference outside eval root: ${value}`, + ); + const rewrittenTarget = path.relative(targetConfigDir, absoluteTarget).split(path.sep).join('/'); + return `file://${rewrittenTarget}${suffix}`; +} + +module.exports = { + TMP_ROOT, + resolveConfigFile, + resolveProviderId, + writeResolvedConfig, +}; diff --git a/tests/evals/scripts/resolve-promptfoo-config.test.js b/tests/evals/scripts/resolve-promptfoo-config.test.js new file mode 100644 index 000000000..70fac3711 --- /dev/null +++ b/tests/evals/scripts/resolve-promptfoo-config.test.js @@ -0,0 +1,104 @@ +const assert = require('node:assert/strict'); +const test = require('node:test'); +const path = require('node:path'); + +const { + TMP_ROOT, + resolveConfigFile, + resolveProviderId, + writeResolvedConfig, +} = require('./resolve-promptfoo-config'); + +test('resolveConfigFile materializes an opencode provider from metadata.eval_tier', () => { + const resolved = resolveConfigFile('packages/harness-smoke/promptfooconfig.json'); + + assert.equal( + resolved.providers[0].id, + `file://${path.join(path.dirname(TMP_ROOT), '..', 'scripts', 'opencode-cli-provider.js')}`, + ); + assert.equal(resolved.providers[0].config.agent, 'eval_light'); + assert.equal(resolved.providers[0].config.format, 'default'); + assert.equal(resolved.providers[0].config.log_level, 'ERROR'); + assert.equal(resolved.providers[0].config.print_logs, false); + assert.equal(resolved.providers[0].config.empty_output_retries, 1); + assert.match(resolved.providers[0].config.opencode_config, /tests\/evals\/opencode\.json$/); + assert.equal(resolved.providers[0].config.project_dir, path.resolve(__dirname, '..', '..', '..')); + assert.equal('max_turns' in resolved.providers[0].config, false); + assert.equal('model' in resolved.providers[0].config, false); + assert.equal('provider_id' in resolved.providers[0].config, false); + assert.equal('tools' in resolved.providers[0].config, false); + assert.match(resolved.prompts[0], /harness-smoke/); +}); + +test('resolveConfigFile rejects configs missing metadata.eval_tier', () => { + const relativePath = 'scripts/fixtures/missing-eval-tier.json'; + + assert.throws( + () => resolveConfigFile(relativePath), + new RegExp(`${relativePath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')} is missing metadata\\.eval_tier`), + ); +}); + +test('resolveConfigFile rejects traversal outside the eval root', () => { + assert.throws( + () => resolveConfigFile('packages/../../foo.yaml'), + /Refusing to access config outside eval root: packages\/\.\.\/\.\.\/foo\.yaml/, + ); +}); + +test('writeResolvedConfig writes suite-owned resolved configs only under .tmp', () => { + const calls = []; + const relativePath = writeResolvedConfig( + 'packages/harness-smoke/promptfooconfig.json', + { + fsImpl: { + mkdirSync: (targetPath, options) => { + calls.push(['mkdir', targetPath, options]); + }, + writeFileSync: (targetPath, contents, encoding) => { + calls.push(['write', targetPath, contents, encoding]); + }, + }, + }, + ); + + assert.match(relativePath, /^\.tmp\/resolved-configs\/packages\/harness-smoke\/promptfooconfig\.json$/); + assert.deepEqual(calls[0], ['mkdir', TMP_ROOT, { recursive: true }]); + assert.deepEqual(calls[1], [ + 'mkdir', + path.join(TMP_ROOT, 'packages', 'harness-smoke'), + { recursive: true }, + ]); + assert.equal(calls[2][0], 'write'); + assert.equal(calls[2][1], path.join(TMP_ROOT, 'packages', 'harness-smoke', 'promptfooconfig.json')); + assert.match(calls[2][2], /file:\/\/.*\/scripts\/opencode-cli-provider\.js/); + assert.equal(calls[2][3], 'utf8'); +}); + +test('resolveProviderId makes local file providers stable from materialized configs', () => { + assert.equal( + resolveProviderId('file://scripts/opencode-cli-provider.js'), + `file://${path.join(path.dirname(TMP_ROOT), '..', 'scripts', 'opencode-cli-provider.js')}`, + ); + assert.equal(resolveProviderId('custom:provider'), 'custom:provider'); +}); + +test('writeResolvedConfig rejects traversal outside the resolved-config output root', () => { + assert.throws( + () => writeResolvedConfig( + 'packages/harness-smoke/promptfooconfig.json', + { + fsImpl: { + mkdirSync: () => { + throw new Error('should not mkdir'); + }, + writeFileSync: () => { + throw new Error('should not write'); + }, + }, + outputRoot: path.join(TMP_ROOT, '..'), + }, + ), + /Refusing to write resolved configs outside \.tmp\/resolved-configs/, + ); +}); diff --git a/tests/evals/scripts/run-promptfoo-with-guard.js b/tests/evals/scripts/run-promptfoo-with-guard.js new file mode 100644 index 000000000..f387795a4 --- /dev/null +++ b/tests/evals/scripts/run-promptfoo-with-guard.js @@ -0,0 +1,321 @@ +const { execFileSync, spawnSync } = require('node:child_process'); +const crypto = require('node:crypto'); +const fs = require('node:fs'); +const path = require('node:path'); + +const { writeResolvedConfig } = require('./resolve-promptfoo-config'); + +const REPO_ROOT = path.resolve(__dirname, '..', '..', '..'); +const EVAL_ROOT = path.join(REPO_ROOT, 'tests', 'evals'); +const PROMPTFOO_ENTRYPOINT = path.join( + EVAL_ROOT, + 'node_modules', + 'promptfoo', + 'dist', + 'src', + 'entrypoint.js', +); + +const ALLOWED_ARTIFACT_PREFIXES = [ + 'tests/evals/.cache/', + 'tests/evals/.promptfoo/', + 'tests/evals/.tmp/', + 'tests/evals/output/', + 'tests/evals/results/', +]; + +function runGitLines(args) { + const output = execFileSync( + 'git', + ['-C', REPO_ROOT, ...args], + { encoding: 'utf8' }, + ); + + return output + .split(/\r?\n/) + .map((line) => line.trim()) + .filter(Boolean); +} + +function hashRepoFile(filePath) { + const absolutePath = path.join(REPO_ROOT, filePath); + if (!fs.existsSync(absolutePath)) { + return 'missing'; + } + + const stat = fs.statSync(absolutePath); + if (!stat.isFile()) { + return `non-file:${stat.mode}`; + } + + return crypto + .createHash('sha256') + .update(fs.readFileSync(absolutePath)) + .digest('hex'); +} + +function hashPaths(paths) { + return new Map([...paths].map((filePath) => [filePath, hashRepoFile(filePath)])); +} + +function collectGitSnapshot() { + const tracked = new Set( + runGitLines(['diff', '--name-only', 'HEAD', '--', 'tests/evals']), + ); + const untracked = new Set( + runGitLines(['ls-files', '--others', '--exclude-standard', '--', 'tests/evals']), + ); + + return { + tracked, + untracked, + trackedHashes: hashPaths(tracked), + untrackedHashes: hashPaths(untracked), + }; +} + +function isAllowedArtifactPath(filePath) { + return ALLOWED_ARTIFACT_PREFIXES.some((prefix) => filePath.startsWith(prefix)); +} + +function collectNewPaths(beforeSet, afterSet) { + return [...afterSet].filter((filePath) => !beforeSet.has(filePath)); +} + +function collectChangedPreexistingPaths(beforeSet, afterSet, beforeHashes, afterHashes) { + if (!beforeHashes || !afterHashes) { + return []; + } + + return [...afterSet].filter((filePath) => ( + beforeSet.has(filePath) && beforeHashes.get(filePath) !== afterHashes.get(filePath) + )); +} + +function detectCleanupViolations(before, after) { + const newTracked = collectNewPaths(before.tracked, after.tracked); + const newUntracked = collectNewPaths(before.untracked, after.untracked); + const changedTracked = collectChangedPreexistingPaths( + before.tracked, + after.tracked, + before.trackedHashes, + after.trackedHashes, + ); + const changedUntracked = collectChangedPreexistingPaths( + before.untracked, + after.untracked, + before.untrackedHashes, + after.untrackedHashes, + ); + + return [...newTracked, ...newUntracked, ...changedTracked, ...changedUntracked] + .filter((filePath) => !isAllowedArtifactPath(filePath)) + .sort(); +} + +function formatViolationMessage(paths) { + return [ + 'Eval run dirtied files outside approved artifact directories:', + ...paths.map((filePath) => `- ${filePath}`), + 'Allowed artifact roots: tests/evals/.cache/, tests/evals/.promptfoo/, tests/evals/.tmp/, tests/evals/output/, tests/evals/results/', + ].join('\n'); +} + +function resolveRepoPath(filePath, repoRoot = REPO_ROOT) { + const resolved = path.resolve(repoRoot, filePath); + const repoRootWithSeparator = `${repoRoot}${path.sep}`; + if (resolved !== repoRoot && !resolved.startsWith(repoRootWithSeparator)) { + throw new Error(`Refusing to restore path outside repository: ${filePath}`); + } + return resolved; +} + +function restoreCleanupViolations( + paths, + { + execFileSync: execFile = execFileSync, + repoRoot = REPO_ROOT, + resolveRepoPath: resolvePath = (filePath) => resolveRepoPath(filePath, repoRoot), + rmSync = fs.rmSync, + runGitLines: gitLines = runGitLines, + } = {}, +) { + if (paths.length === 0) { + return; + } + + const trackedPaths = new Set(gitLines(['ls-files', '--', ...paths])); + const trackedViolations = paths.filter((filePath) => trackedPaths.has(filePath)); + const untrackedViolations = paths.filter((filePath) => !trackedPaths.has(filePath)); + + for (const filePath of untrackedViolations) { + rmSync(resolvePath(filePath), { force: true, recursive: true }); + } + + if (trackedViolations.length > 0) { + execFile( + 'git', + ['-C', repoRoot, 'checkout', '--', ...trackedViolations], + { stdio: 'ignore' }, + ); + } +} + +function splitPromptfooInvocations(argv) { + const sharedArgs = []; + const configArgs = []; + + for (let index = 0; index < argv.length; index += 1) { + const token = argv[index]; + if (token === '-c') { + const configPath = argv[index + 1]; + if (!configPath) { + throw new Error('Missing config path after -c'); + } + + configArgs.push(configPath); + index += 1; + continue; + } + + sharedArgs.push(token); + } + + if (configArgs.length === 0) { + return [sharedArgs]; + } + + return configArgs.map((configPath) => [...sharedArgs, '-c', configPath]); +} + +function materializeInvocation(argv, { writeResolvedConfig: writeResolved = writeResolvedConfig } = {}) { + const next = []; + + for (let index = 0; index < argv.length; index += 1) { + const token = argv[index]; + if (token === '-c') { + const configPath = argv[index + 1]; + if (!configPath) { + throw new Error('Missing config path after -c'); + } + + next.push('-c'); + next.push( + shouldMaterializeConfig(configPath) + ? writeResolved(configPath) + : configPath, + ); + index += 1; + continue; + } + + next.push(token); + } + + return next; +} + +function applyDefaultEvalConcurrency(argv) { + const hasConcurrency = argv.some( + (token) => token === '--max-concurrency' || token.startsWith('--max-concurrency='), + ); + if (argv[0] !== 'eval' || hasConcurrency) { + return argv; + } + + return ['eval', '--max-concurrency', '4', ...argv.slice(1)]; +} + +function shouldMaterializeConfig(configPath) { + if (!configPath || configPath.startsWith('.tmp/resolved-configs/')) { + return false; + } + + return configPath.endsWith('.yaml') || configPath.endsWith('.yml') || configPath.endsWith('.json'); +} + +function runPromptfooInvocation( + argv, + { + materializeInvocation: materialize = materializeInvocation, + spawnSync: spawn = spawnSync, + } = {}, +) { + const materializedArgv = applyDefaultEvalConcurrency(materialize(argv)); + const result = spawn( + process.execPath, + [PROMPTFOO_ENTRYPOINT, ...materializedArgv], + { + cwd: EVAL_ROOT, + env: process.env, + stdio: 'inherit', + }, + ); + + if (result.error) { + throw result.error; + } + + if (result.status !== null) { + return result.status; + } + + if (result.signal) { + console.error(`promptfoo exited due to signal ${result.signal}`); + return 1; + } + + return 1; +} + +function main( + argv = process.argv.slice(2), + { + collectGitSnapshot: collectSnapshot = collectGitSnapshot, + detectCleanupViolations: detectViolations = detectCleanupViolations, + formatViolationMessage: formatViolations = formatViolationMessage, + restoreCleanupViolations: restoreViolations = restoreCleanupViolations, + runPromptfooInvocation: runInvocation = runPromptfooInvocation, + splitPromptfooInvocations: splitInvocations = splitPromptfooInvocations, + } = {}, +) { + for (const invocation of splitInvocations(argv)) { + const before = collectSnapshot(); + const status = runInvocation(invocation); + const after = collectSnapshot(); + const violations = detectViolations(before, after); + + if (violations.length > 0) { + const preexistingPaths = new Set([...before.tracked, ...before.untracked]); + restoreViolations(violations.filter((filePath) => !preexistingPaths.has(filePath))); + console.error(formatViolations(violations)); + return 1; + } + + if (status !== 0) { + return status; + } + } + + return 0; +} + +if (require.main === module) { + process.exitCode = main(); +} + +module.exports = { + ALLOWED_ARTIFACT_PREFIXES, + collectGitSnapshot, + detectCleanupViolations, + formatViolationMessage, + hashPaths, + isAllowedArtifactPath, + main, + materializeInvocation, + runPromptfooInvocation, + applyDefaultEvalConcurrency, + restoreCleanupViolations, + shouldMaterializeConfig, + splitPromptfooInvocations, +}; diff --git a/tests/evals/scripts/run-promptfoo-with-guard.test.js b/tests/evals/scripts/run-promptfoo-with-guard.test.js new file mode 100644 index 000000000..b3b66a6e2 --- /dev/null +++ b/tests/evals/scripts/run-promptfoo-with-guard.test.js @@ -0,0 +1,610 @@ +const assert = require('node:assert/strict'); +const test = require('node:test'); + +const { + ALLOWED_ARTIFACT_PREFIXES, + applyDefaultEvalConcurrency, + detectCleanupViolations, + main, + materializeInvocation, + restoreCleanupViolations, + runPromptfooInvocation, + shouldMaterializeConfig, + splitPromptfooInvocations, +} = require('./run-promptfoo-with-guard'); + +test('detectCleanupViolations ignores new files under approved eval artifact directories', () => { + const before = { + tracked: new Set(), + untracked: new Set(), + }; + const after = { + tracked: new Set(), + untracked: new Set([ + 'tests/evals/output/runs/harness-smoke/run-1/transcript.txt', + 'tests/evals/results/logs/promptfoo.log', + 'tests/evals/.tmp/trace.json', + 'tests/evals/.cache/promptfoo/cache.db', + 'tests/evals/.promptfoo/promptfoo.db', + ]), + }; + + const violations = detectCleanupViolations(before, after); + + assert.deepEqual(violations, []); +}); + +test('detectCleanupViolations reports newly dirtied tracked files outside approved artifact directories', () => { + const before = { + tracked: new Set(['tests/evals/package.json']), + untracked: new Set(), + }; + const after = { + tracked: new Set([ + 'tests/evals/package.json', + 'tests/evals/fixtures/harness-smoke/catalog.json', + 'tests/evals/package-lock.json', + ]), + untracked: new Set(), + }; + + const violations = detectCleanupViolations(before, after); + + assert.deepEqual(violations, [ + 'tests/evals/fixtures/harness-smoke/catalog.json', + 'tests/evals/package-lock.json', + ]); +}); + +test('detectCleanupViolations reports new untracked files outside approved artifact directories', () => { + const before = { + tracked: new Set(), + untracked: new Set(['tests/evals/results/logs/already-there.log']), + }; + const after = { + tracked: new Set(), + untracked: new Set([ + 'tests/evals/results/logs/already-there.log', + 'tests/evals/eval-dimcustomer.log', + 'tests/evals/tests/evals/eval_output.log', + ]), + }; + + const violations = detectCleanupViolations(before, after); + + assert.deepEqual(violations, [ + 'tests/evals/eval-dimcustomer.log', + 'tests/evals/tests/evals/eval_output.log', + ]); +}); + +test('detectCleanupViolations reports changed pre-existing tracked files outside approved artifact directories', () => { + const before = { + tracked: new Set(['tests/evals/fixtures/scenario/catalog.json']), + untracked: new Set(), + trackedHashes: new Map([ + ['tests/evals/fixtures/scenario/catalog.json', 'before'], + ]), + untrackedHashes: new Map(), + }; + const after = { + tracked: new Set(['tests/evals/fixtures/scenario/catalog.json']), + untracked: new Set(), + trackedHashes: new Map([ + ['tests/evals/fixtures/scenario/catalog.json', 'after'], + ]), + untrackedHashes: new Map(), + }; + + const violations = detectCleanupViolations(before, after); + + assert.deepEqual(violations, ['tests/evals/fixtures/scenario/catalog.json']); +}); + +test('detectCleanupViolations reports changed pre-existing untracked files outside approved artifact directories', () => { + const before = { + tracked: new Set(), + untracked: new Set(['tests/evals/manual-debug.json']), + trackedHashes: new Map(), + untrackedHashes: new Map([ + ['tests/evals/manual-debug.json', 'before'], + ]), + }; + const after = { + tracked: new Set(), + untracked: new Set(['tests/evals/manual-debug.json']), + trackedHashes: new Map(), + untrackedHashes: new Map([ + ['tests/evals/manual-debug.json', 'after'], + ]), + }; + + const violations = detectCleanupViolations(before, after); + + assert.deepEqual(violations, ['tests/evals/manual-debug.json']); +}); + +test('detectCleanupViolations ignores changed pre-existing files under approved eval artifact directories', () => { + const before = { + tracked: new Set(), + untracked: new Set(['tests/evals/output/runs/eval/debug/transcript.txt']), + trackedHashes: new Map(), + untrackedHashes: new Map([ + ['tests/evals/output/runs/eval/debug/transcript.txt', 'before'], + ]), + }; + const after = { + tracked: new Set(), + untracked: new Set(['tests/evals/output/runs/eval/debug/transcript.txt']), + trackedHashes: new Map(), + untrackedHashes: new Map([ + ['tests/evals/output/runs/eval/debug/transcript.txt', 'after'], + ]), + }; + + const violations = detectCleanupViolations(before, after); + + assert.deepEqual(violations, []); +}); + +test('allowed artifact prefixes stay limited to the dedicated eval output roots', () => { + assert.deepEqual(ALLOWED_ARTIFACT_PREFIXES, [ + 'tests/evals/.cache/', + 'tests/evals/.promptfoo/', + 'tests/evals/.tmp/', + 'tests/evals/output/', + 'tests/evals/results/', + ]); +}); + +test('splitPromptfooInvocations preserves shared args and runs each config separately', () => { + const invocations = splitPromptfooInvocations([ + 'eval', + '--no-cache', + '--max-concurrency', + '1', + '--filter-pattern', + '^\\[smoke\\]', + '-c', + 'packages/harness-smoke/promptfooconfig.json', + '-c', + 'packages/harness-smoke/promptfooconfig.json', + ]); + + assert.deepEqual(invocations, [ + [ + 'eval', + '--no-cache', + '--max-concurrency', + '1', + '--filter-pattern', + '^\\[smoke\\]', + '-c', + 'packages/harness-smoke/promptfooconfig.json', + ], + [ + 'eval', + '--no-cache', + '--max-concurrency', + '1', + '--filter-pattern', + '^\\[smoke\\]', + '-c', + 'packages/harness-smoke/promptfooconfig.json', + ], + ]); +}); + +test('splitPromptfooInvocations keeps single-config and no-config argv unchanged', () => { + assert.deepEqual( + splitPromptfooInvocations([ + 'view', + '-c', + 'packages/harness-smoke/promptfooconfig.json', + ]), + [[ + 'view', + '-c', + 'packages/harness-smoke/promptfooconfig.json', + ]], + ); + + assert.deepEqual( + splitPromptfooInvocations(['list']), + [['list']], + ); +}); + +test('splitPromptfooInvocations rejects a dangling -c flag', () => { + assert.throws( + () => splitPromptfooInvocations(['eval', '-c']), + /Missing config path after -c/, + ); +}); + +test('materializeInvocation resolves suite-local package configs into tests/evals/.tmp', () => { + const materialized = materializeInvocation( + ['eval', '-c', 'packages/harness-smoke/promptfooconfig.json', '-c', 'packages/harness-smoke/promptfooconfig.json'], + { + writeResolvedConfig: (configPath) => `.tmp/resolved-configs/${configPath}`, + }, + ); + + assert.deepEqual(materialized, [ + 'eval', + '-c', + '.tmp/resolved-configs/packages/harness-smoke/promptfooconfig.json', + '-c', + '.tmp/resolved-configs/packages/harness-smoke/promptfooconfig.json', + ]); +}); + +test('shouldMaterializeConfig skips already resolved configs and non-config args', () => { + assert.equal(shouldMaterializeConfig('.tmp/resolved-configs/packages/foo.yaml'), false); + assert.equal(shouldMaterializeConfig('packages/foo.yaml'), true); + assert.equal(shouldMaterializeConfig('packages/foo.json'), true); + assert.equal(shouldMaterializeConfig('packages/harness-smoke/promptfooconfig.json'), true); + assert.equal(shouldMaterializeConfig('--no-cache'), false); +}); + +test('applyDefaultEvalConcurrency runs four eval cases unless caller overrides concurrency', () => { + assert.deepEqual( + applyDefaultEvalConcurrency(['eval', '--no-cache', '-c', 'packages/foo.yaml']), + ['eval', '--max-concurrency', '4', '--no-cache', '-c', 'packages/foo.yaml'], + ); + + assert.deepEqual( + applyDefaultEvalConcurrency(['eval', '--max-concurrency', '2', '-c', 'packages/foo.yaml']), + ['eval', '--max-concurrency', '2', '-c', 'packages/foo.yaml'], + ); + + assert.deepEqual( + applyDefaultEvalConcurrency(['eval', '--max-concurrency=3', '-c', 'packages/foo.yaml']), + ['eval', '--max-concurrency=3', '-c', 'packages/foo.yaml'], + ); + + assert.deepEqual( + applyDefaultEvalConcurrency(['view']), + ['view'], + ); +}); + +test('runPromptfooInvocation never passes unresolved package configs to promptfoo', () => { + const spawns = []; + const status = runPromptfooInvocation( + ['eval', '-c', 'packages/harness-smoke/promptfooconfig.json'], + { + materializeInvocation: () => ['eval', '-c', '.tmp/resolved-configs/packages/harness-smoke/promptfooconfig.json'], + spawnSync: (command, args) => { + spawns.push([command, args]); + return { status: 0 }; + }, + }, + ); + + assert.equal(status, 0); + assert.deepEqual(spawns, [[ + process.execPath, + [ + require('node:path').join( + require('node:path').resolve(__dirname, '..'), + 'node_modules', + 'promptfoo', + 'dist', + 'src', + 'entrypoint.js', + ), + 'eval', + '--max-concurrency', + '4', + '-c', + '.tmp/resolved-configs/packages/harness-smoke/promptfooconfig.json', + ], + ]]); +}); + +test('main runs split promptfoo invocations sequentially and returns success when clean', () => { + const invocations = []; + const snapshots = [ + { tracked: new Set(), untracked: new Set() }, + { tracked: new Set(), untracked: new Set() }, + { tracked: new Set(), untracked: new Set() }, + { tracked: new Set(), untracked: new Set() }, + ]; + + const status = main( + ['eval', '--filter-pattern', '^\\[smoke\\]', '-c', 'a.yaml', '-c', 'b.yaml'], + { + collectGitSnapshot: () => snapshots.shift(), + detectCleanupViolations: () => [], + formatViolationMessage: () => 'unused', + runPromptfooInvocation: (argv) => { + invocations.push(argv); + return 0; + }, + }, + ); + + assert.equal(status, 0); + assert.deepEqual(invocations, [ + ['eval', '--filter-pattern', '^\\[smoke\\]', '-c', 'a.yaml'], + ['eval', '--filter-pattern', '^\\[smoke\\]', '-c', 'b.yaml'], + ]); +}); + +test('main stops after the first failing split invocation', () => { + const invocations = []; + const snapshots = [ + { tracked: new Set(), untracked: new Set() }, + { tracked: new Set(), untracked: new Set() }, + { tracked: new Set(), untracked: new Set() }, + { tracked: new Set(), untracked: new Set() }, + ]; + + const status = main( + ['eval', '--filter-pattern', '^\\[smoke\\]', '-c', 'a.yaml', '-c', 'b.yaml', '-c', 'c.yaml'], + { + collectGitSnapshot: () => snapshots.shift(), + detectCleanupViolations: () => [], + formatViolationMessage: () => 'unused', + runPromptfooInvocation: (argv) => { + invocations.push(argv); + return invocations.length === 2 ? 100 : 0; + }, + }, + ); + + assert.equal(status, 100); + assert.deepEqual(invocations, [ + ['eval', '--filter-pattern', '^\\[smoke\\]', '-c', 'a.yaml'], + ['eval', '--filter-pattern', '^\\[smoke\\]', '-c', 'b.yaml'], + ]); +}); + +test('main reports cleanup violations even after successful invocations', () => { + const errors = []; + const originalError = console.error; + const restored = []; + const snapshots = [ + { tracked: new Set(), untracked: new Set() }, + { tracked: new Set(['tests/evals/fixtures/x.json']), untracked: new Set() }, + ]; + + console.error = (message) => { + errors.push(message); + }; + + try { + const status = main( + ['eval', '-c', 'a.yaml', '-c', 'b.yaml'], + { + collectGitSnapshot: () => snapshots.shift(), + detectCleanupViolations: () => ['tests/evals/fixtures/x.json'], + formatViolationMessage: (paths) => `violations:${paths.join(',')}`, + restoreCleanupViolations: (paths) => { + restored.push(...paths); + }, + runPromptfooInvocation: () => 0, + }, + ); + + assert.equal(status, 1); + assert.deepEqual(errors, ['violations:tests/evals/fixtures/x.json']); + assert.deepEqual(restored, ['tests/evals/fixtures/x.json']); + } finally { + console.error = originalError; + } +}); + +test('restoreCleanupViolations removes untracked blockers before restoring tracked files', () => { + const calls = []; + + restoreCleanupViolations( + [ + 'tests/evals/fixtures/blocker', + 'tests/evals/fixtures/blocker/catalog.json', + ], + { + runGitLines: (args) => { + calls.push(['git-lines', ...args]); + return ['tests/evals/fixtures/blocker/catalog.json']; + }, + execFileSync: (command, args) => { + calls.push(['exec', command, ...args]); + }, + repoRoot: 'REPO_ROOT', + resolveRepoPath: (filePath) => filePath, + rmSync: (filePath, options) => { + calls.push(['rm', filePath, options]); + }, + }, + ); + + assert.deepEqual(calls, [ + [ + 'git-lines', + 'ls-files', + '--', + 'tests/evals/fixtures/blocker', + 'tests/evals/fixtures/blocker/catalog.json', + ], + [ + 'rm', + 'tests/evals/fixtures/blocker', + { force: true, recursive: true }, + ], + [ + 'exec', + 'git', + '-C', + 'REPO_ROOT', + 'checkout', + '--', + 'tests/evals/fixtures/blocker/catalog.json', + ], + ]); +}); + +test('main restores cleanup violations before returning a promptfoo failure', () => { + const errors = []; + const originalError = console.error; + const restored = []; + const snapshots = [ + { tracked: new Set(), untracked: new Set() }, + { tracked: new Set(['tests/evals/fixtures/dirty.json']), untracked: new Set() }, + ]; + + console.error = (message) => { + errors.push(message); + }; + + try { + const status = main( + ['eval', '-c', 'a.yaml'], + { + collectGitSnapshot: () => snapshots.shift(), + detectCleanupViolations: () => ['tests/evals/fixtures/dirty.json'], + formatViolationMessage: () => 'violation', + restoreCleanupViolations: (paths) => { + restored.push(...paths); + }, + runPromptfooInvocation: () => 99, + }, + ); + + assert.equal(status, 1); + assert.deepEqual(errors, ['violation']); + assert.deepEqual(restored, ['tests/evals/fixtures/dirty.json']); + } finally { + console.error = originalError; + } +}); + +test('main does not restore pre-existing dirty files that changed during promptfoo', () => { + const errors = []; + const originalError = console.error; + const restored = []; + const snapshots = [ + { + tracked: new Set(['tests/evals/fixtures/already-dirty.json']), + untracked: new Set(), + trackedHashes: new Map([['tests/evals/fixtures/already-dirty.json', 'before']]), + untrackedHashes: new Map(), + }, + { + tracked: new Set(['tests/evals/fixtures/already-dirty.json']), + untracked: new Set(), + trackedHashes: new Map([['tests/evals/fixtures/already-dirty.json', 'after']]), + untrackedHashes: new Map(), + }, + ]; + + console.error = (message) => { + errors.push(message); + }; + + try { + const status = main( + ['eval', '-c', 'a.yaml'], + { + collectGitSnapshot: () => snapshots.shift(), + formatViolationMessage: (paths) => `violations:${paths.join(',')}`, + restoreCleanupViolations: (paths) => { + restored.push(...paths); + }, + runPromptfooInvocation: () => 0, + }, + ); + + assert.equal(status, 1); + assert.deepEqual(errors, ['violations:tests/evals/fixtures/already-dirty.json']); + assert.deepEqual(restored, []); + } finally { + console.error = originalError; + } +}); + +test('main checks cleanup violations after each split invocation', () => { + const errors = []; + const originalError = console.error; + const invocations = []; + const restored = []; + const snapshots = [ + { tracked: new Set(), untracked: new Set() }, + { tracked: new Set(['tests/evals/fixtures/dirty.json']), untracked: new Set() }, + ]; + + console.error = (message) => { + errors.push(message); + }; + + try { + const status = main( + ['eval', '-c', 'a.yaml', '-c', 'b.yaml'], + { + collectGitSnapshot: () => snapshots.shift(), + detectCleanupViolations: (before, after) => { + if (before.tracked.size === 0 && after.tracked.size === 1) { + return ['tests/evals/fixtures/dirty.json']; + } + return []; + }, + formatViolationMessage: (paths) => `violations:${paths.join(',')}`, + restoreCleanupViolations: (paths) => { + restored.push(...paths); + }, + runPromptfooInvocation: (argv) => { + invocations.push(argv); + return 0; + }, + }, + ); + + assert.equal(status, 1); + assert.deepEqual(invocations, [['eval', '-c', 'a.yaml']]); + assert.deepEqual(errors, ['violations:tests/evals/fixtures/dirty.json']); + assert.deepEqual(restored, ['tests/evals/fixtures/dirty.json']); + } finally { + console.error = originalError; + } +}); + +test('main still fails for dirty paths outside allowed roots after config materialization', () => { + const errors = []; + const originalError = console.error; + const restored = []; + const invocations = []; + const snapshots = [ + { tracked: new Set(), untracked: new Set() }, + { tracked: new Set(['tests/evals/packages/harness-smoke/promptfooconfig.json']), untracked: new Set() }, + ]; + + console.error = (message) => { + errors.push(message); + }; + + try { + const status = main( + ['eval', '-c', 'packages/harness-smoke/promptfooconfig.json'], + { + collectGitSnapshot: () => snapshots.shift(), + detectCleanupViolations: () => ['tests/evals/packages/harness-smoke/promptfooconfig.json'], + formatViolationMessage: (paths) => `violations:${paths.join(',')}`, + restoreCleanupViolations: (paths) => { + restored.push(...paths); + }, + runPromptfooInvocation: (argv) => { + invocations.push(argv); + return 0; + }, + }, + ); + + assert.equal(status, 1); + assert.deepEqual(invocations, [['eval', '-c', 'packages/harness-smoke/promptfooconfig.json']]); + assert.deepEqual(errors, ['violations:tests/evals/packages/harness-smoke/promptfooconfig.json']); + assert.deepEqual(restored, ['tests/evals/packages/harness-smoke/promptfooconfig.json']); + } finally { + console.error = originalError; + } +}); diff --git a/tests/evals/scripts/worktree-script.test.js b/tests/evals/scripts/worktree-script.test.js new file mode 100644 index 000000000..2eb1a1e86 --- /dev/null +++ b/tests/evals/scripts/worktree-script.test.js @@ -0,0 +1,115 @@ +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const os = require('node:os'); +const path = require('node:path'); +const { spawnSync } = require('node:child_process'); +const test = require('node:test'); + +const EVAL_ROOT = path.resolve(__dirname, '..'); +const REPO_ROOT = path.resolve(EVAL_ROOT, '..', '..'); +const SCRIPT_PATH = path.join(REPO_ROOT, 'scripts', 'worktree.sh'); + +function writeExecutable(filePath, body) { + fs.writeFileSync(filePath, body, 'utf8'); + fs.chmodSync(filePath, 0o755); +} + +function createBaseEnv(tmpDir) { + const binDir = path.join(tmpDir, 'bin'); + const logPath = path.join(tmpDir, 'calls.log'); + const worktreeBase = path.join(tmpDir, 'worktrees'); + + fs.mkdirSync(binDir, { recursive: true }); + writeExecutable( + path.join(binDir, 'git'), + `#!/usr/bin/env bash +set -euo pipefail +echo "git $*" >> "${logPath}" + +if [[ "$1" == "show-ref" ]]; then + exit 1 +fi + +if [[ "$1" == "worktree" && "$2" == "list" ]]; then + exit 0 +fi + +if [[ "$1" == "worktree" && "$2" == "add" ]]; then + if [[ "$3" == "-b" ]]; then + path="$5" + else + path="$3" + fi + mkdir -p "$path/app" "$path/tests/evals" + printf '{"private":true}\\n' > "$path/app/package.json" + printf '{"lockfileVersion":3}\\n' > "$path/app/package-lock.json" + printf '{"private":true}\\n' > "$path/tests/evals/package.json" + printf '{"lockfileVersion":3}\\n' > "$path/tests/evals/package-lock.json" + exit 0 +fi + +echo "unexpected git invocation: $*" >&2 +exit 99 +`, + ); + writeExecutable( + path.join(binDir, 'npm'), + `#!/usr/bin/env bash +set -euo pipefail +echo "npm $*" >> "${logPath}" +exit 0 +`, + ); + + return { + env: { + ...process.env, + PATH: `${binDir}:${process.env.PATH}`, + WORKTREE_BASE_DIR: worktreeBase, + }, + logPath, + worktreeBase, + }; +} + +test('worktree helper links Promptfoo state back to the source checkout', () => { + const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'skill-builder-worktree-')); + const promptfooRoot = path.join(REPO_ROOT, 'tests', 'evals', '.promptfoo'); + const promptfooWasPresent = fs.existsSync(promptfooRoot); + const promptfooWasSymlink = promptfooWasPresent && fs.lstatSync(promptfooRoot).isSymbolicLink(); + + assert.equal(fs.existsSync(SCRIPT_PATH), true); + + try { + const { env, logPath, worktreeBase } = createBaseEnv(tmpDir); + const result = spawnSync(SCRIPT_PATH, ['feature/eval-state-link'], { + cwd: REPO_ROOT, + env, + encoding: 'utf8', + }); + + assert.equal(result.status, 0, result.stderr); + + const worktreePath = path.join(worktreeBase, 'feature', 'eval-state-link'); + const worktreePromptfoo = path.join(worktreePath, 'tests', 'evals', '.promptfoo'); + const stat = fs.lstatSync(worktreePromptfoo); + + assert.equal(stat.isSymbolicLink(), true); + assert.equal(fs.readlinkSync(worktreePromptfoo), promptfooRoot); + assert.match(result.stdout, /PROMPTFOO_DB: symlink /); + const npmCalls = fs.readFileSync(logPath, 'utf8').match(/npm ci --no-audit --no-fund/g) ?? []; + assert.equal(npmCalls.length, 2); + } finally { + if (!promptfooWasPresent && fs.existsSync(promptfooRoot)) { + fs.rmSync(promptfooRoot, { recursive: true, force: true }); + } else if ( + promptfooWasPresent && + promptfooWasSymlink && + fs.existsSync(promptfooRoot) && + !fs.lstatSync(promptfooRoot).isSymbolicLink() + ) { + fs.rmSync(promptfooRoot, { recursive: true, force: true }); + } + fs.rmSync(tmpDir, { recursive: true, force: true }); + } +});