diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..5958686 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "changelog": [ + "@changesets/changelog-github", + { "repo": "agentvision/agentvision" } + ], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch" +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cd16ed0 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + ci: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [20, 22] + + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: pnpm + + - run: pnpm install --frozen-lockfile + + - run: pnpm --filter @agentvision/core build + + - run: pnpm typecheck + + - run: pnpm build + + - run: pnpm test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..9f2af6b --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,49 @@ +name: Publish + +on: + push: + branches: [main] + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm typecheck + - run: pnpm build + - run: pnpm test + + publish: + needs: ci + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + id-token: write + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + registry-url: https://registry.npmjs.org + - run: pnpm install --frozen-lockfile + - run: pnpm build + - uses: changesets/action@v1 + with: + version: pnpm changeset version + publish: pnpm changeset publish + title: "chore: version packages" + commit: "chore: version packages" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/package.json b/package.json index 3ca3524..02e035e 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,18 @@ "build": "pnpm -r build", "dev": "pnpm --filter agentvision dev", "lint": "pnpm -r lint", - "typecheck": "pnpm -r typecheck" + "typecheck": "pnpm -r typecheck", + "test": "vitest run", + "test:watch": "vitest", + "changeset": "changeset" }, "devDependencies": { - "typescript": "^5.7.0" + "@changesets/changelog-github": "^0.6.0", + "@changesets/cli": "^2.30.0", + "typescript": "^5.7.0", + "vitest": "^4.1.0" }, + "packageManager": "pnpm@10.29.3", "engines": { "node": ">=20" } diff --git a/packages/cli/package.json b/packages/cli/package.json index d7e680e..1fe5087 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -10,6 +10,11 @@ "dist/", "README.md" ], + "repository": { + "type": "git", + "url": "https://github.com/agentvision/agentvision.git", + "directory": "packages/cli" + }, "keywords": [ "ai", "agent", @@ -33,5 +38,9 @@ "@types/node": "^25.5.0", "tsup": "^8.4.0", "typescript": "^5.7.0" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" } } diff --git a/packages/core/src/__fixtures__/test-project-1/.mcp.json b/packages/core/src/__fixtures__/test-project-1/.mcp.json new file mode 100644 index 0000000..38531fe --- /dev/null +++ b/packages/core/src/__fixtures__/test-project-1/.mcp.json @@ -0,0 +1,11 @@ +{ + "mcpServers": { + "filesystem": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] + }, + "remote-server": { + "url": "https://mcp.example.com/api" + } + } +} diff --git a/packages/core/src/__fixtures__/test-project-1/CLAUDE.md b/packages/core/src/__fixtures__/test-project-1/CLAUDE.md new file mode 100644 index 0000000..d0287ac --- /dev/null +++ b/packages/core/src/__fixtures__/test-project-1/CLAUDE.md @@ -0,0 +1,7 @@ +# Project Instructions + +This is a test project for Claude Code. + +## Rules +- Use TypeScript +- Write tests diff --git a/packages/core/src/__fixtures__/test-project-2/.cursor/mcp.json b/packages/core/src/__fixtures__/test-project-2/.cursor/mcp.json new file mode 100644 index 0000000..438376e --- /dev/null +++ b/packages/core/src/__fixtures__/test-project-2/.cursor/mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "filesystem": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] + } + } +} diff --git a/packages/core/src/__fixtures__/test-project-2/.cursorrules b/packages/core/src/__fixtures__/test-project-2/.cursorrules new file mode 100644 index 0000000..3b6d078 --- /dev/null +++ b/packages/core/src/__fixtures__/test-project-2/.cursorrules @@ -0,0 +1,2 @@ +Use TypeScript with strict mode enabled. +Prefer functional patterns over classes. diff --git a/packages/core/src/__fixtures__/test-project-3-multi/.cursor/mcp.json b/packages/core/src/__fixtures__/test-project-3-multi/.cursor/mcp.json new file mode 100644 index 0000000..438376e --- /dev/null +++ b/packages/core/src/__fixtures__/test-project-3-multi/.cursor/mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "filesystem": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] + } + } +} diff --git a/packages/core/src/__fixtures__/test-project-3-multi/.cursorrules b/packages/core/src/__fixtures__/test-project-3-multi/.cursorrules new file mode 100644 index 0000000..ef60bb8 --- /dev/null +++ b/packages/core/src/__fixtures__/test-project-3-multi/.cursorrules @@ -0,0 +1 @@ +Use TypeScript. diff --git a/packages/core/src/__fixtures__/test-project-3-multi/CLAUDE.md b/packages/core/src/__fixtures__/test-project-3-multi/CLAUDE.md new file mode 100644 index 0000000..88982f5 --- /dev/null +++ b/packages/core/src/__fixtures__/test-project-3-multi/CLAUDE.md @@ -0,0 +1,3 @@ +# Instructions + +Multi-agent project. diff --git a/packages/core/src/__fixtures__/test-project-4-broken/.mcp.json b/packages/core/src/__fixtures__/test-project-4-broken/.mcp.json new file mode 100644 index 0000000..e27e11e --- /dev/null +++ b/packages/core/src/__fixtures__/test-project-4-broken/.mcp.json @@ -0,0 +1 @@ +{ invalid json here \ No newline at end of file diff --git a/packages/core/src/__fixtures__/test-project-4-broken/CLAUDE.md b/packages/core/src/__fixtures__/test-project-4-broken/CLAUDE.md new file mode 100644 index 0000000..e69de29 diff --git a/packages/core/src/agents/agents.test.ts b/packages/core/src/agents/agents.test.ts new file mode 100644 index 0000000..9bb7faa --- /dev/null +++ b/packages/core/src/agents/agents.test.ts @@ -0,0 +1,68 @@ +import { describe, it, expect } from "vitest"; +import { agents, getAgent, getAgentIds } from "./index.js"; + +describe("agent registry", () => { + it("exports all 5 agents", () => { + expect(agents).toHaveLength(5); + }); + + it("each agent has required fields", () => { + for (const agent of agents) { + expect(agent.id).toBeTruthy(); + expect(agent.name).toBeTruthy(); + expect(agent.description).toBeTruthy(); + expect(agent.docsUrl).toMatch(/^https?:\/\//); + expect(agent.configs.length).toBeGreaterThan(0); + } + }); + + it("agent IDs are unique", () => { + const ids = agents.map((a) => a.id); + expect(new Set(ids).size).toBe(ids.length); + }); + + it("getAgent returns correct agent by ID", () => { + const claude = getAgent("claude-code"); + expect(claude).toBeDefined(); + expect(claude!.name).toBe("Claude Code"); + }); + + it("getAgent returns undefined for unknown ID", () => { + expect(getAgent("nonexistent")).toBeUndefined(); + }); + + it("getAgentIds returns all IDs", () => { + const ids = getAgentIds(); + expect(ids).toContain("claude-code"); + expect(ids).toContain("cursor"); + expect(ids).toContain("codex"); + expect(ids).toContain("gemini-cli"); + expect(ids).toContain("github-copilot"); + }); + + it("each config location has valid category", () => { + const validCategories = ["instructions", "mcp-servers", "settings", "skills", "rules", "context"]; + for (const agent of agents) { + for (const config of agent.configs) { + expect(validCategories).toContain(config.category); + } + } + }); + + it("each config location has valid format", () => { + const validFormats = ["json", "jsonc", "yaml", "markdown", "toml", "text", "directory"]; + for (const agent of agents) { + for (const config of agent.configs) { + expect(validFormats).toContain(config.format); + } + } + }); + + it("agents with MCP extraction have extractMcpServers function", () => { + const withMcp = ["claude-code", "cursor", "gemini-cli"]; + for (const id of withMcp) { + const agent = getAgent(id); + expect(agent?.extractMcpServers).toBeTypeOf("function"); + } + }); +}); diff --git a/packages/core/src/comparator/comparator.test.ts b/packages/core/src/comparator/comparator.test.ts new file mode 100644 index 0000000..2e54e68 --- /dev/null +++ b/packages/core/src/comparator/comparator.test.ts @@ -0,0 +1,79 @@ +import { describe, it, expect } from "vitest"; +import { compare } from "./comparator.js"; +import type { AgentScanResult } from "../types.js"; +import type { AgentDefinition } from "../agents/types.js"; + +function makeAgent(id: string, name: string): AgentDefinition { + return { id, name, description: "", docsUrl: "https://example.com", configs: [] }; +} + +function makeResult( + agent: AgentDefinition, + opts: { detected?: boolean; hasMcp?: boolean; hasInstructions?: boolean; emptyInstructions?: boolean } = {}, +): AgentScanResult { + const { detected = true, hasMcp = false, hasInstructions = false, emptyInstructions = false } = opts; + return { + agent, + detected, + configs: hasInstructions || emptyInstructions + ? [{ + location: { label: "instructions", category: "instructions", paths: [], multi: false, format: "markdown", description: "" }, + files: [{ + absolutePath: "/test/CLAUDE.md", + relativePath: "./CLAUDE.md", + scope: "project", + size: emptyInstructions ? 0 : 100, + gitignored: false, + status: emptyInstructions ? "empty" : "valid", + }], + }] + : [], + mcpServers: hasMcp + ? [{ name: "test", transport: "stdio", command: "node", source: "/test/.mcp.json" }] + : [], + warnings: [], + }; +} + +describe("compare", () => { + it("returns empty result with fewer than 2 detected agents", () => { + const result = compare([makeResult(makeAgent("a", "A"), { detected: false })]); + expect(result.gaps).toEqual([]); + expect(result.conflicts).toEqual([]); + }); + + it("detects MCP gap when one agent has MCP and another does not", () => { + const a = makeResult(makeAgent("claude-code", "Claude Code"), { hasMcp: true }); + const b = makeResult(makeAgent("cursor", "Cursor"), { hasMcp: false }); + const result = compare([a, b]); + const mcpGap = result.gaps.find((g) => g.category === "mcp-servers"); + expect(mcpGap).toBeDefined(); + expect(mcpGap!.presentIn).toContain("claude-code"); + expect(mcpGap!.missingFrom).toContain("cursor"); + }); + + it("detects instructions gap", () => { + const a = makeResult(makeAgent("claude-code", "Claude Code"), { hasInstructions: true }); + const b = makeResult(makeAgent("cursor", "Cursor"), { hasInstructions: false }); + const result = compare([a, b]); + const instrGap = result.gaps.find((g) => g.category === "instructions" && g.missingFrom.length > 0); + expect(instrGap).toBeDefined(); + expect(instrGap!.presentIn).toContain("claude-code"); + }); + + it("detects empty instruction files", () => { + const a = makeResult(makeAgent("claude-code", "Claude Code"), { emptyInstructions: true }); + const b = makeResult(makeAgent("cursor", "Cursor"), { hasInstructions: true }); + const result = compare([a, b]); + const emptyGap = result.gaps.find((g) => g.description.includes("Empty")); + expect(emptyGap).toBeDefined(); + expect(emptyGap!.presentIn).toContain("claude-code"); + }); + + it("reports no gaps when agents are symmetric", () => { + const a = makeResult(makeAgent("a", "A"), { hasMcp: true, hasInstructions: true }); + const b = makeResult(makeAgent("b", "B"), { hasMcp: true, hasInstructions: true }); + const result = compare([a, b]); + expect(result.gaps).toHaveLength(0); + }); +}); diff --git a/packages/core/src/scanner/scanner.test.ts b/packages/core/src/scanner/scanner.test.ts new file mode 100644 index 0000000..f82d301 --- /dev/null +++ b/packages/core/src/scanner/scanner.test.ts @@ -0,0 +1,89 @@ +import { describe, it, expect } from "vitest"; +import { resolve } from "path"; +import { scan } from "./scanner.js"; + +const fixturesDir = resolve(import.meta.dirname, "../__fixtures__"); + +describe("scan", () => { + it("detects Claude Code config in test-project-1", async () => { + const result = await scan(resolve(fixturesDir, "test-project-1"), { + agents: ["claude-code"], + scope: "project-only", + }); + const claude = result.agents.find((a) => a.agent.id === "claude-code"); + expect(claude).toBeDefined(); + expect(claude!.detected).toBe(true); + }); + + it("extracts MCP servers from test-project-1", async () => { + const result = await scan(resolve(fixturesDir, "test-project-1"), { + agents: ["claude-code"], + scope: "project-only", + }); + const claude = result.agents.find((a) => a.agent.id === "claude-code")!; + expect(claude.mcpServers.length).toBeGreaterThanOrEqual(1); + const fs = claude.mcpServers.find((m) => m.name === "filesystem"); + expect(fs).toBeDefined(); + expect(fs!.transport).toBe("stdio"); + expect(fs!.command).toBe("npx"); + }); + + it("detects Cursor config in test-project-2", async () => { + const result = await scan(resolve(fixturesDir, "test-project-2"), { + agents: ["cursor"], + scope: "project-only", + }); + const cursor = result.agents.find((a) => a.agent.id === "cursor"); + expect(cursor).toBeDefined(); + expect(cursor!.detected).toBe(true); + }); + + it("detects multiple agents in test-project-3-multi", async () => { + const result = await scan(resolve(fixturesDir, "test-project-3-multi"), { + agents: ["claude-code", "cursor"], + scope: "project-only", + }); + const detected = result.agents.filter((a) => a.detected); + expect(detected.length).toBe(2); + }); + + it("handles broken JSON in test-project-4-broken", async () => { + const result = await scan(resolve(fixturesDir, "test-project-4-broken"), { + agents: ["claude-code"], + scope: "project-only", + }); + const claude = result.agents.find((a) => a.agent.id === "claude-code")!; + const mcpConfig = claude.configs.find((c) => c.location.category === "mcp-servers"); + const brokenFile = mcpConfig?.files.find((f) => f.status === "parse-error"); + expect(brokenFile).toBeDefined(); + }); + + it("detects empty files in test-project-4-broken", async () => { + const result = await scan(resolve(fixturesDir, "test-project-4-broken"), { + agents: ["claude-code"], + scope: "project-only", + }); + const claude = result.agents.find((a) => a.agent.id === "claude-code")!; + const instructionsConfig = claude.configs.find((c) => c.location.category === "instructions"); + const emptyFile = instructionsConfig?.files.find((f) => f.status === "empty"); + expect(emptyFile).toBeDefined(); + }); + + it("returns project name and path", async () => { + const projectPath = resolve(fixturesDir, "test-project-1"); + const result = await scan(projectPath, { scope: "project-only" }); + expect(result.projectPath).toBe(projectPath); + expect(result.projectName).toBeTruthy(); + expect(result.scannedAt).toBeTruthy(); + }); + + it("returns no detection for empty project", async () => { + const result = await scan(resolve(fixturesDir, "test-project-1"), { + agents: ["codex"], + scope: "project-only", + }); + const codex = result.agents.find((a) => a.agent.id === "codex"); + expect(codex).toBeDefined(); + expect(codex!.detected).toBe(false); + }); +}); diff --git a/packages/core/src/validator/index.ts b/packages/core/src/validator/index.ts index 5bf2ec2..a5d8f99 100644 --- a/packages/core/src/validator/index.ts +++ b/packages/core/src/validator/index.ts @@ -1 +1,3 @@ export { validate } from "./validator.js"; +export { fileRules, mcpRules } from "./rules.js"; +export type { ValidationRule, McpValidationRule } from "./rules.js"; diff --git a/packages/core/src/validator/rules.ts b/packages/core/src/validator/rules.ts index 1c36040..8f7d6a6 100644 --- a/packages/core/src/validator/rules.ts +++ b/packages/core/src/validator/rules.ts @@ -1,2 +1,216 @@ -// Validation rule definitions — implemented in Phase 4 -export {}; +import type { DiscoveredFile, DoctorCheck } from "../types.js"; +import type { McpServerEntry } from "../agents/types.js"; +import { exec } from "child_process"; +import { promisify } from "util"; + +const execAsync = promisify(exec); + +/** + * A validation rule that inspects a discovered file and returns zero or more checks. + */ +export interface ValidationRule { + /** Unique rule ID (e.g., "EMPTY_FILE") */ + id: string; + + /** What this rule checks */ + description: string; + + /** Category tag for grouping */ + category: string; + + /** Run the check against a single file. Return checks (empty = nothing to report). */ + check: (file: DiscoveredFile, agentName: string) => DoctorCheck[]; +} + +/** + * A validation rule that inspects MCP server entries. + */ +export interface McpValidationRule { + id: string; + description: string; + category: string; + check: (mcp: McpServerEntry, agentName: string) => Promise; +} + +// --- File-level rules --- + +const emptyFile: ValidationRule = { + id: "EMPTY_FILE", + description: "Detects empty config files", + category: "content", + check(file, agentName) { + if (file.status !== "empty") return []; + return [ + { + name: `${agentName}: ${file.relativePath}`, + category: "content", + status: "fail", + message: `File is empty: ${file.relativePath}`, + fix: `Add content to ${file.relativePath} or remove it`, + }, + ]; + }, +}; + +const parseError: ValidationRule = { + id: "PARSE_ERROR", + description: "Detects files that failed to parse", + category: "syntax", + check(file, agentName) { + if (file.status !== "parse-error") return []; + return [ + { + name: `${agentName}: ${file.relativePath}`, + category: "syntax", + status: "fail", + message: `Parse error in ${file.relativePath}: ${file.error ?? "unknown error"}`, + fix: `Fix the syntax error in ${file.relativePath}`, + }, + ]; + }, +}; + +const invalidFile: ValidationRule = { + id: "INVALID", + description: "Detects files with invalid status", + category: "syntax", + check(file, agentName) { + if (file.status !== "invalid") return []; + return [ + { + name: `${agentName}: ${file.relativePath}`, + category: "syntax", + status: "fail", + message: `Invalid file ${file.relativePath}: ${file.error ?? "unknown error"}`, + }, + ]; + }, +}; + +const KNOWN_TYPOS: Record = { + mcpServer: "mcpServers", + mcp_servers: "mcpServers", + rule: "rules", + command: "commands", + instruction: "instructions", + setting: "settings", +}; + +const commonTypo: ValidationRule = { + id: "COMMON_TYPO", + description: "Detects common key typos in JSON config files", + category: "typo", + check(file, agentName) { + if (!file.content || typeof file.content !== "object" || Array.isArray(file.content)) return []; + const obj = file.content as Record; + const checks: DoctorCheck[] = []; + for (const [typo, correct] of Object.entries(KNOWN_TYPOS)) { + if (typo in obj) { + checks.push({ + name: `${agentName}: ${file.relativePath} — typo "${typo}"`, + category: "typo", + status: "fail", + message: `Possible typo in ${file.relativePath}: found key "${typo}", did you mean "${correct}"?`, + fix: `Rename "${typo}" to "${correct}" in ${file.relativePath}`, + }); + } + } + return checks; + }, +}; + +const wrongLocation: ValidationRule = { + id: "WRONG_LOCATION", + description: "Detects config files in incorrect directories", + category: "location", + check(file, agentName) { + if (!file.absolutePath.includes(".cursor/.cursorrules")) return []; + return [ + { + name: `${agentName}: ${file.relativePath} — wrong location`, + category: "location", + status: "fail", + message: `.cursorrules should be in the project root, not inside .cursor/`, + fix: `Move .cursorrules to the project root directory`, + }, + ]; + }, +}; + +const validFile: ValidationRule = { + id: "VALID", + description: "Reports valid files as passing", + category: "syntax", + check(file, agentName) { + if (file.status !== "valid") return []; + return [ + { + name: `${agentName}: ${file.relativePath}`, + category: "syntax", + status: "pass", + message: `${file.relativePath} is valid`, + }, + ]; + }, +}; + +// --- MCP rules --- + +async function commandExists(cmd: string): Promise { + const which = process.platform === "win32" ? "where" : "which"; + try { + await execAsync(`${which} ${cmd}`); + return true; + } catch { + return false; + } +} + +const mcpCommandNotFound: McpValidationRule = { + id: "MCP_COMMAND_NOT_FOUND", + description: "Checks that stdio MCP server commands are available on PATH", + category: "mcp", + async check(mcp, agentName) { + if (mcp.transport !== "stdio" || !mcp.command) return []; + const cmd = mcp.command.split("/").pop() ?? mcp.command; + const exists = await commandExists(cmd); + if (!exists) { + return [ + { + name: `${agentName}: MCP "${mcp.name}" command not found`, + category: "mcp", + status: "fail", + message: `MCP server "${mcp.name}" uses command "${mcp.command}" which was not found on PATH`, + fix: `Install "${mcp.command}" or update the MCP server configuration`, + }, + ]; + } + return [ + { + name: `${agentName}: MCP "${mcp.name}" command found`, + category: "mcp", + status: "pass", + message: `MCP server "${mcp.name}" command "${mcp.command}" is available`, + }, + ]; + }, +}; + +/** + * All file-level validation rules, applied in order. + * Rules that match early statuses (empty, parse-error, invalid) should come first, + * and the validFile rule should come last. + */ +export const fileRules: ValidationRule[] = [ + emptyFile, + parseError, + invalidFile, + commonTypo, + wrongLocation, + validFile, +]; + +/** + * All MCP validation rules. + */ +export const mcpRules: McpValidationRule[] = [mcpCommandNotFound]; diff --git a/packages/core/src/validator/validator.test.ts b/packages/core/src/validator/validator.test.ts new file mode 100644 index 0000000..89da4bb --- /dev/null +++ b/packages/core/src/validator/validator.test.ts @@ -0,0 +1,142 @@ +import { describe, it, expect } from "vitest"; +import { validate } from "./validator.js"; +import { fileRules, mcpRules } from "./rules.js"; +import type { AgentScanResult, DiscoveredFile } from "../types.js"; +import type { AgentDefinition } from "../agents/types.js"; + +const stubAgent: AgentDefinition = { + id: "test-agent", + name: "Test Agent", + description: "A test agent", + docsUrl: "https://example.com", + configs: [], +}; + +function makeFile(overrides: Partial): DiscoveredFile { + return { + absolutePath: "/project/test-file.json", + relativePath: "./test-file.json", + scope: "project", + size: 100, + gitignored: false, + status: "valid", + ...overrides, + }; +} + +function makeAgentResult(files: DiscoveredFile[], mcpServers: AgentScanResult["mcpServers"] = []): AgentScanResult { + return { + agent: stubAgent, + detected: true, + configs: [{ location: { label: "test", category: "settings", paths: [], multi: false, format: "json", description: "test" }, files }], + mcpServers, + warnings: [], + }; +} + +describe("fileRules", () => { + it("exports all expected rules", () => { + const ids = fileRules.map((r) => r.id); + expect(ids).toContain("EMPTY_FILE"); + expect(ids).toContain("PARSE_ERROR"); + expect(ids).toContain("INVALID"); + expect(ids).toContain("COMMON_TYPO"); + expect(ids).toContain("WRONG_LOCATION"); + expect(ids).toContain("VALID"); + }); +}); + +describe("mcpRules", () => { + it("exports MCP_COMMAND_NOT_FOUND rule", () => { + const ids = mcpRules.map((r) => r.id); + expect(ids).toContain("MCP_COMMAND_NOT_FOUND"); + }); +}); + +describe("validate", () => { + it("returns empty result for no agents", async () => { + const result = await validate([]); + expect(result.totalChecks).toBe(0); + expect(result.passed).toBe(0); + expect(result.failed).toBe(0); + expect(result.checks).toEqual([]); + }); + + it("skips undetected agents", async () => { + const result = await validate([{ ...makeAgentResult([]), detected: false }]); + expect(result.totalChecks).toBe(0); + }); + + it("reports empty files", async () => { + const file = makeFile({ status: "empty", size: 0 }); + const result = await validate([makeAgentResult([file])]); + expect(result.failed).toBe(1); + expect(result.checks[0].category).toBe("content"); + expect(result.checks[0].message).toContain("empty"); + }); + + it("reports parse errors", async () => { + const file = makeFile({ status: "parse-error", error: "Unexpected token" }); + const result = await validate([makeAgentResult([file])]); + expect(result.failed).toBe(1); + expect(result.checks[0].category).toBe("syntax"); + expect(result.checks[0].message).toContain("Parse error"); + }); + + it("reports invalid files", async () => { + const file = makeFile({ status: "invalid", error: "Not a regular file" }); + const result = await validate([makeAgentResult([file])]); + expect(result.failed).toBe(1); + expect(result.checks[0].message).toContain("Invalid"); + }); + + it("detects common typos in JSON keys", async () => { + const file = makeFile({ content: { mcpServer: {}, instruction: "test" } }); + const result = await validate([makeAgentResult([file])]); + const typoChecks = result.checks.filter((c) => c.category === "typo"); + expect(typoChecks).toHaveLength(2); + expect(typoChecks[0].message).toContain("mcpServer"); + expect(typoChecks[1].message).toContain("instruction"); + }); + + it("detects wrong location for .cursorrules", async () => { + const file = makeFile({ + absolutePath: "/project/.cursor/.cursorrules", + relativePath: "./.cursor/.cursorrules", + }); + const result = await validate([makeAgentResult([file])]); + const locationChecks = result.checks.filter((c) => c.category === "location"); + expect(locationChecks).toHaveLength(1); + expect(locationChecks[0].message).toContain("project root"); + }); + + it("marks valid files as passing", async () => { + const file = makeFile({ status: "valid" }); + const result = await validate([makeAgentResult([file])]); + expect(result.passed).toBeGreaterThanOrEqual(1); + const passCheck = result.checks.find((c) => c.status === "pass"); + expect(passCheck?.message).toContain("is valid"); + }); + + it("checks MCP stdio commands", async () => { + const mcpServers = [ + { name: "test-mcp", transport: "stdio" as const, command: "node", source: "/project/.mcp.json" }, + ]; + const result = await validate([makeAgentResult([], mcpServers)]); + // node should be on PATH in test environment + const mcpCheck = result.checks.find((c) => c.category === "mcp"); + expect(mcpCheck).toBeDefined(); + expect(mcpCheck!.status).toBe("pass"); + }); + + it("reports missing MCP commands", async () => { + const mcpServers = [ + { name: "missing-mcp", transport: "stdio" as const, command: "nonexistent-command-xyz-123", source: "/project/.mcp.json" }, + ]; + const result = await validate([makeAgentResult([], mcpServers)]); + const mcpCheck = result.checks.find((c) => c.category === "mcp"); + expect(mcpCheck).toBeDefined(); + expect(mcpCheck!.status).toBe("fail"); + expect(mcpCheck!.message).toContain("not found on PATH"); + }); +}); diff --git a/packages/core/src/validator/validator.ts b/packages/core/src/validator/validator.ts index 4bc1b06..791bce6 100644 --- a/packages/core/src/validator/validator.ts +++ b/packages/core/src/validator/validator.ts @@ -1,18 +1,5 @@ -import { exec } from "child_process"; -import { promisify } from "util"; import type { AgentScanResult, DoctorResult, DoctorCheck } from "../types.js"; - -const execAsync = promisify(exec); - -async function commandExists(cmd: string): Promise { - const which = process.platform === "win32" ? "where" : "which"; - try { - await execAsync(`${which} ${cmd}`); - return true; - } catch { - return false; - } -} +import { fileRules, mcpRules } from "./rules.js"; export async function validate(results: AgentScanResult[]): Promise { const checks: DoctorCheck[] = []; @@ -20,110 +7,33 @@ export async function validate(results: AgentScanResult[]): Promise; - const knownTypos: Record = { - mcpServer: "mcpServers", - mcp_servers: "mcpServers", - rule: "rules", - command: "commands", - instruction: "instructions", - setting: "settings", - }; - for (const [typo, correct] of Object.entries(knownTypos)) { - if (typo in obj) { - checks.push({ - name: `${agentName}: ${filePath} — typo "${typo}"`, - category: "typo", - status: "fail", - message: `Possible typo in ${filePath}: found key "${typo}", did you mean "${correct}"?`, - fix: `Rename "${typo}" to "${correct}" in ${filePath}`, - }); + // Run each file rule; stop on the first rule that produces checks + // for terminal statuses (empty, parse-error, invalid) + let handled = false; + for (const rule of fileRules) { + const ruleChecks = rule.check(file, agentName); + if (ruleChecks.length > 0) { + checks.push(...ruleChecks); + // Terminal status rules should skip further checks for this file + if (rule.id === "EMPTY_FILE" || rule.id === "PARSE_ERROR" || rule.id === "INVALID") { + handled = true; + break; } } } - - // WRONG_LOCATION — .cursorrules inside .cursor/ - if (file.absolutePath.includes(".cursor/.cursorrules")) { - checks.push({ - name: `${agentName}: ${filePath} — wrong location`, - category: "location", - status: "fail", - message: `.cursorrules should be in the project root, not inside .cursor/`, - fix: `Move .cursorrules to the project root directory`, - }); - } - - checks.push({ - name: `${agentName}: ${filePath}`, - category: "syntax", - status: "pass", - message: `${filePath} is valid`, - }); + if (handled) continue; } } - // MCP_COMMAND_NOT_FOUND + // MCP rules for (const mcp of agentResult.mcpServers) { - if (mcp.transport === "stdio" && mcp.command) { - const cmd = mcp.command.split("/").pop() ?? mcp.command; - const exists = await commandExists(cmd); - if (!exists) { - checks.push({ - name: `${agentResult.agent.name}: MCP "${mcp.name}" command not found`, - category: "mcp", - status: "fail", - message: `MCP server "${mcp.name}" uses command "${mcp.command}" which was not found on PATH`, - fix: `Install "${mcp.command}" or update the MCP server configuration`, - }); - } else { - checks.push({ - name: `${agentResult.agent.name}: MCP "${mcp.name}" command found`, - category: "mcp", - status: "pass", - message: `MCP server "${mcp.name}" command "${mcp.command}" is available`, - }); - } + for (const rule of mcpRules) { + const ruleChecks = await rule.check(mcp, agentName); + checks.push(...ruleChecks); } } } diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 8f24167..1d92f57 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", - "rootDir": "./src" + "rootDir": "./src", }, "include": ["src/**/*"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dca5e95..57bcf49 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,18 @@ importers: .: devDependencies: + '@changesets/changelog-github': + specifier: ^0.6.0 + version: 0.6.0 + '@changesets/cli': + specifier: ^2.30.0 + version: 2.30.0(@types/node@25.5.0) typescript: specifier: ^5.7.0 version: 5.9.3 + vitest: + specifier: ^4.1.0 + version: 4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(yaml@2.8.2)) packages/cli: dependencies: @@ -26,7 +35,7 @@ importers: version: 25.5.0 tsup: specifier: ^8.4.0 - version: 8.5.1(typescript@5.9.3)(yaml@2.8.2) + version: 8.5.1(postcss@8.5.8)(typescript@5.9.3)(yaml@2.8.2) typescript: specifier: ^5.7.0 version: 5.9.3 @@ -57,6 +66,80 @@ importers: packages: + '@babel/runtime@7.28.6': + resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} + engines: {node: '>=6.9.0'} + + '@changesets/apply-release-plan@7.1.0': + resolution: {integrity: sha512-yq8ML3YS7koKQ/9bk1PqO0HMzApIFNwjlwCnwFEXMzNe8NpzeeYYKCmnhWJGkN8g7E51MnWaSbqRcTcdIxUgnQ==} + + '@changesets/assemble-release-plan@6.0.9': + resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} + + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + + '@changesets/changelog-github@0.6.0': + resolution: {integrity: sha512-wA2/y4hR/A1K411cCT75rz0d46Iezxp1WYRFoFJDIUpkQ6oDBAIUiU7BZkDCmYgz0NBl94X1lgcZO+mHoiHnFg==} + + '@changesets/cli@2.30.0': + resolution: {integrity: sha512-5D3Nk2JPqMI1wK25pEymeWRSlSMdo5QOGlyfrKg0AOufrUcjEE3RQgaCpHoBiM31CSNrtSgdJ0U6zL1rLDDfBA==} + hasBin: true + + '@changesets/config@3.1.3': + resolution: {integrity: sha512-vnXjcey8YgBn2L1OPWd3ORs0bGC4LoYcK/ubpgvzNVr53JXV5GiTVj7fWdMRsoKUH7hhhMAQnsJUqLr21EncNw==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.3': + resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} + + '@changesets/get-github-info@0.8.0': + resolution: {integrity: sha512-cRnC+xdF0JIik7coko3iUP9qbnfi1iJQ3sAa6dE+Tx3+ET8bjFEm63PA4WEohgjYcmsOikPHWzPsMWWiZmntOQ==} + + '@changesets/get-release-plan@4.0.15': + resolution: {integrity: sha512-Q04ZaRPuEVZtA+auOYgFaVQQSA98dXiVe/yFaZfY7hoSmQICHGvP0TF4u3EDNHWmmCS4ekA/XSpKlSM2PyTS2g==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.3': + resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} + + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + + '@changesets/read@0.6.7': + resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} + + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + + '@emnapi/core@1.9.0': + resolution: {integrity: sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==} + + '@emnapi/runtime@1.9.0': + resolution: {integrity: sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==} + + '@emnapi/wasi-threads@1.2.0': + resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} + '@esbuild/aix-ppc64@0.27.4': resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} engines: {node: '>=18'} @@ -213,6 +296,15 @@ packages: cpu: [x64] os: [win32] + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -226,6 +318,15 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -238,6 +339,111 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@oxc-project/runtime@0.115.0': + resolution: {integrity: sha512-Rg8Wlt5dCbXhQnsXPrkOjL1DTSvXLgb2R/KYfnf1/K+R0k6UMLEmbQXPM+kwrWqSmWA2t0B1EtHy2/3zikQpvQ==} + engines: {node: ^20.19.0 || >=22.12.0} + + '@oxc-project/types@0.115.0': + resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==} + + '@rolldown/binding-android-arm64@1.0.0-rc.9': + resolution: {integrity: sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-rc.9': + resolution: {integrity: sha512-J7Zk3kLYFsLtuH6U+F4pS2sYVzac0qkjcO5QxHS7OS7yZu2LRs+IXo+uvJ/mvpyUljDJ3LROZPoQfgBIpCMhdQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-rc.9': + resolution: {integrity: sha512-iwtmmghy8nhfRGeNAIltcNXzD0QMNaaA5U/NyZc1Ia4bxrzFByNMDoppoC+hl7cDiUq5/1CnFthpT9n+UtfFyg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-rc.9': + resolution: {integrity: sha512-DLFYI78SCiZr5VvdEplsVC2Vx53lnA4/Ga5C65iyldMVaErr86aiqCoNBLl92PXPfDtUYjUh+xFFor40ueNs4Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9': + resolution: {integrity: sha512-CsjTmTwd0Hri6iTw/DRMK7kOZ7FwAkrO4h8YWKoX/kcj833e4coqo2wzIFywtch/8Eb5enQ/lwLM7w6JX1W5RQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-2x9O2JbSPxpxMDhP9Z74mahAStibTlrBMW0520+epJH5sac7/LwZW5Bmg/E6CXuEF53JJFW509uP+lSedaUNxg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9': + resolution: {integrity: sha512-JA1QRW31ogheAIRhIg9tjMfsYbglXXYGNPLdPEYrwFxdbkQCAzvpSCSHCDWNl4hTtrol8WeboCSEpjdZK8qrCg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-aOKU9dJheda8Kj8Y3w9gnt9QFOO+qKPAl8SWd7JPHP+Cu0EuDAE5wokQubLzIDQWg2myXq2XhTpOVS07qqvT+w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-OalO94fqj7IWRn3VdXWty75jC5dk4C197AWEuMhIpvVv2lw9fiPhud0+bW2ctCxb3YoBZor71QHbY+9/WToadA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.9': + resolution: {integrity: sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.9': + resolution: {integrity: sha512-+6zoiF+RRyf5cdlFQP7nm58mq7+/2PFaY2DNQeD4B87N36JzfF/l9mdBkkmTvSYcYPE8tMh/o3cRlsx1ldLfog==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.9': + resolution: {integrity: sha512-rgFN6sA/dyebil3YTlL2evvi/M+ivhfnyxec7AccTpRPccno/rPoNlqybEZQBkcbZu8Hy+eqNJCqfBR8P7Pg8g==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9': + resolution: {integrity: sha512-lHVNUG/8nlF1IQk1C0Ci574qKYyty2goMiPlRqkC5R+3LkXDkL5Dhx8ytbxq35m+pkHVIvIxviD+TWLdfeuadA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9': + resolution: {integrity: sha512-G0oA4+w1iY5AGi5HcDTxWsoxF509hrFIPB2rduV5aDqS9FtDg1CAfa7V34qImbjfhIcA8C+RekocJZA96EarwQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-rc.9': + resolution: {integrity: sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==} + '@rollup/rollup-android-arm-eabi@4.59.0': resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} cpu: [arm] @@ -376,20 +582,90 @@ packages: cpu: [x64] os: [win32] + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@25.5.0': resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==} + '@vitest/expect@4.1.0': + resolution: {integrity: sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==} + + '@vitest/mocker@4.1.0': + resolution: {integrity: sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.1.0': + resolution: {integrity: sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==} + + '@vitest/runner@4.1.0': + resolution: {integrity: sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==} + + '@vitest/snapshot@4.1.0': + resolution: {integrity: sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==} + + '@vitest/spy@4.1.0': + resolution: {integrity: sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==} + + '@vitest/utils@4.1.0': + resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==} + acorn@8.16.0: resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} hasBin: true + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -404,6 +680,13 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} @@ -419,6 +702,16 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + dataloader@1.4.0: + resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -428,11 +721,49 @@ packages: supports-color: optional: true + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dotenv@8.6.0: + resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} + engines: {node: '>=10'} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + esbuild@0.27.4: resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} engines: {node: '>=18'} hasBin: true + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -453,9 +784,21 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + fix-dts-default-cjs-exports@1.0.1: resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -465,6 +808,25 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + human-id@4.1.3: + resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} + hasBin: true + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -477,13 +839,109 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -495,6 +953,13 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -509,16 +974,75 @@ packages: mlly@1.8.1: resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==} + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -533,6 +1057,10 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -558,9 +1086,25 @@ packages: yaml: optional: true + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} @@ -573,6 +1117,11 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rolldown@1.0.0-rc.9: + resolution: {integrity: sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup@4.59.0: resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -581,19 +1130,74 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + smol-toml@1.6.0: resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} engines: {node: '>= 18'} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + source-map@0.7.6: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@4.0.0: + resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + sucrase@3.35.1: resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -601,17 +1205,31 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.4: + resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -619,6 +1237,9 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsup@8.5.1: resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} engines: {node: '>=18'} @@ -649,6 +1270,104 @@ packages: undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + vite@8.0.0: + resolution: {integrity: sha512-fPGaRNj9Zytaf8LEiBhY7Z6ijnFKdzU/+mL8EFBaKr7Vw1/FWcTBAMW0wLPJAGMPX38ZPVCVgLceWiEqeoqL2Q==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.0.0-alpha.31 + esbuild: ^0.27.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.1.0: + resolution: {integrity: sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.0 + '@vitest/browser-preview': 4.1.0 + '@vitest/browser-webdriverio': 4.1.0 + '@vitest/ui': 4.1.0 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + yaml@2.8.2: resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} @@ -656,6 +1375,182 @@ packages: snapshots: + '@babel/runtime@7.28.6': {} + + '@changesets/apply-release-plan@7.1.0': + dependencies: + '@changesets/config': 3.1.3 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.4 + + '@changesets/assemble-release-plan@6.0.9': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.4 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/changelog-github@0.6.0': + dependencies: + '@changesets/get-github-info': 0.8.0 + '@changesets/types': 6.1.0 + dotenv: 8.6.0 + transitivePeerDependencies: + - encoding + + '@changesets/cli@2.30.0(@types/node@25.5.0)': + dependencies: + '@changesets/apply-release-plan': 7.1.0 + '@changesets/assemble-release-plan': 6.0.9 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.3 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/get-release-plan': 4.0.15 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3(@types/node@25.5.0) + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.7.4 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' + + '@changesets/config@3.1.3': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.3': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.7.4 + + '@changesets/get-github-info@0.8.0': + dependencies: + dataloader: 1.4.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + '@changesets/get-release-plan@4.0.15': + dependencies: + '@changesets/assemble-release-plan': 6.0.9 + '@changesets/config': 3.1.3 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.3': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 4.1.1 + + '@changesets/pre@2.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.7': + dependencies: + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.3 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.1.0': {} + + '@changesets/write@0.4.0': + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.1.3 + prettier: 2.8.8 + + '@emnapi/core@1.9.0': + dependencies: + '@emnapi/wasi-threads': 1.2.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.0': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.27.4': optional: true @@ -734,6 +1629,13 @@ snapshots: '@esbuild/win32-x64@0.27.4': optional: true + '@inquirer/external-editor@1.0.3(@types/node@25.5.0)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 25.5.0 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -748,6 +1650,29 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.28.6 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.28.6 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@napi-rs/wasm-runtime@1.1.1': + dependencies: + '@emnapi/core': 1.9.0 + '@emnapi/runtime': 1.9.0 + '@tybys/wasm-util': 0.10.1 + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -760,6 +1685,59 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 + '@oxc-project/runtime@0.115.0': {} + + '@oxc-project/types@0.115.0': {} + + '@rolldown/binding-android-arm64@1.0.0-rc.9': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.9': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.9': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.9': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.9': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.9': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.9': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9': + optional: true + + '@rolldown/pluginutils@1.0.0-rc.9': {} + '@rollup/rollup-android-arm-eabi@4.59.0': optional: true @@ -835,16 +1813,91 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true + '@standard-schema/spec@1.1.0': {} + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + '@types/estree@1.0.8': {} + '@types/node@12.20.55': {} + '@types/node@25.5.0': dependencies: undici-types: 7.18.2 + '@vitest/expect@4.1.0': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 + chai: 6.2.2 + tinyrainbow: 3.1.0 + + '@vitest/mocker@4.1.0(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(yaml@2.8.2))': + dependencies: + '@vitest/spy': 4.1.0 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(yaml@2.8.2) + + '@vitest/pretty-format@4.1.0': + dependencies: + tinyrainbow: 3.1.0 + + '@vitest/runner@4.1.0': + dependencies: + '@vitest/utils': 4.1.0 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.0': + dependencies: + '@vitest/pretty-format': 4.1.0 + '@vitest/utils': 4.1.0 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.0': {} + + '@vitest/utils@4.1.0': + dependencies: + '@vitest/pretty-format': 4.1.0 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + acorn@8.16.0: {} + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + any-promise@1.3.0: {} + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-union@2.1.0: {} + + assertion-error@2.0.1: {} + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -856,6 +1909,10 @@ snapshots: cac@6.7.14: {} + chai@6.2.2: {} + + chardet@2.1.1: {} + chokidar@4.0.3: dependencies: readdirp: 4.1.2 @@ -866,10 +1923,37 @@ snapshots: consola@3.4.2: {} + convert-source-map@2.0.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + dataloader@1.4.0: {} + debug@4.4.3: dependencies: ms: 2.1.3 + detect-indent@6.1.0: {} + + detect-libc@2.1.2: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dotenv@8.6.0: {} + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + es-module-lexer@2.0.0: {} + esbuild@0.27.4: optionalDependencies: '@esbuild/aix-ppc64': 0.27.4 @@ -899,6 +1983,16 @@ snapshots: '@esbuild/win32-ia32': 0.27.4 '@esbuild/win32-x64': 0.27.4 + esprima@4.0.1: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + expect-type@1.3.0: {} + + extendable-error@0.1.7: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -919,12 +2013,29 @@ snapshots: dependencies: to-regex-range: 5.0.1 + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + fix-dts-default-cjs-exports@1.0.1: dependencies: magic-string: 0.30.21 mlly: 1.8.1 rollup: 4.59.0 + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + fsevents@2.3.3: optional: true @@ -932,6 +2043,25 @@ snapshots: dependencies: is-glob: 4.0.3 + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + graceful-fs@4.2.11: {} + + human-id@4.1.3: {} + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + is-extglob@2.1.1: {} is-glob@4.0.3: @@ -940,16 +2070,92 @@ snapshots: is-number@7.0.0: {} + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-windows@1.0.2: {} + + isexe@2.0.0: {} + joycon@3.1.1: {} + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + jsonc-parser@3.3.1: {} + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} load-tsconfig@0.2.5: {} + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.startcase@4.4.0: {} + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -968,6 +2174,8 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.3 + mri@1.2.0: {} + ms@2.1.3: {} mz@2.7.0: @@ -976,8 +2184,44 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + nanoid@3.3.11: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + object-assign@4.1.1: {} + obug@2.1.1: {} + + outdent@0.5.0: {} + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-map@2.1.0: {} + + p-try@2.2.0: {} + + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-type@4.0.0: {} + pathe@2.0.3: {} picocolors@1.1.1: {} @@ -986,6 +2230,8 @@ snapshots: picomatch@4.0.3: {} + pify@4.0.1: {} + pirates@4.0.7: {} pkg-types@1.3.1: @@ -994,20 +2240,59 @@ snapshots: mlly: 1.8.1 pathe: 2.0.3 - postcss-load-config@6.0.1(yaml@2.8.2): + postcss-load-config@6.0.1(postcss@8.5.8)(yaml@2.8.2): dependencies: lilconfig: 3.1.3 optionalDependencies: + postcss: 8.5.8 yaml: 2.8.2 + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@2.8.8: {} + + quansync@0.2.11: {} + queue-microtask@1.2.3: {} + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.2 + pify: 4.0.1 + strip-bom: 3.0.0 + readdirp@4.1.2: {} resolve-from@5.0.0: {} reusify@1.1.0: {} + rolldown@1.0.0-rc.9: + dependencies: + '@oxc-project/types': 0.115.0 + '@rolldown/pluginutils': 1.0.0-rc.9 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.9 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.9 + '@rolldown/binding-darwin-x64': 1.0.0-rc.9 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.9 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.9 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.9 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.9 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.9 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.9 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.9 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.9 + rollup@4.59.0: dependencies: '@types/estree': 1.0.8 @@ -1043,10 +2328,45 @@ snapshots: dependencies: queue-microtask: 1.2.3 + safer-buffer@2.1.2: {} + + semver@7.7.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + slash@3.0.0: {} + smol-toml@1.6.0: {} + source-map-js@1.2.1: {} + source-map@0.7.6: {} + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + sprintf-js@1.0.3: {} + + stackback@0.0.2: {} + + std-env@4.0.0: {} + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -1057,6 +2377,8 @@ snapshots: tinyglobby: 0.2.15 ts-interface-checker: 0.1.13 + term-size@2.2.1: {} + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -1065,22 +2387,33 @@ snapshots: dependencies: any-promise: 1.3.0 + tinybench@2.9.0: {} + tinyexec@0.3.2: {} + tinyexec@1.0.4: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyrainbow@3.1.0: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + tr46@0.0.3: {} + tree-kill@1.2.2: {} ts-interface-checker@0.1.13: {} - tsup@8.5.1(typescript@5.9.3)(yaml@2.8.2): + tslib@2.8.1: + optional: true + + tsup@8.5.1(postcss@8.5.8)(typescript@5.9.3)(yaml@2.8.2): dependencies: bundle-require: 5.1.0(esbuild@0.27.4) cac: 6.7.14 @@ -1091,7 +2424,7 @@ snapshots: fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(yaml@2.8.2) + postcss-load-config: 6.0.1(postcss@8.5.8)(yaml@2.8.2) resolve-from: 5.0.0 rollup: 4.59.0 source-map: 0.7.6 @@ -1100,6 +2433,7 @@ snapshots: tinyglobby: 0.2.15 tree-kill: 1.2.2 optionalDependencies: + postcss: 8.5.8 typescript: 5.9.3 transitivePeerDependencies: - jiti @@ -1113,4 +2447,63 @@ snapshots: undici-types@7.18.2: {} + universalify@0.1.2: {} + + vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(yaml@2.8.2): + dependencies: + '@oxc-project/runtime': 0.115.0 + lightningcss: 1.32.0 + picomatch: 4.0.3 + postcss: 8.5.8 + rolldown: 1.0.0-rc.9 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 25.5.0 + esbuild: 0.27.4 + fsevents: 2.3.3 + yaml: 2.8.2 + + vitest@4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(yaml@2.8.2)): + dependencies: + '@vitest/expect': 4.1.0 + '@vitest/mocker': 4.1.0(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(yaml@2.8.2)) + '@vitest/pretty-format': 4.1.0 + '@vitest/runner': 4.1.0 + '@vitest/snapshot': 4.1.0 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 + es-module-lexer: 2.0.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 4.0.0 + tinybench: 2.9.0 + tinyexec: 1.0.4 + tinyglobby: 0.2.15 + tinyrainbow: 3.1.0 + vite: 8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(yaml@2.8.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.5.0 + transitivePeerDependencies: + - msw + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + yaml@2.8.2: {} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..ea8701c --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + root: ".", + include: ["packages/*/src/**/*.test.ts"], + }, +});