@vexyo/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +11 -0
- package/dist/index.d.ts +400 -0
- package/dist/index.js +1406 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/rule.ts","../src/rules/2025-11-25/init/server-info-name.ts","../src/rules/2025-11-25/init/server-info-version.ts","../src/rules/2025-11-25/support.ts","../src/mcp/errors.ts","../src/mcp/schemas.ts","../src/rules/2025-11-25/discovery/tools-list.ts","../src/rules/2025-11-25/discovery/tools-have-names.ts","../src/rules/2025-11-25/discovery/tools-have-input-schema.ts","../src/rules/2025-11-25/discovery/tool-names-unique.ts","../src/rules/2025-11-25/discovery/resources-list.ts","../src/rules/2025-11-25/discovery/resources-have-uri.ts","../src/rules/2025-11-25/discovery/prompts-list.ts","../src/rules/2025-11-25/discovery/prompts-have-names.ts","../src/rules/2025-11-25/errors/unknown-method.ts","../src/rules/2025-11-25/errors/unknown-tool.ts","../src/rules/2025-11-25/errors/tool-invalid-params.ts","../src/rules/2025-11-25/errors/unknown-resource.ts","../src/rules/2025-11-25/errors/error-object-shape.ts","../src/rules/2025-11-25/transport/http-session-id-valid.ts","../src/rules/2025-11-25/index.ts","../src/registry.ts","../src/transports/http.ts","../src/brand.ts","../src/transports/stdio.ts","../src/transports/index.ts","../src/runner.ts","../src/golden/format.ts","../src/golden/normalize.ts","../src/golden/record.ts","../src/golden/serialize.ts","../src/golden/diff.ts","../src/golden/regress.ts","../src/golden/io.ts"],"sourcesContent":["/**\n * The public result contract consumed by every reporter.\n *\n * CLAUDE.md hard rule #7: reporters consume `RunResult` only; breaking this\n * shape is a semver-major event. Keep it stable and additive.\n */\n\n/**\n * MCP spec versions this harness knows about. A run targets exactly one\n * (CLAUDE.md hard rule #2 — spec versions never mix). Only the stable version\n * is wired up today; `2026-07-28` is a scaffolding slot for the RC.\n */\nexport type SpecVersion = '2025-11-25' | '2026-07-28';\n\n/** The stable spec version this build fully supports. */\nexport const STABLE_SPEC_VERSION: SpecVersion = '2025-11-25';\n\nexport type Severity = 'error' | 'warning' | 'info';\n\nexport type Category =\n 'initialization' | 'discovery' | 'error-semantics' | 'transport' | 'security' | 'regression';\n\n/**\n * Outcome of running one rule:\n * - `pass` — rule ran and produced no findings.\n * - `fail` — rule produced at least one `error`-severity finding.\n * - `warn` — rule produced findings, but none above `warning`/`info` severity.\n * - `skip` — rule was not applicable (e.g. capability not advertised).\n * - `error` — rule threw unexpectedly (server crash or harness bug).\n */\nexport type RuleStatus = 'pass' | 'fail' | 'warn' | 'skip' | 'error';\n\n/** A single problem detected by a rule. A rule with zero findings passed. */\nexport interface Finding {\n ruleId: string;\n severity: Severity;\n /** What is wrong. */\n message: string;\n /** What to do next (CLAUDE.md: every user-facing failure states the fix). */\n remediation: string;\n /** Spec section citation, e.g. \"Base Protocol §Lifecycle\". */\n specRef: string;\n /** Optional machine-readable context (offending payload, error, etc.). */\n detail?: unknown;\n}\n\nexport interface RuleResult {\n ruleId: string;\n title: string;\n category: Category;\n severity: Severity;\n specVersion: SpecVersion;\n /** Spec section citation for this rule, surfaced by reporters. */\n specRef: string;\n status: RuleStatus;\n /**\n * Why the rule was skipped. A skip means either \"not applicable\" (capability\n * absent) or \"a prerequisite is unavailable\" (e.g. `tools/list` failed, so\n * rules that consume it skip rather than cascade errors).\n */\n skipReason?: string;\n findings: Finding[];\n durationMs: number;\n}\n\nexport interface RunTarget {\n transport: 'stdio' | 'http';\n /** Human-readable description of what we connected to. */\n description: string;\n}\n\nexport interface RunSummary {\n pass: number;\n fail: number;\n warn: number;\n skip: number;\n error: number;\n total: number;\n}\n\nexport interface RunResult {\n specVersion: SpecVersion;\n target: RunTarget;\n /** ISO-8601 timestamps. */\n startedAt: string;\n finishedAt: string;\n results: RuleResult[];\n summary: RunSummary;\n /** 0 = pass, 1 = findings at/above threshold, 2 = harness/config error. */\n exitCode: 0 | 1 | 2;\n}\n","import type { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport type { Implementation, ServerCapabilities } from '@modelcontextprotocol/sdk/types.js';\nimport type { TransportInfo } from './transports/types';\nimport type { Category, Finding, Severity, SpecVersion } from './types';\n\n/**\n * Everything a rule needs to make its assessment. The runner owns the\n * connection lifecycle; a rule never spawns processes or manages sockets\n * (CLAUDE.md hard rule #1 + architecture note).\n */\nexport interface RuleContext {\n /** Connected MCP client (handshake already completed). */\n readonly client: Client;\n /** Server identity captured during initialization. */\n readonly serverInfo: Implementation | undefined;\n /** Capabilities the server advertised during negotiation. */\n readonly capabilities: ServerCapabilities | undefined;\n /** The transport in use, plus transport-specific facts (e.g. HTTP session id). */\n readonly transport: TransportInfo;\n readonly specVersion: SpecVersion;\n}\n\n/**\n * A rule is a pure, declarative conformance check. It returns the findings it\n * detected; an empty array means the server passed. Applicability is signalled\n * by throwing {@link SkipRule}.\n */\nexport interface Rule {\n readonly id: string;\n /** Exactly one spec version (CLAUDE.md hard rule #2). */\n readonly specVersion: SpecVersion;\n readonly category: Category;\n readonly severity: Severity;\n readonly title: string;\n /** Spec section citation surfaced to users, e.g. \"Base Protocol §Lifecycle\". */\n readonly specRef: string;\n run(ctx: RuleContext): Promise<Finding[]>;\n}\n\n/**\n * Thrown by a rule to declare itself not applicable to this server (e.g. the\n * relevant capability was never advertised). The runner records a `skip`\n * rather than a pass or fail.\n */\nexport class SkipRule extends Error {\n constructor(public readonly reason: string) {\n super(reason);\n this.name = 'SkipRule';\n }\n}\n\n/** Build a {@link Finding}, prefilling identity fields from the rule. */\nexport function finding(\n rule: Pick<Rule, 'id' | 'severity' | 'specRef'>,\n message: string,\n remediation: string,\n detail?: unknown,\n): Finding {\n return {\n ruleId: rule.id,\n severity: rule.severity,\n message,\n remediation,\n specRef: rule.specRef,\n detail,\n };\n}\n","import { finding, type Rule } from '../../../rule';\n\n/**\n * Initialization must identify the server with a non-empty name. The SDK\n * completes the handshake before rules run, so `serverInfo` is available; a\n * missing or empty name is a conformance defect the SDK tolerates but the spec\n * forbids.\n */\nexport const serverInfoName: Rule = {\n id: 'init/server-info-name',\n specVersion: '2025-11-25',\n category: 'initialization',\n severity: 'error',\n title: 'Server advertises a non-empty serverInfo.name',\n specRef: 'Base Protocol §Lifecycle / Initialization (serverInfo)',\n async run(ctx) {\n const name = ctx.serverInfo?.name;\n if (typeof name !== 'string' || name.length === 0) {\n return [\n finding(\n this,\n 'Server did not return a non-empty `serverInfo.name` during initialization.',\n 'Return a non-empty `serverInfo.name` in the initialize response.',\n { serverInfo: ctx.serverInfo },\n ),\n ];\n }\n return [];\n },\n};\n","import { finding, type Rule } from '../../../rule';\n\n/**\n * The spec requires `serverInfo.version` alongside the name. The SDK schema\n * allows an empty string; the spec expects a meaningful version identifier.\n */\nexport const serverInfoVersion: Rule = {\n id: 'init/server-info-version',\n specVersion: '2025-11-25',\n category: 'initialization',\n severity: 'error',\n title: 'Server advertises a non-empty serverInfo.version',\n specRef: 'Base Protocol §Lifecycle / Initialization (serverInfo)',\n async run(ctx) {\n const version = ctx.serverInfo?.version;\n if (typeof version !== 'string' || version.length === 0) {\n return [\n finding(\n this,\n 'Server did not return a non-empty `serverInfo.version` during initialization.',\n 'Return a non-empty `serverInfo.version` in the initialize response.',\n { serverInfo: ctx.serverInfo },\n ),\n ];\n }\n return [];\n },\n};\n","import { z } from 'zod';\nimport { cleanErrorMessage, errorCode } from '../../mcp/errors';\nimport {\n isRecord,\n promptsListResult,\n resourcesListResult,\n stringField,\n toolsListResult,\n} from '../../mcp/schemas';\nimport { SkipRule, type RuleContext } from '../../rule';\n\n// Re-export the shared MCP schemas/helpers so rule files keep a single import.\nexport {\n anyResult,\n isRecord,\n promptsListResult,\n resourcesListResult,\n stringField,\n toolsListResult,\n} from '../../mcp/schemas';\nexport { cleanErrorMessage } from '../../mcp/errors';\n\n/** Just enough of a CallToolResult to read the `isError` signal. */\nexport const callToolResult = z.object({ isError: z.boolean().optional() });\n\nexport interface ErrorInfo {\n threw: boolean;\n code?: number;\n message?: string;\n}\n\n/**\n * Normalize a thrown value into `{ code, message }`, unwrapping every\n * `MCP error <code>: ` prefix so the server's original message (which may be\n * empty) is recoverable — required to detect malformed, empty-message error\n * objects and to keep findings free of doubled prefixes.\n */\nexport function classifyError(err: unknown): ErrorInfo {\n return { threw: true, code: errorCode(err), message: cleanErrorMessage(err) };\n}\n\n/**\n * Dependency accessors: a rule that consumes a list operation depends on it. If\n * the operation fails, the dependent rule skips with a reason instead of\n * cascading an error — so one broken `tools/list` reads as one failure (from\n * the rule that directly tests it) plus N skips, not N errors.\n */\nexport async function requireToolList(ctx: RuleContext): Promise<Record<string, unknown>[]> {\n try {\n return (await ctx.client.request({ method: 'tools/list', params: {} }, toolsListResult)).tools;\n } catch {\n throw new SkipRule('tools/list unavailable');\n }\n}\n\nexport async function requireResourceList(ctx: RuleContext): Promise<Record<string, unknown>[]> {\n try {\n return (await ctx.client.request({ method: 'resources/list', params: {} }, resourcesListResult))\n .resources;\n } catch {\n throw new SkipRule('resources/list unavailable');\n }\n}\n\nexport async function requirePromptList(ctx: RuleContext): Promise<Record<string, unknown>[]> {\n try {\n return (await ctx.client.request({ method: 'prompts/list', params: {} }, promptsListResult))\n .prompts;\n } catch {\n throw new SkipRule('prompts/list unavailable');\n }\n}\n\n/**\n * Find the first tool whose `inputSchema` declares required parameters, so an\n * argument-validation rule can call it with empty arguments and expect an\n * error. Returns the tool name, or `undefined` if none qualifies.\n */\nexport function toolWithRequiredParams(\n tools: ReadonlyArray<Record<string, unknown>>,\n): string | undefined {\n for (const tool of tools) {\n const name = stringField(tool, 'name');\n const schema = tool['inputSchema'];\n if (\n name &&\n isRecord(schema) &&\n Array.isArray(schema['required']) &&\n schema['required'].length > 0\n ) {\n return name;\n }\n }\n return undefined;\n}\n","import { McpError } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * McpError formats its message as `MCP error <code>: <message>`. When such an\n * error round-trips over the wire (server formats it, the client re-wraps the\n * already-formatted string) the prefix doubles up:\n * `MCP error -32603: MCP error -32603: tools/list is broken`. Strip every\n * leading prefix so a finding carries one clean message.\n */\nexport function cleanErrorMessage(err: unknown): string {\n let message = err instanceof Error ? err.message : String(err);\n const prefix = /^MCP error -?\\d+: /;\n while (prefix.test(message)) {\n message = message.replace(prefix, '');\n }\n return message;\n}\n\n/** The JSON-RPC error code, if the thrown value was an McpError. */\nexport function errorCode(err: unknown): number | undefined {\n return err instanceof McpError ? err.code : undefined;\n}\n","import { z } from 'zod';\n\n/**\n * Lax MCP result schemas and small helpers shared by the conformance rules and\n * the regression/golden engine. Both fetch raw responses via\n * `client.request(req, schema)` and validate fields themselves rather than\n * letting the SDK's strict parsing define conformance — so each list entry is\n * an opaque record the caller inspects directly.\n */\nexport const toolsListResult = z.object({ tools: z.array(z.record(z.string(), z.unknown())) });\nexport const resourcesListResult = z.object({\n resources: z.array(z.record(z.string(), z.unknown())),\n});\nexport const promptsListResult = z.object({ prompts: z.array(z.record(z.string(), z.unknown())) });\n\n/** Accept any successful result (used when a caller only cares whether it threw). */\nexport const anyResult = z.unknown();\n\n/** Type guard for a plain object (JSON-RPC result entries). */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Read a string field from an opaque record, or `undefined` if not a string. */\nexport function stringField(record: Record<string, unknown>, key: string): string | undefined {\n const value = record[key];\n return typeof value === 'string' ? value : undefined;\n}\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { cleanErrorMessage, toolsListResult } from '../support';\n\n/**\n * A server that advertises the `tools` capability must answer `tools/list` with\n * a well-formed `{ tools: [...] }` result. If the capability was never\n * advertised the check is not applicable and is skipped.\n */\nexport const toolsListAvailable: Rule = {\n id: 'discovery/tools-list-available',\n specVersion: '2025-11-25',\n category: 'discovery',\n severity: 'error',\n title: 'tools/list responds with a tool array',\n specRef: 'Server Features §Tools / Listing Tools',\n async run(ctx) {\n if (!ctx.capabilities?.tools) {\n throw new SkipRule('Server does not advertise the `tools` capability.');\n }\n try {\n await ctx.client.request({ method: 'tools/list', params: {} }, toolsListResult);\n return [];\n } catch (err) {\n return [\n finding(\n this,\n '`tools/list` failed despite the `tools` capability being advertised.',\n 'Implement `tools/list` to return `{ tools: Tool[] }`, or stop advertising the `tools` capability.',\n { error: cleanErrorMessage(err) },\n ),\n ];\n }\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { requireToolList, stringField } from '../support';\n\n/** Every tool in `tools/list` must carry a non-empty `name` (its call handle). */\nexport const toolsHaveNames: Rule = {\n id: 'discovery/tools-have-names',\n specVersion: '2025-11-25',\n category: 'discovery',\n severity: 'error',\n title: 'Every tool has a non-empty name',\n specRef: 'Server Features §Tools / Tool.name',\n async run(ctx) {\n if (!ctx.capabilities?.tools) {\n throw new SkipRule('Server does not advertise the `tools` capability.');\n }\n const tools = await requireToolList(ctx);\n const invalid = tools.filter((tool) => {\n const name = stringField(tool, 'name');\n return name === undefined || name.length === 0;\n });\n if (invalid.length > 0) {\n return [\n finding(\n this,\n `${invalid.length} tool(s) have a missing or empty name.`,\n 'Give every tool a non-empty string `name`.',\n { tools },\n ),\n ];\n }\n return [];\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { isRecord, requireToolList } from '../support';\n\n/**\n * Each tool must declare an `inputSchema` that is a JSON Schema object\n * (`type: \"object\"`). Clients rely on this to build valid tool calls; a missing\n * or non-object schema is a frequent cause of malformed calls in production.\n */\nexport const toolsHaveInputSchema: Rule = {\n id: 'discovery/tools-have-input-schema',\n specVersion: '2025-11-25',\n category: 'discovery',\n severity: 'error',\n title: 'Every tool declares an object inputSchema',\n specRef: 'Server Features §Tools / Tool.inputSchema',\n async run(ctx) {\n if (!ctx.capabilities?.tools) {\n throw new SkipRule('Server does not advertise the `tools` capability.');\n }\n const tools = await requireToolList(ctx);\n const invalid = tools.filter((tool) => {\n const schema = tool['inputSchema'];\n return !isRecord(schema) || schema['type'] !== 'object';\n });\n if (invalid.length > 0) {\n return [\n finding(\n this,\n `${invalid.length} tool(s) are missing an object inputSchema (type: \"object\").`,\n 'Declare an `inputSchema` of `{ \"type\": \"object\", ... }` for every tool.',\n { tools },\n ),\n ];\n }\n return [];\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { requireToolList, stringField } from '../support';\n\n/**\n * Tool names are the call handle and must be unique. Duplicates make tool\n * dispatch ambiguous — the client cannot know which definition a call targets.\n */\nexport const toolNamesUnique: Rule = {\n id: 'discovery/tool-names-unique',\n specVersion: '2025-11-25',\n category: 'discovery',\n severity: 'error',\n title: 'Tool names are unique',\n specRef: 'Server Features §Tools / Tool.name',\n async run(ctx) {\n if (!ctx.capabilities?.tools) {\n throw new SkipRule('Server does not advertise the `tools` capability.');\n }\n const tools = await requireToolList(ctx);\n const names = tools.map((tool) => stringField(tool, 'name')).filter((n): n is string => !!n);\n const duplicates = [...new Set(names.filter((name, i) => names.indexOf(name) !== i))];\n if (duplicates.length > 0) {\n return [\n finding(\n this,\n `Duplicate tool name(s): ${duplicates.join(', ')}.`,\n 'Ensure every tool has a distinct `name`.',\n { duplicates },\n ),\n ];\n }\n return [];\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { cleanErrorMessage, resourcesListResult } from '../support';\n\n/**\n * A server advertising the `resources` capability must answer `resources/list`\n * with a `{ resources: [...] }` result. Skipped when the capability is absent.\n */\nexport const resourcesListAvailable: Rule = {\n id: 'discovery/resources-list-available',\n specVersion: '2025-11-25',\n category: 'discovery',\n severity: 'error',\n title: 'resources/list responds with a resource array',\n specRef: 'Server Features §Resources / Listing Resources',\n async run(ctx) {\n if (!ctx.capabilities?.resources) {\n throw new SkipRule('Server does not advertise the `resources` capability.');\n }\n try {\n await ctx.client.request({ method: 'resources/list', params: {} }, resourcesListResult);\n return [];\n } catch (err) {\n return [\n finding(\n this,\n '`resources/list` failed despite the `resources` capability being advertised.',\n 'Implement `resources/list`, or stop advertising the `resources` capability.',\n { error: cleanErrorMessage(err) },\n ),\n ];\n }\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { requireResourceList, stringField } from '../support';\n\n/**\n * Every resource in `resources/list` must carry a non-empty `uri` — the handle\n * a client uses to read it. A missing or empty uri makes the resource\n * unreadable.\n */\nexport const resourcesHaveUri: Rule = {\n id: 'discovery/resources-have-uri',\n specVersion: '2025-11-25',\n category: 'discovery',\n severity: 'error',\n title: 'Every resource has a non-empty uri',\n specRef: 'Server Features §Resources / Resource.uri',\n async run(ctx) {\n if (!ctx.capabilities?.resources) {\n throw new SkipRule('Server does not advertise the `resources` capability.');\n }\n const resources = await requireResourceList(ctx);\n const invalid = resources.filter((resource) => {\n const uri = stringField(resource, 'uri');\n return uri === undefined || uri.length === 0;\n });\n if (invalid.length > 0) {\n return [\n finding(\n this,\n `${invalid.length} resource(s) have a missing or empty uri.`,\n 'Give every resource a non-empty `uri`.',\n { resources },\n ),\n ];\n }\n return [];\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { cleanErrorMessage, promptsListResult } from '../support';\n\n/**\n * A server advertising the `prompts` capability must answer `prompts/list` with\n * a `{ prompts: [...] }` result. Skipped when the capability is absent.\n */\nexport const promptsListAvailable: Rule = {\n id: 'discovery/prompts-list-available',\n specVersion: '2025-11-25',\n category: 'discovery',\n severity: 'error',\n title: 'prompts/list responds with a prompt array',\n specRef: 'Server Features §Prompts / Listing Prompts',\n async run(ctx) {\n if (!ctx.capabilities?.prompts) {\n throw new SkipRule('Server does not advertise the `prompts` capability.');\n }\n try {\n await ctx.client.request({ method: 'prompts/list', params: {} }, promptsListResult);\n return [];\n } catch (err) {\n return [\n finding(\n this,\n '`prompts/list` failed despite the `prompts` capability being advertised.',\n 'Implement `prompts/list`, or stop advertising the `prompts` capability.',\n { error: cleanErrorMessage(err) },\n ),\n ];\n }\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { requirePromptList, stringField } from '../support';\n\n/** Every prompt in `prompts/list` must carry a non-empty `name`. */\nexport const promptsHaveNames: Rule = {\n id: 'discovery/prompts-have-names',\n specVersion: '2025-11-25',\n category: 'discovery',\n severity: 'error',\n title: 'Every prompt has a non-empty name',\n specRef: 'Server Features §Prompts / Prompt.name',\n async run(ctx) {\n if (!ctx.capabilities?.prompts) {\n throw new SkipRule('Server does not advertise the `prompts` capability.');\n }\n const prompts = await requirePromptList(ctx);\n const invalid = prompts.filter((prompt) => {\n const name = stringField(prompt, 'name');\n return name === undefined || name.length === 0;\n });\n if (invalid.length > 0) {\n return [\n finding(\n this,\n `${invalid.length} prompt(s) have a missing or empty name.`,\n 'Give every prompt a non-empty string `name`.',\n { prompts },\n ),\n ];\n }\n return [];\n },\n};\n","import { ErrorCode, type ClientRequest } from '@modelcontextprotocol/sdk/types.js';\nimport { finding, type Rule } from '../../../rule';\nimport { anyResult, classifyError } from '../support';\n\n/**\n * A request for a method the server does not implement must be answered with a\n * JSON-RPC `-32601` (Method not found), not a bogus success. We probe a\n * deliberately unknown method — a conformance probe, which CLAUDE.md hard rule\n * #1 permits inside a rule. The request is cast because an unknown method is,\n * by definition, not part of the typed `ClientRequest` union.\n */\nconst PROBE_UNSUPPORTED_METHOD = 'vexyo/probe-unsupported-method';\n\nexport const unknownMethod: Rule = {\n id: 'errors/unknown-method',\n specVersion: '2025-11-25',\n category: 'error-semantics',\n severity: 'error',\n title: 'Unknown methods return -32601 (Method not found)',\n specRef: 'Base Protocol §JSON-RPC / Error codes',\n async run(ctx) {\n const probe = { method: PROBE_UNSUPPORTED_METHOD, params: {} } as unknown as ClientRequest;\n try {\n await ctx.client.request(probe, anyResult);\n return [\n finding(\n this,\n 'An unknown method returned a result instead of an error.',\n 'Return JSON-RPC error -32601 (Method not found) for methods the server does not implement.',\n ),\n ];\n } catch (err) {\n const info = classifyError(err);\n if (info.code === ErrorCode.MethodNotFound) {\n return [];\n }\n return [\n finding(\n this,\n `Unknown method returned error code ${info.code ?? '(none)'}, expected -32601 (Method not found).`,\n 'Return JSON-RPC error -32601 for methods the server does not implement.',\n info,\n ),\n ];\n }\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { callToolResult } from '../support';\n\nconst NONEXISTENT_TOOL = '__vexyo_nonexistent_tool__';\n\n/**\n * Calling a tool that does not exist must be signalled as an error — either a\n * JSON-RPC error or a result with `isError: true`. Both are spec-legitimate, so\n * we accept either (see docs/spec-ambiguities.md). A plain success result is the\n * defect: the model would treat a no-op as if the tool ran.\n */\nexport const unknownTool: Rule = {\n id: 'errors/unknown-tool',\n specVersion: '2025-11-25',\n category: 'error-semantics',\n severity: 'error',\n title: 'Calling an unknown tool is signalled as an error',\n specRef: 'Server Features §Tools / Calling Tools (error handling)',\n async run(ctx) {\n if (!ctx.capabilities?.tools) {\n throw new SkipRule('Server does not advertise the `tools` capability.');\n }\n try {\n const result = await ctx.client.request(\n { method: 'tools/call', params: { name: NONEXISTENT_TOOL, arguments: {} } },\n callToolResult,\n );\n if (result.isError === true) {\n return [];\n }\n return [\n finding(\n this,\n 'Calling a nonexistent tool returned a successful result instead of an error.',\n 'Return a JSON-RPC error or a result with `isError: true` for unknown tool names.',\n result,\n ),\n ];\n } catch {\n // JSON-RPC error response — the acceptable alternative.\n return [];\n }\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { callToolResult, requireToolList, toolWithRequiredParams } from '../support';\n\n/**\n * Calling a tool with missing required arguments must be rejected — via a\n * JSON-RPC error (`-32602`) or an `isError: true` result — never silently\n * accepted. We pick the first tool that declares required parameters and call\n * it with empty arguments. Skipped if no tool declares required parameters.\n */\nexport const toolInvalidParams: Rule = {\n id: 'errors/tool-invalid-params',\n specVersion: '2025-11-25',\n category: 'error-semantics',\n severity: 'error',\n title: 'Invalid tool arguments are rejected',\n specRef: 'Server Features §Tools / Calling Tools (input validation)',\n async run(ctx) {\n if (!ctx.capabilities?.tools) {\n throw new SkipRule('Server does not advertise the `tools` capability.');\n }\n const tools = await requireToolList(ctx);\n const target = toolWithRequiredParams(tools);\n if (target === undefined) {\n throw new SkipRule('No tool declares required parameters to probe.');\n }\n try {\n const result = await ctx.client.request(\n { method: 'tools/call', params: { name: target, arguments: {} } },\n callToolResult,\n );\n if (result.isError === true) {\n return [];\n }\n return [\n finding(\n this,\n `Tool \"${target}\" accepted a call with missing required arguments and returned success.`,\n 'Validate tool arguments and return an error (-32602 or `isError: true`) on invalid input.',\n result,\n ),\n ];\n } catch {\n // JSON-RPC error response — arguments were validated. Acceptable.\n return [];\n }\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { anyResult } from '../support';\n\nconst NONEXISTENT_URI = 'vexyo://__vexyo_nonexistent_resource__';\n\n/**\n * Reading a resource URI the server does not serve must be an error, not an\n * empty success. A silent empty read looks to the model like the resource\n * exists but is blank.\n */\nexport const unknownResource: Rule = {\n id: 'errors/unknown-resource',\n specVersion: '2025-11-25',\n category: 'error-semantics',\n severity: 'error',\n title: 'Reading an unknown resource returns an error',\n specRef: 'Server Features §Resources / Reading Resources (error handling)',\n async run(ctx) {\n if (!ctx.capabilities?.resources) {\n throw new SkipRule('Server does not advertise the `resources` capability.');\n }\n try {\n await ctx.client.request(\n { method: 'resources/read', params: { uri: NONEXISTENT_URI } },\n anyResult,\n );\n return [\n finding(\n this,\n 'Reading a nonexistent resource URI returned a successful result instead of an error.',\n 'Return a JSON-RPC error for resource URIs the server does not serve.',\n ),\n ];\n } catch {\n return [];\n }\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\nimport { anyResult, classifyError } from '../support';\n\nconst NONEXISTENT_URI = 'vexyo://__vexyo_error_shape_probe__';\n\n/**\n * When a server returns a JSON-RPC error, the error object must be well-formed:\n * a numeric `code` and a non-empty `message`. We trigger a reliable JSON-RPC\n * error — reading a resource the server does not serve — and inspect the\n * resulting error object. (Tool argument errors are excluded here because a\n * compliant server may legitimately signal them via an `isError` result rather\n * than a JSON-RPC error, which leaves no error object to assess.)\n */\nexport const errorObjectShape: Rule = {\n id: 'errors/error-object-shape',\n specVersion: '2025-11-25',\n category: 'error-semantics',\n severity: 'error',\n title: 'JSON-RPC error objects carry a numeric code and non-empty message',\n specRef: 'Base Protocol §JSON-RPC / Error object',\n async run(ctx) {\n if (!ctx.capabilities?.resources) {\n throw new SkipRule('Server does not advertise the `resources` capability.');\n }\n try {\n await ctx.client.request(\n { method: 'resources/read', params: { uri: NONEXISTENT_URI } },\n anyResult,\n );\n // A compliant server errors on an unknown resource; if it succeeds there\n // is no error object to assess (that gap is covered by errors/unknown-resource).\n throw new SkipRule('Server did not raise a JSON-RPC error for an unknown resource.');\n } catch (err) {\n if (err instanceof SkipRule) {\n throw err;\n }\n const info = classifyError(err);\n const problems: string[] = [];\n if (typeof info.code !== 'number') {\n problems.push('missing numeric `code`');\n }\n if (info.message === undefined || info.message.length === 0) {\n problems.push('missing or empty `message`');\n }\n if (problems.length > 0) {\n return [\n finding(\n this,\n `JSON-RPC error object is malformed: ${problems.join(', ')}.`,\n 'Every JSON-RPC error must include a numeric `code` and a non-empty `message`.',\n info,\n ),\n ];\n }\n return [];\n }\n },\n};\n","import { finding, SkipRule, type Rule } from '../../../rule';\n\n// Streamable HTTP session ids must contain only visible ASCII (0x21–0x7E).\nconst VISIBLE_ASCII = /^[\\x21-\\x7e]+$/;\n\n/**\n * When connected over Streamable HTTP and the server operates statefully (it\n * issued an `Mcp-Session-Id`), that id must contain only visible ASCII\n * characters per the spec. Skipped over stdio and for stateless HTTP servers\n * (statelessness is spec-valid) — so this rule only fires on a genuine\n * violation.\n */\nexport const httpSessionIdValid: Rule = {\n id: 'transport/http-session-id-valid',\n specVersion: '2025-11-25',\n category: 'transport',\n severity: 'error',\n title: 'HTTP session id contains only visible ASCII',\n specRef: 'Transports §Streamable HTTP / Session management',\n async run(ctx) {\n if (ctx.transport.kind !== 'http') {\n throw new SkipRule('Not an HTTP connection.');\n }\n const sessionId = ctx.transport.sessionId;\n if (sessionId === undefined) {\n throw new SkipRule('Server operates statelessly (no Mcp-Session-Id issued).');\n }\n if (!VISIBLE_ASCII.test(sessionId)) {\n return [\n finding(\n this,\n 'The issued Mcp-Session-Id contains characters outside visible ASCII (0x21–0x7E).',\n 'Generate session ids using only visible ASCII characters (e.g. a UUID).',\n { sessionId },\n ),\n ];\n }\n return [];\n },\n};\n","import type { Rule } from '../../rule';\n\nimport { serverInfoName } from './init/server-info-name';\nimport { serverInfoVersion } from './init/server-info-version';\n\nimport { toolsListAvailable } from './discovery/tools-list';\nimport { toolsHaveNames } from './discovery/tools-have-names';\nimport { toolsHaveInputSchema } from './discovery/tools-have-input-schema';\nimport { toolNamesUnique } from './discovery/tool-names-unique';\nimport { resourcesListAvailable } from './discovery/resources-list';\nimport { resourcesHaveUri } from './discovery/resources-have-uri';\nimport { promptsListAvailable } from './discovery/prompts-list';\nimport { promptsHaveNames } from './discovery/prompts-have-names';\n\nimport { unknownMethod } from './errors/unknown-method';\nimport { unknownTool } from './errors/unknown-tool';\nimport { toolInvalidParams } from './errors/tool-invalid-params';\nimport { unknownResource } from './errors/unknown-resource';\nimport { errorObjectShape } from './errors/error-object-shape';\n\nimport { httpSessionIdValid } from './transport/http-session-id-valid';\n\n// Re-export individual rules so fixture-pair tests can reference them by name.\nexport {\n serverInfoName,\n serverInfoVersion,\n toolsListAvailable,\n toolsHaveNames,\n toolsHaveInputSchema,\n toolNamesUnique,\n resourcesListAvailable,\n resourcesHaveUri,\n promptsListAvailable,\n promptsHaveNames,\n unknownMethod,\n unknownTool,\n toolInvalidParams,\n unknownResource,\n errorObjectShape,\n httpSessionIdValid,\n};\n\n/** All rules for spec version 2025-11-25, in reporting order. */\nexport const rules2025_11_25: readonly Rule[] = [\n // initialization\n serverInfoName,\n serverInfoVersion,\n // discovery\n toolsListAvailable,\n toolsHaveNames,\n toolsHaveInputSchema,\n toolNamesUnique,\n resourcesListAvailable,\n resourcesHaveUri,\n promptsListAvailable,\n promptsHaveNames,\n // error-semantics\n unknownMethod,\n unknownTool,\n toolInvalidParams,\n unknownResource,\n errorObjectShape,\n // transport\n httpSessionIdValid,\n];\n","import type { Rule } from './rule';\nimport type { SpecVersion } from './types';\nimport { rules2025_11_25 } from './rules/2025-11-25/index';\n\n/**\n * The complete rule catalog. Rules are grouped by spec version at the source\n * level and never merged across versions (CLAUDE.md hard rule #2).\n */\nconst ALL_RULES: readonly Rule[] = [...rules2025_11_25];\n\n/** Rules that target the given spec version, in registration order. */\nexport function rulesForSpecVersion(version: SpecVersion): Rule[] {\n return ALL_RULES.filter((rule) => rule.specVersion === version);\n}\n\n/** The full catalog (all versions) — used for introspection/tests. */\nexport function allRules(): readonly Rule[] {\n return ALL_RULES;\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { BRAND } from '../brand';\nimport type { ConnectedClient, HttpTargetConfig } from './types';\n\nexport type { HttpTargetConfig } from './types';\n\n/**\n * Connect to a running Streamable HTTP MCP server and complete the handshake\n * using the official SDK. The server is not ours to manage — over HTTP the\n * runner owns only the connection: `connect()` performs initialize (and the SDK\n * captures the `Mcp-Session-Id` the server issues), `close()` ends the session\n * (the SDK sends the terminating `DELETE`). Rules never touch the session or\n * HTTP verbs; the negotiated session id is surfaced via {@link ConnectedClient.transport}.\n */\nexport async function connectHttp(target: HttpTargetConfig): Promise<ConnectedClient> {\n let url: URL;\n try {\n url = new URL(target.url);\n } catch (err) {\n throw new Error(`Invalid HTTP target url: ${target.url}`, { cause: err });\n }\n\n const transport = new StreamableHTTPClientTransport(url, {\n requestInit: target.headers ? { headers: target.headers } : undefined,\n });\n\n const client = new Client(\n { name: `${BRAND.name}-probe`, version: '0.0.0' },\n { capabilities: {} },\n );\n\n try {\n await client.connect(transport);\n } catch (err) {\n await transport.close().catch(() => undefined);\n throw new Error(\n `Failed to connect to an MCP server over Streamable HTTP (url: ${target.url}). ` +\n 'Check that the server is running and the URL points at its MCP endpoint.',\n { cause: err },\n );\n }\n\n return {\n client,\n transport: { kind: 'http', sessionId: transport.sessionId },\n close: async () => {\n await client.close();\n },\n };\n}\n","/**\n * The single source of truth for the product name (CLAUDE.md: \"the name lives\n * in one constant pending final branding\"). Rename here only.\n */\nexport const BRAND = {\n /** Display name of the product. */\n name: 'vexyo',\n /** CLI command / binary name. */\n bin: 'vexyo',\n} as const;\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport { BRAND } from '../brand';\nimport type { ConnectedClient, StdioTargetConfig } from './types';\n\nexport type { StdioTargetConfig } from './types';\n\n/**\n * Spawn the target server over stdio and complete the MCP handshake using the\n * official SDK (CLAUDE.md hard rule #1). Over stdio the client transport owns\n * the spawned process, so `close()` also terminates the server. Callers must\n * always `close()` the returned handle to avoid leaking the child process.\n */\nexport async function connectStdio(target: StdioTargetConfig): Promise<ConnectedClient> {\n const transport = new StdioClientTransport({\n command: target.command,\n args: target.args,\n cwd: target.cwd,\n // When env is omitted the SDK supplies a safe default (PATH/HOME/etc.).\n env: target.env,\n stderr: 'inherit',\n });\n\n const client = new Client(\n { name: `${BRAND.name}-probe`, version: '0.0.0' },\n { capabilities: {} },\n );\n\n try {\n await client.connect(transport);\n } catch (err) {\n await transport.close().catch(() => undefined);\n throw new Error(\n `Failed to connect to an MCP server over stdio (command: ${target.command}). ` +\n 'Check that the command starts a stdio MCP server and exits cleanly on stdin close.',\n { cause: err },\n );\n }\n\n return {\n client,\n transport: { kind: 'stdio' },\n close: async () => {\n await client.close();\n },\n };\n}\n","import { connectHttp } from './http';\nimport { connectStdio } from './stdio';\nimport type { ConnectedClient, ConnectTarget } from './types';\n\nexport { connectStdio } from './stdio';\nexport { connectHttp } from './http';\nexport type {\n ConnectedClient,\n ConnectTarget,\n HttpTargetConfig,\n StdioTargetConfig,\n TransportInfo,\n} from './types';\n\n/** Connect to a target over whichever transport it declares. */\nexport function connectTarget(target: ConnectTarget): Promise<ConnectedClient> {\n return target.transport === 'stdio' ? connectStdio(target.stdio) : connectHttp(target.http);\n}\n","import { cleanErrorMessage } from './mcp/errors';\nimport { connectTarget, type ConnectTarget } from './transports/index';\nimport { rulesForSpecVersion } from './registry';\nimport { SkipRule, type Rule, type RuleContext } from './rule';\nimport type { RuleResult, RunResult, RunSummary, RunTarget, Severity, SpecVersion } from './types';\n\nexport interface RunSuiteOptions {\n specVersion: SpecVersion;\n target: ConnectTarget;\n /** Severity at/above which findings cause a non-zero exit. Default `error`. */\n failOn?: Severity;\n /**\n * Optional extra checks run against the *same* connection after the\n * conformance rules (e.g. regression drift). Their results are appended.\n */\n extraChecks?: (ctx: RuleContext) => Promise<RuleResult[]>;\n}\n\n/** Human-readable description of a connect target for reporters. */\nfunction describeTarget(target: ConnectTarget): RunTarget {\n if (target.transport === 'http') {\n return { transport: 'http', description: `http: ${target.http.url}` };\n }\n const { command, args } = target.stdio;\n return { transport: 'stdio', description: `stdio: ${command} ${(args ?? []).join(' ')}`.trim() };\n}\n\nconst SEVERITY_RANK: Record<Severity, number> = { info: 1, warning: 2, error: 3 };\n\n/**\n * Connect to the target server, run every rule for the requested spec version\n * (plus any extra checks), and assemble a {@link RunResult}. Connection/\n * handshake failures throw (the CLI maps them to exit code 2); per-rule\n * failures are captured as findings.\n */\nexport async function runSuite(opts: RunSuiteOptions): Promise<RunResult> {\n const startedAt = new Date().toISOString();\n const failOn: Severity = opts.failOn ?? 'error';\n const rules = rulesForSpecVersion(opts.specVersion);\n const target = describeTarget(opts.target);\n\n const conn = await connectTarget(opts.target);\n let results: RuleResult[];\n try {\n const ctx: RuleContext = {\n client: conn.client,\n serverInfo: conn.client.getServerVersion(),\n capabilities: conn.client.getServerCapabilities(),\n transport: conn.transport,\n specVersion: opts.specVersion,\n };\n results = await runRules(ctx, rules);\n if (opts.extraChecks) {\n results.push(...(await opts.extraChecks(ctx)));\n }\n } finally {\n await conn.close().catch(() => undefined);\n }\n\n const finishedAt = new Date().toISOString();\n return {\n specVersion: opts.specVersion,\n target,\n startedAt,\n finishedAt,\n results,\n summary: summarizeResults(results),\n exitCode: computeExitCode(results, failOn),\n };\n}\n\n/**\n * Run a set of rules against an already-connected context. Extracted from\n * {@link runSuite} so rule-outcome handling is unit-testable without a live\n * server connection.\n */\nexport async function runRules(ctx: RuleContext, rules: readonly Rule[]): Promise<RuleResult[]> {\n const results: RuleResult[] = [];\n for (const rule of rules) {\n results.push(await runOneRule(rule, ctx));\n }\n return results;\n}\n\nasync function runOneRule(rule: Rule, ctx: RuleContext): Promise<RuleResult> {\n const start = Date.now();\n const base = {\n ruleId: rule.id,\n title: rule.title,\n category: rule.category,\n severity: rule.severity,\n specVersion: rule.specVersion,\n specRef: rule.specRef,\n } as const;\n\n try {\n const findings = await rule.run(ctx);\n return {\n ...base,\n status: statusFromFindings(findings),\n findings,\n durationMs: Date.now() - start,\n };\n } catch (err) {\n if (err instanceof SkipRule) {\n return {\n ...base,\n status: 'skip',\n skipReason: err.reason,\n findings: [],\n durationMs: Date.now() - start,\n };\n }\n return {\n ...base,\n status: 'error',\n findings: [\n {\n ruleId: rule.id,\n severity: rule.severity,\n message: `Rule threw an unexpected error: ${cleanErrorMessage(err)}`,\n remediation:\n 'This usually means the server crashed mid-run or the rule has a bug. ' +\n 'Re-run and inspect the server logs.',\n specRef: rule.specRef,\n detail: err instanceof Error ? { stack: err.stack } : err,\n },\n ],\n durationMs: Date.now() - start,\n };\n }\n}\n\n/** A result passes with no findings, fails on any error-severity finding, else warns. */\nfunction statusFromFindings(findings: { severity: Severity }[]): 'pass' | 'fail' | 'warn' {\n if (findings.length === 0) {\n return 'pass';\n }\n return findings.some((f) => f.severity === 'error') ? 'fail' : 'warn';\n}\n\nexport function summarizeResults(results: RuleResult[]): RunSummary {\n const summary: RunSummary = {\n pass: 0,\n fail: 0,\n warn: 0,\n skip: 0,\n error: 0,\n total: results.length,\n };\n for (const result of results) {\n summary[result.status] += 1;\n }\n return summary;\n}\n\n/**\n * Exit 1 if any rule errored, or any finding is at/above the `failOn` severity;\n * otherwise 0. Harness/config errors (exit 2) surface as thrown exceptions.\n */\nexport function computeExitCode(results: RuleResult[], failOn: Severity): 0 | 1 {\n const threshold = SEVERITY_RANK[failOn];\n for (const result of results) {\n if (result.status === 'error') {\n return 1;\n }\n for (const finding of result.findings) {\n if (SEVERITY_RANK[finding.severity] >= threshold) {\n return 1;\n }\n }\n }\n return 0;\n}\n","import { z } from 'zod';\n\n/**\n * Golden-file format contract. This becomes public the moment a user commits a\n * golden, so it is versioned: bump {@link GOLDEN_FORMAT_VERSION} to evolve the\n * shape, and readers reject a mismatched version with a clear error rather than\n * silently misinterpreting old goldens.\n */\nexport const GOLDEN_FORMAT_VERSION = 1;\n\n/** An opaque JSON object (a tool/resource/prompt definition, or a tool result). */\nconst jsonRecord = z.record(z.string(), z.unknown());\n\nexport const GoldenManifestSchema = z.object({\n formatVersion: z.literal(GOLDEN_FORMAT_VERSION),\n specVersion: z.string(),\n server: z.object({ name: z.string(), version: z.string() }),\n tools: z.array(jsonRecord),\n resources: z.array(jsonRecord),\n prompts: z.array(jsonRecord),\n});\nexport type GoldenManifest = z.infer<typeof GoldenManifestSchema>;\n\nexport const GoldenCaseSchema = z.object({\n case: z.string(),\n arguments: z.record(z.string(), z.unknown()),\n /** Names of the normalizers applied at record time (for human reference). */\n normalizers: z.array(z.string()),\n result: z.unknown(),\n});\nexport type GoldenCase = z.infer<typeof GoldenCaseSchema>;\n\nexport const GoldenRecordingSchema = z.object({\n formatVersion: z.literal(GOLDEN_FORMAT_VERSION),\n tool: z.string(),\n cases: z.array(GoldenCaseSchema),\n});\nexport type GoldenRecording = z.infer<typeof GoldenRecordingSchema>;\n\n/** The full committed golden set: one manifest + one recording file per tool. */\nexport interface GoldenSet {\n manifest: GoldenManifest;\n recordings: GoldenRecording[];\n}\n\n// --- Regression finding detail (rides the existing `Finding.detail`) ---\n\nexport const FieldDiffSchema = z.object({\n path: z.string(),\n before: z.unknown().optional(),\n after: z.unknown().optional(),\n});\nexport type FieldDiff = z.infer<typeof FieldDiffSchema>;\n\nexport type RegressionKind = 'schema' | 'behavioral' | 'coverage';\n\nexport const RegressionDetailSchema = z.object({\n kind: z.enum(['schema', 'behavioral', 'coverage']),\n target: z.object({\n type: z.enum(['tool', 'resource', 'prompt']),\n name: z.string(),\n case: z.string().optional(),\n }),\n change: z.enum(['added', 'removed', 'changed']),\n before: z.unknown().optional(),\n after: z.unknown().optional(),\n fieldDiffs: z.array(FieldDiffSchema).optional(),\n /** Builtin normalizer names that would collapse a volatile-looking diff. */\n suggestedNormalizers: z.array(z.string()).optional(),\n});\nexport type RegressionDetail = z.infer<typeof RegressionDetailSchema>;\n","/**\n * Normalizers collapse volatile values (timestamps, ids, paths) to stable\n * placeholders so a re-recorded golden matches. Both `record` and the\n * regression comparison run the *same* pipeline, so a normalized field can\n * never register as drift.\n */\n\nexport type NormalizerFn = (value: unknown) => unknown;\n\n/** A normalizer is either a builtin name or an inline `{ name, apply }` object. */\nexport interface NormalizerObject {\n name: string;\n apply: NormalizerFn;\n}\nexport type NormalizerRef = string | NormalizerObject;\n\ninterface StringPattern {\n readonly regex: RegExp;\n readonly placeholder: string;\n}\n\n/** Builtins that replace matching substrings inside every string value. */\nconst STRING_PATTERNS: Record<string, StringPattern> = {\n 'iso-timestamp': {\n regex: /\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})/g,\n placeholder: '<timestamp>',\n },\n uuid: {\n regex: /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/g,\n placeholder: '<uuid>',\n },\n 'hex-id': { regex: /\\b[0-9a-fA-F]{16,}\\b/g, placeholder: '<hex>' },\n 'abs-path': { regex: /(?:\\/[\\w.-]+){2,}\\/?/g, placeholder: '<path>' },\n};\n\n/** Builtins that replace integer values in a plausible epoch range. */\nconst NUMBER_RANGES: Record<string, { min: number; max: number }> = {\n 'epoch-millis': { min: 1_000_000_000_000, max: 2_000_000_000_000 },\n 'epoch-seconds': { min: 1_000_000_000, max: 2_000_000_000 },\n};\n\nexport const BUILTIN_NORMALIZER_NAMES: readonly string[] = [\n ...Object.keys(STRING_PATTERNS),\n ...Object.keys(NUMBER_RANGES),\n];\n\nfunction builtin(name: string): NormalizerFn {\n const stringPattern = STRING_PATTERNS[name];\n if (stringPattern) {\n return (value) =>\n mapScalars(value, (scalar) =>\n typeof scalar === 'string'\n ? scalar.replace(stringPattern.regex, stringPattern.placeholder)\n : scalar,\n );\n }\n const range = NUMBER_RANGES[name];\n if (range) {\n return (value) =>\n mapScalars(value, (scalar) =>\n typeof scalar === 'number' &&\n Number.isInteger(scalar) &&\n scalar >= range.min &&\n scalar < range.max\n ? '<epoch>'\n : scalar,\n );\n }\n throw new Error(\n `Unknown normalizer \"${name}\". Available builtins: ${BUILTIN_NORMALIZER_NAMES.join(', ')}.`,\n );\n}\n\n/** Deep-map every scalar (non-object, non-array) value in a JSON tree. */\nfunction mapScalars(value: unknown, fn: (scalar: unknown) => unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => mapScalars(item, fn));\n }\n if (value !== null && typeof value === 'object') {\n const record = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(record)) {\n out[key] = mapScalars(record[key], fn);\n }\n return out;\n }\n return fn(value);\n}\n\nfunction resolve(ref: NormalizerRef): NormalizerFn {\n return typeof ref === 'string' ? builtin(ref) : ref.apply;\n}\n\nexport function normalizerName(ref: NormalizerRef): string {\n return typeof ref === 'string' ? ref : ref.name;\n}\n\n/** Apply a normalizer pipeline (in order) to a value. */\nexport function applyNormalizers(value: unknown, refs: readonly NormalizerRef[]): unknown {\n return refs.reduce<unknown>((acc, ref) => resolve(ref)(acc), value);\n}\n\n/**\n * Given a changed field's before/after, return builtin normalizer names that\n * would collapse it — i.e. whose pattern matches BOTH sides. This is what turns\n * a noisy diff into \"add this normalizer\" guidance instead of blind re-record\n * (CLAUDE.md hard rule #6).\n */\nexport function suggestNormalizer(before: unknown, after: unknown): string[] {\n const suggestions: string[] = [];\n for (const [name, pattern] of Object.entries(STRING_PATTERNS)) {\n if (\n typeof before === 'string' &&\n typeof after === 'string' &&\n matchesPattern(before, pattern.regex) &&\n matchesPattern(after, pattern.regex)\n ) {\n suggestions.push(name);\n }\n }\n for (const [name, range] of Object.entries(NUMBER_RANGES)) {\n if (inRange(before, range) && inRange(after, range)) {\n suggestions.push(name);\n }\n }\n return suggestions;\n}\n\nfunction matchesPattern(value: string, regex: RegExp): boolean {\n // Fresh lastIndex — the shared regexes are global.\n return new RegExp(regex.source).test(value);\n}\n\nfunction inRange(value: unknown, range: { min: number; max: number }): boolean {\n return (\n typeof value === 'number' && Number.isInteger(value) && value >= range.min && value < range.max\n );\n}\n","import type { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n anyResult,\n promptsListResult,\n resourcesListResult,\n stringField,\n toolsListResult,\n} from '../mcp/schemas';\nimport type { GoldenConfig } from './config';\nimport {\n GOLDEN_FORMAT_VERSION,\n type GoldenManifest,\n type GoldenRecording,\n type GoldenSet,\n} from './format';\nimport { applyNormalizers, normalizerName, type NormalizerRef } from './normalize';\n\n/**\n * Capture a golden set from a connected server: a schema manifest (always safe —\n * read-only list calls) plus behavioral recordings for the explicitly-configured\n * tools only. A tool absent from `cfg.tools` is never invoked (opt-in per\n * CLAUDE.md side-effect safety).\n */\nexport async function recordGoldens(client: Client, cfg: GoldenConfig): Promise<GoldenSet> {\n const manifest = await snapshotManifest(client, cfg.specVersion);\n\n const recordings: GoldenRecording[] = [];\n for (const tool of Object.keys(cfg.tools).sort()) {\n const toolSpec = cfg.tools[tool];\n if (!toolSpec) {\n continue;\n }\n const refs: NormalizerRef[] = toolSpec.normalizers ?? cfg.defaultNormalizers;\n const cases = [];\n for (const spec of [...toolSpec.cases].sort((a, b) => compare(a.case, b.case))) {\n const raw = await client.request(\n { method: 'tools/call', params: { name: tool, arguments: spec.arguments } },\n anyResult,\n );\n cases.push({\n case: spec.case,\n arguments: spec.arguments,\n normalizers: refs.map(normalizerName),\n result: applyNormalizers(raw, refs),\n });\n }\n recordings.push({ formatVersion: GOLDEN_FORMAT_VERSION, tool, cases });\n }\n\n return { manifest, recordings };\n}\n\nasync function snapshotManifest(client: Client, specVersion: string): Promise<GoldenManifest> {\n const caps = client.getServerCapabilities();\n const info = client.getServerVersion();\n\n const tools = caps?.tools\n ? (await client.request({ method: 'tools/list', params: {} }, toolsListResult)).tools\n : [];\n const resources = caps?.resources\n ? (await client.request({ method: 'resources/list', params: {} }, resourcesListResult))\n .resources\n : [];\n const prompts = caps?.prompts\n ? (await client.request({ method: 'prompts/list', params: {} }, promptsListResult)).prompts\n : [];\n\n return {\n formatVersion: GOLDEN_FORMAT_VERSION,\n specVersion,\n server: { name: info?.name ?? '', version: info?.version ?? '' },\n tools: sortBy(tools, 'name'),\n resources: sortBy(resources, 'uri'),\n prompts: sortBy(prompts, 'name'),\n };\n}\n\nfunction sortBy(\n items: ReadonlyArray<Record<string, unknown>>,\n key: string,\n): Record<string, unknown>[] {\n return [...items].sort((a, b) => compare(stringField(a, key) ?? '', stringField(b, key) ?? ''));\n}\n\nfunction compare(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n","/**\n * The single choke-point for golden-file determinism. Every golden is written\n * through {@link stableStringify}, which recursively sorts object keys and emits\n * JSON that is a **fixed point of Prettier** (2-space indent, trailing newline):\n * running `prettier --check` on a freshly written golden makes no changes. This\n * matters because users commit goldens into repos that run Prettier — our output\n * must survive that byte-identically, not get reformatted on the next commit.\n *\n * The rule mirrors Prettier's JSON printer (with the default `objectWrap:\n * \"preserve\"`): a container is printed on one line if that flat form fits within\n * the print width at its column, otherwise it breaks one entry per line. Objects\n * use `{ ... }` (inner spaces); arrays use `[...]`; a broken array of only\n * numbers is packed (\"fill\") the way Prettier packs number lists.\n */\n\n// Must match `.prettierrc.json` printWidth. Changing either requires re-recording goldens.\nconst PRINT_WIDTH = 100;\nconst INDENT = ' ';\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/** Drop `undefined`/function values (as JSON would) and sort object keys. */\nfunction canonicalize(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => canonicalize(item === undefined ? null : item));\n }\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(value).sort()) {\n const child = value[key];\n if (child !== undefined && typeof child !== 'function') {\n out[key] = canonicalize(child);\n }\n }\n return out;\n }\n return typeof value === 'function' ? null : value;\n}\n\n/** Single-line rendering of a canonical value (used to measure fit). */\nfunction flat(value: unknown): string {\n if (Array.isArray(value)) {\n return value.length === 0 ? '[]' : `[${value.map(flat).join(', ')}]`;\n }\n if (isPlainObject(value)) {\n const keys = Object.keys(value);\n if (keys.length === 0) {\n return '{}';\n }\n return `{ ${keys.map((k) => `${JSON.stringify(k)}: ${flat(value[k])}`).join(', ')} }`;\n }\n return JSON.stringify(value);\n}\n\n/**\n * Print a canonical value starting at `column`, breaking to `level` indentation\n * when the flat form (plus a trailing comma, if this value is followed by a\n * sibling) would exceed the print width.\n */\nfunction print(value: unknown, level: number, column: number, trailer: number): string {\n if (!Array.isArray(value) && !isPlainObject(value)) {\n return JSON.stringify(value);\n }\n\n const flatForm = flat(value);\n const mustBreak = Array.isArray(value) && forcesBreak(value);\n if (!mustBreak && column + flatForm.length + trailer <= PRINT_WIDTH) {\n return flatForm;\n }\n\n const childIndent = INDENT.repeat(level + 1);\n const closeIndent = INDENT.repeat(level);\n\n if (Array.isArray(value)) {\n if (value.every((item) => typeof item === 'number')) {\n return fillNumbers(value, level);\n }\n const items = value.map((item, i) =>\n print(item, level + 1, childIndent.length, i < value.length - 1 ? 1 : 0),\n );\n return `[\\n${items.map((s) => childIndent + s).join(',\\n')}\\n${closeIndent}]`;\n }\n\n const keys = Object.keys(value);\n const props = keys.map((key, i) => {\n const prefix = `${JSON.stringify(key)}: `;\n const rendered = print(\n value[key],\n level + 1,\n childIndent.length + prefix.length,\n i < keys.length - 1 ? 1 : 0,\n );\n return `${childIndent}${prefix}${rendered}`;\n });\n return `{\\n${props.join(',\\n')}\\n${closeIndent}}`;\n}\n\n/**\n * Prettier's \"table\" heuristic: an array is always broken onto multiple lines\n * (regardless of width) when it has more than one element and every element is\n * an array or object with more than one child.\n */\nfunction forcesBreak(value: readonly unknown[]): boolean {\n return (\n value.length > 1 &&\n value.every(\n (el) =>\n (Array.isArray(el) && el.length > 1) || (isPlainObject(el) && Object.keys(el).length > 1),\n )\n );\n}\n\n/** Pack a broken number array, wrapping before the width is exceeded (Prettier \"fill\"). */\nfunction fillNumbers(value: readonly number[], level: number): string {\n const childIndent = INDENT.repeat(level + 1);\n const lines: string[] = [];\n let current = '';\n value.forEach((num, i) => {\n const token = i < value.length - 1 ? `${JSON.stringify(num)},` : JSON.stringify(num);\n if (current === '') {\n current = token;\n } else if (childIndent.length + current.length + 1 + token.length <= PRINT_WIDTH) {\n current = `${current} ${token}`;\n } else {\n lines.push(current);\n current = token;\n }\n });\n if (current !== '') {\n lines.push(current);\n }\n return `[\\n${lines.map((l) => childIndent + l).join('\\n')}\\n${INDENT.repeat(level)}]`;\n}\n\n/** Deterministic, Prettier-stable JSON: sorted keys, 2-space indent, trailing newline. */\nexport function stableStringify(value: unknown): string {\n return `${print(canonicalize(value), 0, 0, 0)}\\n`;\n}\n\n/** Deep JSON equality via canonical serialization. */\nexport function jsonEqual(a: unknown, b: unknown): boolean {\n return stableStringify(a) === stableStringify(b);\n}\n","import { jsonEqual } from './serialize';\nimport type { FieldDiff } from './format';\nimport { isRecord } from '../mcp/schemas';\n\n/**\n * Structural JSON diff producing field-level before/after pairs keyed by a\n * JSON-path-ish string (`content[0].text`). Used to point a user at the exact\n * unstable field so they can add a normalizer rather than blindly re-record.\n */\nexport function diffValue(before: unknown, after: unknown, path = ''): FieldDiff[] {\n if (jsonEqual(before, after)) {\n return [];\n }\n\n if (isRecord(before) && isRecord(after)) {\n const keys = [...new Set([...Object.keys(before), ...Object.keys(after)])].sort();\n return keys.flatMap((key) => diffValue(before[key], after[key], join(path, key)));\n }\n\n if (Array.isArray(before) && Array.isArray(after) && before.length === after.length) {\n return before.flatMap((item, i) => diffValue(item, after[i], `${path}[${i}]`));\n }\n\n return [{ path: path || '(root)', before, after }];\n}\n\nfunction join(path: string, key: string): string {\n return path ? `${path}.${key}` : key;\n}\n","import type { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n anyResult,\n promptsListResult,\n resourcesListResult,\n stringField,\n toolsListResult,\n} from '../mcp/schemas';\nimport type { Finding, RuleResult, Severity, SpecVersion } from '../types';\nimport type { GoldenConfig } from './config';\nimport { diffValue } from './diff';\nimport type { GoldenCase, GoldenSet, RegressionDetail, RegressionKind } from './format';\nimport { applyNormalizers, type NormalizerRef, suggestNormalizer } from './normalize';\nimport { jsonEqual } from './serialize';\n\nconst SPEC_REF = 'Regression / Golden set';\ntype TargetType = 'tool' | 'resource' | 'prompt';\n\ninterface LiveSnapshot {\n tools: Record<string, unknown>[];\n resources: Record<string, unknown>[];\n prompts: Record<string, unknown>[];\n}\n\n/**\n * Compare the server's current behavior against a committed golden set and\n * return one {@link RuleResult} per drift (plus a `pass` per matching case).\n * Three drift classes, each with its own severity:\n * - schema (error): a definition changed\n * - behavioral (error): a recorded call's normalized output changed\n * - coverage (error/warn): a golden's target was removed / a live target has no golden\n */\nexport async function runRegression(\n client: Client,\n golden: GoldenSet,\n cfg: GoldenConfig,\n): Promise<RuleResult[]> {\n const specVersion = cfg.specVersion as SpecVersion;\n const live = await snapshotLive(client);\n const results: RuleResult[] = [];\n\n results.push(...manifestDrift(specVersion, 'tool', 'name', golden.manifest.tools, live.tools));\n results.push(\n ...manifestDrift(specVersion, 'resource', 'uri', golden.manifest.resources, live.resources),\n );\n results.push(\n ...manifestDrift(specVersion, 'prompt', 'name', golden.manifest.prompts, live.prompts),\n );\n\n const liveToolNames = new Set(\n live.tools.map((t) => stringField(t, 'name')).filter((n): n is string => !!n),\n );\n for (const recording of golden.recordings) {\n if (!liveToolNames.has(recording.tool)) {\n continue; // removal is already reported as coverage drift\n }\n const refs = cfg.tools[recording.tool]?.normalizers ?? cfg.defaultNormalizers;\n for (const testCase of recording.cases) {\n results.push(await behavioralDrift(client, specVersion, recording.tool, testCase, refs));\n }\n }\n\n return results;\n}\n\n/** Schema + coverage drift for one target family (tools / resources / prompts). */\nfunction manifestDrift(\n specVersion: SpecVersion,\n type: TargetType,\n keyField: string,\n goldenDefs: ReadonlyArray<Record<string, unknown>>,\n liveDefs: ReadonlyArray<Record<string, unknown>>,\n): RuleResult[] {\n const results: RuleResult[] = [];\n const liveByKey = new Map<string, Record<string, unknown>>();\n for (const def of liveDefs) {\n const key = stringField(def, keyField);\n if (key !== undefined) {\n liveByKey.set(key, def);\n }\n }\n\n const goldenKeys = new Set<string>();\n for (const def of goldenDefs) {\n const key = stringField(def, keyField);\n if (key === undefined) {\n continue;\n }\n goldenKeys.add(key);\n const liveDef = liveByKey.get(key);\n if (!liveDef) {\n results.push(\n drift(specVersion, 'coverage', 'error', {\n detail: { kind: 'coverage', target: { type, name: key }, change: 'removed', before: def },\n message: `${type} \"${key}\" has a golden but no longer exists on the server.`,\n remediation:\n 'Restore the target, or remove its golden if the removal is intended, then re-record.',\n }),\n );\n } else if (!jsonEqual(def, liveDef)) {\n results.push(\n drift(specVersion, 'schema', 'error', {\n detail: {\n kind: 'schema',\n target: { type, name: key },\n change: 'changed',\n before: def,\n after: liveDef,\n fieldDiffs: diffValue(def, liveDef),\n },\n message: `${type} \"${key}\" definition changed since the golden was recorded.`,\n remediation: 'Review the change; if intended, re-record with `vexyo record`.',\n }),\n );\n }\n }\n\n for (const def of liveDefs) {\n const key = stringField(def, keyField);\n if (key === undefined || goldenKeys.has(key)) {\n continue;\n }\n results.push(\n drift(specVersion, 'coverage', 'warning', {\n detail: { kind: 'coverage', target: { type, name: key }, change: 'added', after: def },\n message: `${type} \"${key}\" exists on the server but has no golden.`,\n remediation: 'Run `vexyo record` to capture it into the golden set.',\n }),\n );\n }\n\n return results;\n}\n\nasync function behavioralDrift(\n client: Client,\n specVersion: SpecVersion,\n tool: string,\n testCase: GoldenCase,\n refs: readonly NormalizerRef[],\n): Promise<RuleResult> {\n let liveNormalized: unknown;\n try {\n const raw = await client.request(\n { method: 'tools/call', params: { name: tool, arguments: testCase.arguments } },\n anyResult,\n );\n liveNormalized = applyNormalizers(raw, refs);\n } catch (err) {\n liveNormalized = { error: err instanceof Error ? err.message : String(err) };\n }\n\n const fieldDiffs = diffValue(testCase.result, liveNormalized);\n if (fieldDiffs.length === 0) {\n return passResult(specVersion, tool, testCase.case);\n }\n\n const suggested = [...new Set(fieldDiffs.flatMap((d) => suggestNormalizer(d.before, d.after)))];\n const remediation =\n suggested.length > 0\n ? `Field(s) look volatile (${suggested.join(', ')}); add the normalizer(s) for \"${tool}\", or re-record if the change is real.`\n : 'If the change is intended, re-record with `vexyo record`.';\n\n return drift(specVersion, 'behavioral', 'error', {\n detail: {\n kind: 'behavioral',\n target: { type: 'tool', name: tool, case: testCase.case },\n change: 'changed',\n before: testCase.result,\n after: liveNormalized,\n fieldDiffs,\n suggestedNormalizers: suggested.length > 0 ? suggested : undefined,\n },\n message: `Tool \"${tool}\" (case \"${testCase.case}\") output differs from its golden.`,\n remediation,\n });\n}\n\ninterface DriftSpec {\n detail: RegressionDetail;\n message: string;\n remediation: string;\n}\n\nfunction drift(\n specVersion: SpecVersion,\n kind: RegressionKind,\n severity: Severity,\n spec: DriftSpec,\n): RuleResult {\n const { target } = spec.detail;\n const suffix = target.case ? `${target.name}:${target.case}` : target.name;\n const ruleId = `regression/${kind}-drift:${target.type}:${suffix}`;\n const finding: Finding = {\n ruleId,\n severity,\n message: spec.message,\n remediation: spec.remediation,\n specRef: SPEC_REF,\n detail: spec.detail,\n };\n return {\n ruleId,\n title: `${kind} drift — ${target.type} ${target.name}`,\n category: 'regression',\n severity,\n specVersion,\n specRef: SPEC_REF,\n status: severity === 'error' ? 'fail' : 'warn',\n findings: [finding],\n durationMs: 0,\n };\n}\n\nfunction passResult(specVersion: SpecVersion, tool: string, testCase: string): RuleResult {\n return {\n ruleId: `regression/behavioral:${tool}:${testCase}`,\n title: `behavioral — tool ${tool} (case ${testCase})`,\n category: 'regression',\n severity: 'info',\n specVersion,\n specRef: SPEC_REF,\n status: 'pass',\n findings: [],\n durationMs: 0,\n };\n}\n\nasync function snapshotLive(client: Client): Promise<LiveSnapshot> {\n const caps = client.getServerCapabilities();\n const tools = caps?.tools\n ? (await client.request({ method: 'tools/list', params: {} }, toolsListResult)).tools\n : [];\n const resources = caps?.resources\n ? (await client.request({ method: 'resources/list', params: {} }, resourcesListResult))\n .resources\n : [];\n const prompts = caps?.prompts\n ? (await client.request({ method: 'prompts/list', params: {} }, promptsListResult)).prompts\n : [];\n return { tools, resources, prompts };\n}\n","import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { z } from 'zod';\nimport { isRecord } from '../mcp/schemas';\nimport {\n GOLDEN_FORMAT_VERSION,\n GoldenManifestSchema,\n GoldenRecordingSchema,\n type GoldenRecording,\n type GoldenSet,\n} from './format';\nimport { stableStringify } from './serialize';\n\n/** Raised for missing/malformed/version-mismatched golden files (exit 2). */\nexport class GoldenError extends Error {\n constructor(message: string, cause?: unknown) {\n super(message, cause !== undefined ? { cause } : undefined);\n this.name = 'GoldenError';\n }\n}\n\n/** Write the golden set as `manifest.json` + `recordings/<tool>.json`, deterministically. */\nexport async function writeGoldenSet(dir: string, set: GoldenSet): Promise<string[]> {\n await mkdir(join(dir, 'recordings'), { recursive: true });\n const written: string[] = [];\n\n const manifestPath = join(dir, 'manifest.json');\n await writeFile(manifestPath, stableStringify(set.manifest));\n written.push(manifestPath);\n\n for (const recording of [...set.recordings].sort((a, b) => (a.tool < b.tool ? -1 : 1))) {\n const path = join(dir, 'recordings', `${recording.tool}.json`);\n await writeFile(path, stableStringify(recording));\n written.push(path);\n }\n return written;\n}\n\n/** Read and validate a golden set. Throws {@link GoldenError} with a clear message. */\nexport async function readGoldenSet(dir: string): Promise<GoldenSet> {\n const manifestPath = join(dir, 'manifest.json');\n let manifestRaw: string;\n try {\n manifestRaw = await readFile(manifestPath, 'utf8');\n } catch (err) {\n throw new GoldenError(\n `No golden manifest at ${manifestPath}. Run \\`vexyo record\\` to create one.`,\n err,\n );\n }\n const manifest = parseGolden(GoldenManifestSchema, manifestRaw, manifestPath);\n\n const recordings: GoldenRecording[] = [];\n const recordingsDir = join(dir, 'recordings');\n let files: string[] = [];\n try {\n files = (await readdir(recordingsDir)).filter((f) => f.endsWith('.json')).sort();\n } catch {\n files = []; // manifest-only golden set: schema/coverage drift still work\n }\n for (const file of files) {\n const path = join(recordingsDir, file);\n recordings.push(parseGolden(GoldenRecordingSchema, await readFile(path, 'utf8'), path));\n }\n\n return { manifest, recordings };\n}\n\nfunction parseGolden<T>(schema: z.ZodType<T>, raw: string, path: string): T {\n let json: unknown;\n try {\n json = JSON.parse(raw);\n } catch (err) {\n throw new GoldenError(`Golden at ${path} is not valid JSON.`, err);\n }\n\n const parsed = schema.safeParse(json);\n if (parsed.success) {\n return parsed.data;\n }\n\n const version = isRecord(json) ? json['formatVersion'] : undefined;\n if (version !== undefined && version !== GOLDEN_FORMAT_VERSION) {\n throw new GoldenError(\n `Golden at ${path} has formatVersion ${String(version)}, but this build expects ` +\n `${GOLDEN_FORMAT_VERSION}. Re-run \\`vexyo record\\` or upgrade vexyo.`,\n );\n }\n const issues = parsed.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new GoldenError(`Golden at ${path} is malformed:\\n${issues}`);\n}\n"],"mappings":";AAeO,IAAM,sBAAmC;;;AC6BzC,IAAM,WAAN,cAAuB,MAAM;AAAA,EAClC,YAA4B,QAAgB;AAC1C,UAAM,MAAM;AADc;AAE1B,SAAK,OAAO;AAAA,EACd;AAAA,EAH4B;AAI9B;AAGO,SAAS,QACd,MACA,SACA,aACA,QACS;AACT,SAAO;AAAA,IACL,QAAQ,KAAK;AAAA,IACb,UAAU,KAAK;AAAA,IACf;AAAA,IACA;AAAA,IACA,SAAS,KAAK;AAAA,IACd;AAAA,EACF;AACF;;;AC1DO,IAAM,iBAAuB;AAAA,EAClC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,UAAM,OAAO,IAAI,YAAY;AAC7B,QAAI,OAAO,SAAS,YAAY,KAAK,WAAW,GAAG;AACjD,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE,YAAY,IAAI,WAAW;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AACF;;;ACvBO,IAAM,oBAA0B;AAAA,EACrC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,OAAO,YAAY,YAAY,QAAQ,WAAW,GAAG;AACvD,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE,YAAY,IAAI,WAAW;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AACF;;;AC3BA,SAAS,KAAAA,UAAS;;;ACAlB,SAAS,gBAAgB;AASlB,SAAS,kBAAkB,KAAsB;AACtD,MAAI,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC7D,QAAM,SAAS;AACf,SAAO,OAAO,KAAK,OAAO,GAAG;AAC3B,cAAU,QAAQ,QAAQ,QAAQ,EAAE;AAAA,EACtC;AACA,SAAO;AACT;AAGO,SAAS,UAAU,KAAkC;AAC1D,SAAO,eAAe,WAAW,IAAI,OAAO;AAC9C;;;ACrBA,SAAS,SAAS;AASX,IAAM,kBAAkB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;AACtF,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC;AACM,IAAM,oBAAoB,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;AAG1F,IAAM,YAAY,EAAE,QAAQ;AAG5B,SAAS,SAAS,OAAkD;AACzE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGO,SAAS,YAAY,QAAiC,KAAiC;AAC5F,QAAM,QAAQ,OAAO,GAAG;AACxB,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;;;AFJO,IAAM,iBAAiBC,GAAE,OAAO,EAAE,SAASA,GAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAcnE,SAAS,cAAc,KAAyB;AACrD,SAAO,EAAE,OAAO,MAAM,MAAM,UAAU,GAAG,GAAG,SAAS,kBAAkB,GAAG,EAAE;AAC9E;AAQA,eAAsB,gBAAgB,KAAsD;AAC1F,MAAI;AACF,YAAQ,MAAM,IAAI,OAAO,QAAQ,EAAE,QAAQ,cAAc,QAAQ,CAAC,EAAE,GAAG,eAAe,GAAG;AAAA,EAC3F,QAAQ;AACN,UAAM,IAAI,SAAS,wBAAwB;AAAA,EAC7C;AACF;AAEA,eAAsB,oBAAoB,KAAsD;AAC9F,MAAI;AACF,YAAQ,MAAM,IAAI,OAAO,QAAQ,EAAE,QAAQ,kBAAkB,QAAQ,CAAC,EAAE,GAAG,mBAAmB,GAC3F;AAAA,EACL,QAAQ;AACN,UAAM,IAAI,SAAS,4BAA4B;AAAA,EACjD;AACF;AAEA,eAAsB,kBAAkB,KAAsD;AAC5F,MAAI;AACF,YAAQ,MAAM,IAAI,OAAO,QAAQ,EAAE,QAAQ,gBAAgB,QAAQ,CAAC,EAAE,GAAG,iBAAiB,GACvF;AAAA,EACL,QAAQ;AACN,UAAM,IAAI,SAAS,0BAA0B;AAAA,EAC/C;AACF;AAOO,SAAS,uBACd,OACoB;AACpB,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,YAAY,MAAM,MAAM;AACrC,UAAM,SAAS,KAAK,aAAa;AACjC,QACE,QACA,SAAS,MAAM,KACf,MAAM,QAAQ,OAAO,UAAU,CAAC,KAChC,OAAO,UAAU,EAAE,SAAS,GAC5B;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;;;AGtFO,IAAM,qBAA2B;AAAA,EACtC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,OAAO;AAC5B,YAAM,IAAI,SAAS,mDAAmD;AAAA,IACxE;AACA,QAAI;AACF,YAAM,IAAI,OAAO,QAAQ,EAAE,QAAQ,cAAc,QAAQ,CAAC,EAAE,GAAG,eAAe;AAC9E,aAAO,CAAC;AAAA,IACV,SAAS,KAAK;AACZ,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE,OAAO,kBAAkB,GAAG,EAAE;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC7BO,IAAM,iBAAuB;AAAA,EAClC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,OAAO;AAC5B,YAAM,IAAI,SAAS,mDAAmD;AAAA,IACxE;AACA,UAAM,QAAQ,MAAM,gBAAgB,GAAG;AACvC,UAAM,UAAU,MAAM,OAAO,CAAC,SAAS;AACrC,YAAM,OAAO,YAAY,MAAM,MAAM;AACrC,aAAO,SAAS,UAAa,KAAK,WAAW;AAAA,IAC/C,CAAC;AACD,QAAI,QAAQ,SAAS,GAAG;AACtB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,GAAG,QAAQ,MAAM;AAAA,UACjB;AAAA,UACA,EAAE,MAAM;AAAA,QACV;AAAA,MACF;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AACF;;;ACxBO,IAAM,uBAA6B;AAAA,EACxC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,OAAO;AAC5B,YAAM,IAAI,SAAS,mDAAmD;AAAA,IACxE;AACA,UAAM,QAAQ,MAAM,gBAAgB,GAAG;AACvC,UAAM,UAAU,MAAM,OAAO,CAAC,SAAS;AACrC,YAAM,SAAS,KAAK,aAAa;AACjC,aAAO,CAAC,SAAS,MAAM,KAAK,OAAO,MAAM,MAAM;AAAA,IACjD,CAAC;AACD,QAAI,QAAQ,SAAS,GAAG;AACtB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,GAAG,QAAQ,MAAM;AAAA,UACjB;AAAA,UACA,EAAE,MAAM;AAAA,QACV;AAAA,MACF;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AACF;;;AC7BO,IAAM,kBAAwB;AAAA,EACnC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,OAAO;AAC5B,YAAM,IAAI,SAAS,mDAAmD;AAAA,IACxE;AACA,UAAM,QAAQ,MAAM,gBAAgB,GAAG;AACvC,UAAM,QAAQ,MAAM,IAAI,CAAC,SAAS,YAAY,MAAM,MAAM,CAAC,EAAE,OAAO,CAAC,MAAmB,CAAC,CAAC,CAAC;AAC3F,UAAM,aAAa,CAAC,GAAG,IAAI,IAAI,MAAM,OAAO,CAAC,MAAM,MAAM,MAAM,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC;AACpF,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,2BAA2B,WAAW,KAAK,IAAI,CAAC;AAAA,UAChD;AAAA,UACA,EAAE,WAAW;AAAA,QACf;AAAA,MACF;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AACF;;;AC1BO,IAAM,yBAA+B;AAAA,EAC1C,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,WAAW;AAChC,YAAM,IAAI,SAAS,uDAAuD;AAAA,IAC5E;AACA,QAAI;AACF,YAAM,IAAI,OAAO,QAAQ,EAAE,QAAQ,kBAAkB,QAAQ,CAAC,EAAE,GAAG,mBAAmB;AACtF,aAAO,CAAC;AAAA,IACV,SAAS,KAAK;AACZ,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE,OAAO,kBAAkB,GAAG,EAAE;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACxBO,IAAM,mBAAyB;AAAA,EACpC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,WAAW;AAChC,YAAM,IAAI,SAAS,uDAAuD;AAAA,IAC5E;AACA,UAAM,YAAY,MAAM,oBAAoB,GAAG;AAC/C,UAAM,UAAU,UAAU,OAAO,CAAC,aAAa;AAC7C,YAAM,MAAM,YAAY,UAAU,KAAK;AACvC,aAAO,QAAQ,UAAa,IAAI,WAAW;AAAA,IAC7C,CAAC;AACD,QAAI,QAAQ,SAAS,GAAG;AACtB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,GAAG,QAAQ,MAAM;AAAA,UACjB;AAAA,UACA,EAAE,UAAU;AAAA,QACd;AAAA,MACF;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AACF;;;AC7BO,IAAM,uBAA6B;AAAA,EACxC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,SAAS;AAC9B,YAAM,IAAI,SAAS,qDAAqD;AAAA,IAC1E;AACA,QAAI;AACF,YAAM,IAAI,OAAO,QAAQ,EAAE,QAAQ,gBAAgB,QAAQ,CAAC,EAAE,GAAG,iBAAiB;AAClF,aAAO,CAAC;AAAA,IACV,SAAS,KAAK;AACZ,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE,OAAO,kBAAkB,GAAG,EAAE;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC5BO,IAAM,mBAAyB;AAAA,EACpC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,SAAS;AAC9B,YAAM,IAAI,SAAS,qDAAqD;AAAA,IAC1E;AACA,UAAM,UAAU,MAAM,kBAAkB,GAAG;AAC3C,UAAM,UAAU,QAAQ,OAAO,CAAC,WAAW;AACzC,YAAM,OAAO,YAAY,QAAQ,MAAM;AACvC,aAAO,SAAS,UAAa,KAAK,WAAW;AAAA,IAC/C,CAAC;AACD,QAAI,QAAQ,SAAS,GAAG;AACtB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,GAAG,QAAQ,MAAM;AAAA,UACjB;AAAA,UACA,EAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AACF;;;AChCA,SAAS,iBAAqC;AAW9C,IAAM,2BAA2B;AAE1B,IAAM,gBAAsB;AAAA,EACjC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,UAAM,QAAQ,EAAE,QAAQ,0BAA0B,QAAQ,CAAC,EAAE;AAC7D,QAAI;AACF,YAAM,IAAI,OAAO,QAAQ,OAAO,SAAS;AACzC,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,OAAO,cAAc,GAAG;AAC9B,UAAI,KAAK,SAAS,UAAU,gBAAgB;AAC1C,eAAO,CAAC;AAAA,MACV;AACA,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,sCAAsC,KAAK,QAAQ,QAAQ;AAAA,UAC3D;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC3CA,IAAM,mBAAmB;AAQlB,IAAM,cAAoB;AAAA,EAC/B,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,OAAO;AAC5B,YAAM,IAAI,SAAS,mDAAmD;AAAA,IACxE;AACA,QAAI;AACF,YAAM,SAAS,MAAM,IAAI,OAAO;AAAA,QAC9B,EAAE,QAAQ,cAAc,QAAQ,EAAE,MAAM,kBAAkB,WAAW,CAAC,EAAE,EAAE;AAAA,QAC1E;AAAA,MACF;AACA,UAAI,OAAO,YAAY,MAAM;AAC3B,eAAO,CAAC;AAAA,MACV;AACA,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAEN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;;;AClCO,IAAM,oBAA0B;AAAA,EACrC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,OAAO;AAC5B,YAAM,IAAI,SAAS,mDAAmD;AAAA,IACxE;AACA,UAAM,QAAQ,MAAM,gBAAgB,GAAG;AACvC,UAAM,SAAS,uBAAuB,KAAK;AAC3C,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,SAAS,gDAAgD;AAAA,IACrE;AACA,QAAI;AACF,YAAM,SAAS,MAAM,IAAI,OAAO;AAAA,QAC9B,EAAE,QAAQ,cAAc,QAAQ,EAAE,MAAM,QAAQ,WAAW,CAAC,EAAE,EAAE;AAAA,QAChE;AAAA,MACF;AACA,UAAI,OAAO,YAAY,MAAM;AAC3B,eAAO,CAAC;AAAA,MACV;AACA,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,SAAS,MAAM;AAAA,UACf;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAEN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;;;AC3CA,IAAM,kBAAkB;AAOjB,IAAM,kBAAwB;AAAA,EACnC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,WAAW;AAChC,YAAM,IAAI,SAAS,uDAAuD;AAAA,IAC5E;AACA,QAAI;AACF,YAAM,IAAI,OAAO;AAAA,QACf,EAAE,QAAQ,kBAAkB,QAAQ,EAAE,KAAK,gBAAgB,EAAE;AAAA,QAC7D;AAAA,MACF;AACA,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;;;AClCA,IAAMC,mBAAkB;AAUjB,IAAM,mBAAyB;AAAA,EACpC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,CAAC,IAAI,cAAc,WAAW;AAChC,YAAM,IAAI,SAAS,uDAAuD;AAAA,IAC5E;AACA,QAAI;AACF,YAAM,IAAI,OAAO;AAAA,QACf,EAAE,QAAQ,kBAAkB,QAAQ,EAAE,KAAKA,iBAAgB,EAAE;AAAA,QAC7D;AAAA,MACF;AAGA,YAAM,IAAI,SAAS,gEAAgE;AAAA,IACrF,SAAS,KAAK;AACZ,UAAI,eAAe,UAAU;AAC3B,cAAM;AAAA,MACR;AACA,YAAM,OAAO,cAAc,GAAG;AAC9B,YAAM,WAAqB,CAAC;AAC5B,UAAI,OAAO,KAAK,SAAS,UAAU;AACjC,iBAAS,KAAK,wBAAwB;AAAA,MACxC;AACA,UAAI,KAAK,YAAY,UAAa,KAAK,QAAQ,WAAW,GAAG;AAC3D,iBAAS,KAAK,4BAA4B;AAAA,MAC5C;AACA,UAAI,SAAS,SAAS,GAAG;AACvB,eAAO;AAAA,UACL;AAAA,YACE;AAAA,YACA,uCAAuC,SAAS,KAAK,IAAI,CAAC;AAAA,YAC1D;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;;;ACtDA,IAAM,gBAAgB;AASf,IAAM,qBAA2B;AAAA,EACtC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM,IAAI,KAAK;AACb,QAAI,IAAI,UAAU,SAAS,QAAQ;AACjC,YAAM,IAAI,SAAS,yBAAyB;AAAA,IAC9C;AACA,UAAM,YAAY,IAAI,UAAU;AAChC,QAAI,cAAc,QAAW;AAC3B,YAAM,IAAI,SAAS,yDAAyD;AAAA,IAC9E;AACA,QAAI,CAAC,cAAc,KAAK,SAAS,GAAG;AAClC,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE,UAAU;AAAA,QACd;AAAA,MACF;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AACF;;;ACIO,IAAM,kBAAmC;AAAA;AAAA,EAE9C;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AACF;;;ACxDA,IAAM,YAA6B,CAAC,GAAG,eAAe;AAG/C,SAAS,oBAAoB,SAA8B;AAChE,SAAO,UAAU,OAAO,CAAC,SAAS,KAAK,gBAAgB,OAAO;AAChE;AAGO,SAAS,WAA4B;AAC1C,SAAO;AACT;;;AClBA,SAAS,cAAc;AACvB,SAAS,qCAAqC;;;ACGvC,IAAM,QAAQ;AAAA;AAAA,EAEnB,MAAM;AAAA;AAAA,EAEN,KAAK;AACP;;;ADMA,eAAsB,YAAY,QAAoD;AACpF,MAAI;AACJ,MAAI;AACF,UAAM,IAAI,IAAI,OAAO,GAAG;AAAA,EAC1B,SAAS,KAAK;AACZ,UAAM,IAAI,MAAM,4BAA4B,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,CAAC;AAAA,EAC1E;AAEA,QAAM,YAAY,IAAI,8BAA8B,KAAK;AAAA,IACvD,aAAa,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI;AAAA,EAC9D,CAAC;AAED,QAAM,SAAS,IAAI;AAAA,IACjB,EAAE,MAAM,GAAG,MAAM,IAAI,UAAU,SAAS,QAAQ;AAAA,IAChD,EAAE,cAAc,CAAC,EAAE;AAAA,EACrB;AAEA,MAAI;AACF,UAAM,OAAO,QAAQ,SAAS;AAAA,EAChC,SAAS,KAAK;AACZ,UAAM,UAAU,MAAM,EAAE,MAAM,MAAM,MAAS;AAC7C,UAAM,IAAI;AAAA,MACR,iEAAiE,OAAO,GAAG;AAAA,MAE3E,EAAE,OAAO,IAAI;AAAA,IACf;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,WAAW,EAAE,MAAM,QAAQ,WAAW,UAAU,UAAU;AAAA,IAC1D,OAAO,YAAY;AACjB,YAAM,OAAO,MAAM;AAAA,IACrB;AAAA,EACF;AACF;;;AElDA,SAAS,UAAAC,eAAc;AACvB,SAAS,4BAA4B;AAYrC,eAAsB,aAAa,QAAqD;AACtF,QAAM,YAAY,IAAI,qBAAqB;AAAA,IACzC,SAAS,OAAO;AAAA,IAChB,MAAM,OAAO;AAAA,IACb,KAAK,OAAO;AAAA;AAAA,IAEZ,KAAK,OAAO;AAAA,IACZ,QAAQ;AAAA,EACV,CAAC;AAED,QAAM,SAAS,IAAIC;AAAA,IACjB,EAAE,MAAM,GAAG,MAAM,IAAI,UAAU,SAAS,QAAQ;AAAA,IAChD,EAAE,cAAc,CAAC,EAAE;AAAA,EACrB;AAEA,MAAI;AACF,UAAM,OAAO,QAAQ,SAAS;AAAA,EAChC,SAAS,KAAK;AACZ,UAAM,UAAU,MAAM,EAAE,MAAM,MAAM,MAAS;AAC7C,UAAM,IAAI;AAAA,MACR,2DAA2D,OAAO,OAAO;AAAA,MAEzE,EAAE,OAAO,IAAI;AAAA,IACf;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,WAAW,EAAE,MAAM,QAAQ;AAAA,IAC3B,OAAO,YAAY;AACjB,YAAM,OAAO,MAAM;AAAA,IACrB;AAAA,EACF;AACF;;;AC/BO,SAAS,cAAc,QAAiD;AAC7E,SAAO,OAAO,cAAc,UAAU,aAAa,OAAO,KAAK,IAAI,YAAY,OAAO,IAAI;AAC5F;;;ACEA,SAAS,eAAe,QAAkC;AACxD,MAAI,OAAO,cAAc,QAAQ;AAC/B,WAAO,EAAE,WAAW,QAAQ,aAAa,SAAS,OAAO,KAAK,GAAG,GAAG;AAAA,EACtE;AACA,QAAM,EAAE,SAAS,KAAK,IAAI,OAAO;AACjC,SAAO,EAAE,WAAW,SAAS,aAAa,UAAU,OAAO,KAAK,QAAQ,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,EAAE;AACjG;AAEA,IAAM,gBAA0C,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,EAAE;AAQhF,eAAsB,SAAS,MAA2C;AACxE,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,QAAM,SAAmB,KAAK,UAAU;AACxC,QAAM,QAAQ,oBAAoB,KAAK,WAAW;AAClD,QAAM,SAAS,eAAe,KAAK,MAAM;AAEzC,QAAM,OAAO,MAAM,cAAc,KAAK,MAAM;AAC5C,MAAI;AACJ,MAAI;AACF,UAAM,MAAmB;AAAA,MACvB,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK,OAAO,iBAAiB;AAAA,MACzC,cAAc,KAAK,OAAO,sBAAsB;AAAA,MAChD,WAAW,KAAK;AAAA,MAChB,aAAa,KAAK;AAAA,IACpB;AACA,cAAU,MAAM,SAAS,KAAK,KAAK;AACnC,QAAI,KAAK,aAAa;AACpB,cAAQ,KAAK,GAAI,MAAM,KAAK,YAAY,GAAG,CAAE;AAAA,IAC/C;AAAA,EACF,UAAE;AACA,UAAM,KAAK,MAAM,EAAE,MAAM,MAAM,MAAS;AAAA,EAC1C;AAEA,QAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAC1C,SAAO;AAAA,IACL,aAAa,KAAK;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,iBAAiB,OAAO;AAAA,IACjC,UAAU,gBAAgB,SAAS,MAAM;AAAA,EAC3C;AACF;AAOA,eAAsB,SAAS,KAAkB,OAA+C;AAC9F,QAAM,UAAwB,CAAC;AAC/B,aAAW,QAAQ,OAAO;AACxB,YAAQ,KAAK,MAAM,WAAW,MAAM,GAAG,CAAC;AAAA,EAC1C;AACA,SAAO;AACT;AAEA,eAAe,WAAW,MAAY,KAAuC;AAC3E,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,OAAO;AAAA,IACX,QAAQ,KAAK;AAAA,IACb,OAAO,KAAK;AAAA,IACZ,UAAU,KAAK;AAAA,IACf,UAAU,KAAK;AAAA,IACf,aAAa,KAAK;AAAA,IAClB,SAAS,KAAK;AAAA,EAChB;AAEA,MAAI;AACF,UAAM,WAAW,MAAM,KAAK,IAAI,GAAG;AACnC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ,mBAAmB,QAAQ;AAAA,MACnC;AAAA,MACA,YAAY,KAAK,IAAI,IAAI;AAAA,IAC3B;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,eAAe,UAAU;AAC3B,aAAO;AAAA,QACL,GAAG;AAAA,QACH,QAAQ;AAAA,QACR,YAAY,IAAI;AAAA,QAChB,UAAU,CAAC;AAAA,QACX,YAAY,KAAK,IAAI,IAAI;AAAA,MAC3B;AAAA,IACF;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,UAAU;AAAA,QACR;AAAA,UACE,QAAQ,KAAK;AAAA,UACb,UAAU,KAAK;AAAA,UACf,SAAS,mCAAmC,kBAAkB,GAAG,CAAC;AAAA,UAClE,aACE;AAAA,UAEF,SAAS,KAAK;AAAA,UACd,QAAQ,eAAe,QAAQ,EAAE,OAAO,IAAI,MAAM,IAAI;AAAA,QACxD;AAAA,MACF;AAAA,MACA,YAAY,KAAK,IAAI,IAAI;AAAA,IAC3B;AAAA,EACF;AACF;AAGA,SAAS,mBAAmB,UAA8D;AACxF,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AACA,SAAO,SAAS,KAAK,CAAC,MAAM,EAAE,aAAa,OAAO,IAAI,SAAS;AACjE;AAEO,SAAS,iBAAiB,SAAmC;AAClE,QAAM,UAAsB;AAAA,IAC1B,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,QAAQ;AAAA,EACjB;AACA,aAAW,UAAU,SAAS;AAC5B,YAAQ,OAAO,MAAM,KAAK;AAAA,EAC5B;AACA,SAAO;AACT;AAMO,SAAS,gBAAgB,SAAuB,QAAyB;AAC9E,QAAM,YAAY,cAAc,MAAM;AACtC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,WAAW,SAAS;AAC7B,aAAO;AAAA,IACT;AACA,eAAWC,YAAW,OAAO,UAAU;AACrC,UAAI,cAAcA,SAAQ,QAAQ,KAAK,WAAW;AAChD,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;AC7KA,SAAS,KAAAC,UAAS;AAQX,IAAM,wBAAwB;AAGrC,IAAM,aAAaA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC;AAE5C,IAAM,uBAAuBA,GAAE,OAAO;AAAA,EAC3C,eAAeA,GAAE,QAAQ,qBAAqB;AAAA,EAC9C,aAAaA,GAAE,OAAO;AAAA,EACtB,QAAQA,GAAE,OAAO,EAAE,MAAMA,GAAE,OAAO,GAAG,SAASA,GAAE,OAAO,EAAE,CAAC;AAAA,EAC1D,OAAOA,GAAE,MAAM,UAAU;AAAA,EACzB,WAAWA,GAAE,MAAM,UAAU;AAAA,EAC7B,SAASA,GAAE,MAAM,UAAU;AAC7B,CAAC;AAGM,IAAM,mBAAmBA,GAAE,OAAO;AAAA,EACvC,MAAMA,GAAE,OAAO;AAAA,EACf,WAAWA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC;AAAA;AAAA,EAE3C,aAAaA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,EAC/B,QAAQA,GAAE,QAAQ;AACpB,CAAC;AAGM,IAAM,wBAAwBA,GAAE,OAAO;AAAA,EAC5C,eAAeA,GAAE,QAAQ,qBAAqB;AAAA,EAC9C,MAAMA,GAAE,OAAO;AAAA,EACf,OAAOA,GAAE,MAAM,gBAAgB;AACjC,CAAC;AAWM,IAAM,kBAAkBA,GAAE,OAAO;AAAA,EACtC,MAAMA,GAAE,OAAO;AAAA,EACf,QAAQA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,OAAOA,GAAE,QAAQ,EAAE,SAAS;AAC9B,CAAC;AAKM,IAAM,yBAAyBA,GAAE,OAAO;AAAA,EAC7C,MAAMA,GAAE,KAAK,CAAC,UAAU,cAAc,UAAU,CAAC;AAAA,EACjD,QAAQA,GAAE,OAAO;AAAA,IACf,MAAMA,GAAE,KAAK,CAAC,QAAQ,YAAY,QAAQ,CAAC;AAAA,IAC3C,MAAMA,GAAE,OAAO;AAAA,IACf,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,CAAC;AAAA,EACD,QAAQA,GAAE,KAAK,CAAC,SAAS,WAAW,SAAS,CAAC;AAAA,EAC9C,QAAQA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,OAAOA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC5B,YAAYA,GAAE,MAAM,eAAe,EAAE,SAAS;AAAA;AAAA,EAE9C,sBAAsBA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AACrD,CAAC;;;AC/CD,IAAM,kBAAiD;AAAA,EACrD,iBAAiB;AAAA,IACf,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,UAAU,EAAE,OAAO,yBAAyB,aAAa,QAAQ;AAAA,EACjE,YAAY,EAAE,OAAO,yBAAyB,aAAa,SAAS;AACtE;AAGA,IAAM,gBAA8D;AAAA,EAClE,gBAAgB,EAAE,KAAK,MAAmB,KAAK,KAAkB;AAAA,EACjE,iBAAiB,EAAE,KAAK,KAAe,KAAK,IAAc;AAC5D;AAEO,IAAM,2BAA8C;AAAA,EACzD,GAAG,OAAO,KAAK,eAAe;AAAA,EAC9B,GAAG,OAAO,KAAK,aAAa;AAC9B;AAEA,SAAS,QAAQ,MAA4B;AAC3C,QAAM,gBAAgB,gBAAgB,IAAI;AAC1C,MAAI,eAAe;AACjB,WAAO,CAAC,UACN;AAAA,MAAW;AAAA,MAAO,CAAC,WACjB,OAAO,WAAW,WACd,OAAO,QAAQ,cAAc,OAAO,cAAc,WAAW,IAC7D;AAAA,IACN;AAAA,EACJ;AACA,QAAM,QAAQ,cAAc,IAAI;AAChC,MAAI,OAAO;AACT,WAAO,CAAC,UACN;AAAA,MAAW;AAAA,MAAO,CAAC,WACjB,OAAO,WAAW,YAClB,OAAO,UAAU,MAAM,KACvB,UAAU,MAAM,OAChB,SAAS,MAAM,MACX,YACA;AAAA,IACN;AAAA,EACJ;AACA,QAAM,IAAI;AAAA,IACR,uBAAuB,IAAI,0BAA0B,yBAAyB,KAAK,IAAI,CAAC;AAAA,EAC1F;AACF;AAGA,SAAS,WAAW,OAAgB,IAA2C;AAC7E,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAAS,WAAW,MAAM,EAAE,CAAC;AAAA,EACjD;AACA,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,UAAM,SAAS;AACf,UAAM,MAA+B,CAAC;AACtC,eAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AACrC,UAAI,GAAG,IAAI,WAAW,OAAO,GAAG,GAAG,EAAE;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AACA,SAAO,GAAG,KAAK;AACjB;AAEA,SAAS,QAAQ,KAAkC;AACjD,SAAO,OAAO,QAAQ,WAAW,QAAQ,GAAG,IAAI,IAAI;AACtD;AAEO,SAAS,eAAe,KAA4B;AACzD,SAAO,OAAO,QAAQ,WAAW,MAAM,IAAI;AAC7C;AAGO,SAAS,iBAAiB,OAAgB,MAAyC;AACxF,SAAO,KAAK,OAAgB,CAAC,KAAK,QAAQ,QAAQ,GAAG,EAAE,GAAG,GAAG,KAAK;AACpE;AAQO,SAAS,kBAAkB,QAAiB,OAA0B;AAC3E,QAAM,cAAwB,CAAC;AAC/B,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC7D,QACE,OAAO,WAAW,YAClB,OAAO,UAAU,YACjB,eAAe,QAAQ,QAAQ,KAAK,KACpC,eAAe,OAAO,QAAQ,KAAK,GACnC;AACA,kBAAY,KAAK,IAAI;AAAA,IACvB;AAAA,EACF;AACA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACzD,QAAI,QAAQ,QAAQ,KAAK,KAAK,QAAQ,OAAO,KAAK,GAAG;AACnD,kBAAY,KAAK,IAAI;AAAA,IACvB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,eAAe,OAAe,OAAwB;AAE7D,SAAO,IAAI,OAAO,MAAM,MAAM,EAAE,KAAK,KAAK;AAC5C;AAEA,SAAS,QAAQ,OAAgB,OAA8C;AAC7E,SACE,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK,KAAK,SAAS,MAAM,OAAO,QAAQ,MAAM;AAEhG;;;AClHA,eAAsB,cAAc,QAAgB,KAAuC;AACzF,QAAM,WAAW,MAAM,iBAAiB,QAAQ,IAAI,WAAW;AAE/D,QAAM,aAAgC,CAAC;AACvC,aAAW,QAAQ,OAAO,KAAK,IAAI,KAAK,EAAE,KAAK,GAAG;AAChD,UAAM,WAAW,IAAI,MAAM,IAAI;AAC/B,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AACA,UAAM,OAAwB,SAAS,eAAe,IAAI;AAC1D,UAAM,QAAQ,CAAC;AACf,eAAW,QAAQ,CAAC,GAAG,SAAS,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG;AAC9E,YAAM,MAAM,MAAM,OAAO;AAAA,QACvB,EAAE,QAAQ,cAAc,QAAQ,EAAE,MAAM,MAAM,WAAW,KAAK,UAAU,EAAE;AAAA,QAC1E;AAAA,MACF;AACA,YAAM,KAAK;AAAA,QACT,MAAM,KAAK;AAAA,QACX,WAAW,KAAK;AAAA,QAChB,aAAa,KAAK,IAAI,cAAc;AAAA,QACpC,QAAQ,iBAAiB,KAAK,IAAI;AAAA,MACpC,CAAC;AAAA,IACH;AACA,eAAW,KAAK,EAAE,eAAe,uBAAuB,MAAM,MAAM,CAAC;AAAA,EACvE;AAEA,SAAO,EAAE,UAAU,WAAW;AAChC;AAEA,eAAe,iBAAiB,QAAgB,aAA8C;AAC5F,QAAM,OAAO,OAAO,sBAAsB;AAC1C,QAAM,OAAO,OAAO,iBAAiB;AAErC,QAAM,QAAQ,MAAM,SACf,MAAM,OAAO,QAAQ,EAAE,QAAQ,cAAc,QAAQ,CAAC,EAAE,GAAG,eAAe,GAAG,QAC9E,CAAC;AACL,QAAM,YAAY,MAAM,aACnB,MAAM,OAAO,QAAQ,EAAE,QAAQ,kBAAkB,QAAQ,CAAC,EAAE,GAAG,mBAAmB,GAChF,YACH,CAAC;AACL,QAAM,UAAU,MAAM,WACjB,MAAM,OAAO,QAAQ,EAAE,QAAQ,gBAAgB,QAAQ,CAAC,EAAE,GAAG,iBAAiB,GAAG,UAClF,CAAC;AAEL,SAAO;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA,QAAQ,EAAE,MAAM,MAAM,QAAQ,IAAI,SAAS,MAAM,WAAW,GAAG;AAAA,IAC/D,OAAO,OAAO,OAAO,MAAM;AAAA,IAC3B,WAAW,OAAO,WAAW,KAAK;AAAA,IAClC,SAAS,OAAO,SAAS,MAAM;AAAA,EACjC;AACF;AAEA,SAAS,OACP,OACA,KAC2B;AAC3B,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,QAAQ,YAAY,GAAG,GAAG,KAAK,IAAI,YAAY,GAAG,GAAG,KAAK,EAAE,CAAC;AAChG;AAEA,SAAS,QAAQ,GAAW,GAAmB;AAC7C,SAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAClC;;;ACtEA,IAAM,cAAc;AACpB,IAAM,SAAS;AAEf,SAAS,cAAc,OAAkD;AACvE,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGA,SAAS,aAAa,OAAyB;AAC7C,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAAS,aAAa,SAAS,SAAY,OAAO,IAAI,CAAC;AAAA,EAC3E;AACA,MAAI,cAAc,KAAK,GAAG;AACxB,UAAM,MAA+B,CAAC;AACtC,eAAW,OAAO,OAAO,KAAK,KAAK,EAAE,KAAK,GAAG;AAC3C,YAAM,QAAQ,MAAM,GAAG;AACvB,UAAI,UAAU,UAAa,OAAO,UAAU,YAAY;AACtD,YAAI,GAAG,IAAI,aAAa,KAAK;AAAA,MAC/B;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO,OAAO,UAAU,aAAa,OAAO;AAC9C;AAGA,SAAS,KAAK,OAAwB;AACpC,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,WAAW,IAAI,OAAO,IAAI,MAAM,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,EACnE;AACA,MAAI,cAAc,KAAK,GAAG;AACxB,UAAM,OAAO,OAAO,KAAK,KAAK;AAC9B,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO;AAAA,IACT;AACA,WAAO,KAAK,KAAK,IAAI,CAAC,MAAM,GAAG,KAAK,UAAU,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,EACnF;AACA,SAAO,KAAK,UAAU,KAAK;AAC7B;AAOA,SAAS,MAAM,OAAgB,OAAe,QAAgB,SAAyB;AACrF,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,CAAC,cAAc,KAAK,GAAG;AAClD,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AAEA,QAAM,WAAW,KAAK,KAAK;AAC3B,QAAM,YAAY,MAAM,QAAQ,KAAK,KAAK,YAAY,KAAK;AAC3D,MAAI,CAAC,aAAa,SAAS,SAAS,SAAS,WAAW,aAAa;AACnE,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,OAAO,OAAO,QAAQ,CAAC;AAC3C,QAAM,cAAc,OAAO,OAAO,KAAK;AAEvC,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,QAAI,MAAM,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ,GAAG;AACnD,aAAO,YAAY,OAAO,KAAK;AAAA,IACjC;AACA,UAAM,QAAQ,MAAM;AAAA,MAAI,CAAC,MAAM,MAC7B,MAAM,MAAM,QAAQ,GAAG,YAAY,QAAQ,IAAI,MAAM,SAAS,IAAI,IAAI,CAAC;AAAA,IACzE;AACA,WAAO;AAAA,EAAM,MAAM,IAAI,CAAC,MAAM,cAAc,CAAC,EAAE,KAAK,KAAK,CAAC;AAAA,EAAK,WAAW;AAAA,EAC5E;AAEA,QAAM,OAAO,OAAO,KAAK,KAAK;AAC9B,QAAM,QAAQ,KAAK,IAAI,CAAC,KAAK,MAAM;AACjC,UAAM,SAAS,GAAG,KAAK,UAAU,GAAG,CAAC;AACrC,UAAM,WAAW;AAAA,MACf,MAAM,GAAG;AAAA,MACT,QAAQ;AAAA,MACR,YAAY,SAAS,OAAO;AAAA,MAC5B,IAAI,KAAK,SAAS,IAAI,IAAI;AAAA,IAC5B;AACA,WAAO,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ;AAAA,EAC3C,CAAC;AACD,SAAO;AAAA,EAAM,MAAM,KAAK,KAAK,CAAC;AAAA,EAAK,WAAW;AAChD;AAOA,SAAS,YAAY,OAAoC;AACvD,SACE,MAAM,SAAS,KACf,MAAM;AAAA,IACJ,CAAC,OACE,MAAM,QAAQ,EAAE,KAAK,GAAG,SAAS,KAAO,cAAc,EAAE,KAAK,OAAO,KAAK,EAAE,EAAE,SAAS;AAAA,EAC3F;AAEJ;AAGA,SAAS,YAAY,OAA0B,OAAuB;AACpE,QAAM,cAAc,OAAO,OAAO,QAAQ,CAAC;AAC3C,QAAM,QAAkB,CAAC;AACzB,MAAI,UAAU;AACd,QAAM,QAAQ,CAAC,KAAK,MAAM;AACxB,UAAM,QAAQ,IAAI,MAAM,SAAS,IAAI,GAAG,KAAK,UAAU,GAAG,CAAC,MAAM,KAAK,UAAU,GAAG;AACnF,QAAI,YAAY,IAAI;AAClB,gBAAU;AAAA,IACZ,WAAW,YAAY,SAAS,QAAQ,SAAS,IAAI,MAAM,UAAU,aAAa;AAChF,gBAAU,GAAG,OAAO,IAAI,KAAK;AAAA,IAC/B,OAAO;AACL,YAAM,KAAK,OAAO;AAClB,gBAAU;AAAA,IACZ;AAAA,EACF,CAAC;AACD,MAAI,YAAY,IAAI;AAClB,UAAM,KAAK,OAAO;AAAA,EACpB;AACA,SAAO;AAAA,EAAM,MAAM,IAAI,CAAC,MAAM,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,EAAK,OAAO,OAAO,KAAK,CAAC;AACpF;AAGO,SAAS,gBAAgB,OAAwB;AACtD,SAAO,GAAG,MAAM,aAAa,KAAK,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA;AAC/C;AAGO,SAAS,UAAU,GAAY,GAAqB;AACzD,SAAO,gBAAgB,CAAC,MAAM,gBAAgB,CAAC;AACjD;;;ACvIO,SAAS,UAAU,QAAiB,OAAgB,OAAO,IAAiB;AACjF,MAAI,UAAU,QAAQ,KAAK,GAAG;AAC5B,WAAO,CAAC;AAAA,EACV;AAEA,MAAI,SAAS,MAAM,KAAK,SAAS,KAAK,GAAG;AACvC,UAAM,OAAO,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK;AAChF,WAAO,KAAK,QAAQ,CAAC,QAAQ,UAAU,OAAO,GAAG,GAAG,MAAM,GAAG,GAAG,KAAK,MAAM,GAAG,CAAC,CAAC;AAAA,EAClF;AAEA,MAAI,MAAM,QAAQ,MAAM,KAAK,MAAM,QAAQ,KAAK,KAAK,OAAO,WAAW,MAAM,QAAQ;AACnF,WAAO,OAAO,QAAQ,CAAC,MAAM,MAAM,UAAU,MAAM,MAAM,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;AAAA,EAC/E;AAEA,SAAO,CAAC,EAAE,MAAM,QAAQ,UAAU,QAAQ,MAAM,CAAC;AACnD;AAEA,SAAS,KAAK,MAAc,KAAqB;AAC/C,SAAO,OAAO,GAAG,IAAI,IAAI,GAAG,KAAK;AACnC;;;ACbA,IAAM,WAAW;AAiBjB,eAAsB,cACpB,QACA,QACA,KACuB;AACvB,QAAM,cAAc,IAAI;AACxB,QAAM,OAAO,MAAM,aAAa,MAAM;AACtC,QAAM,UAAwB,CAAC;AAE/B,UAAQ,KAAK,GAAG,cAAc,aAAa,QAAQ,QAAQ,OAAO,SAAS,OAAO,KAAK,KAAK,CAAC;AAC7F,UAAQ;AAAA,IACN,GAAG,cAAc,aAAa,YAAY,OAAO,OAAO,SAAS,WAAW,KAAK,SAAS;AAAA,EAC5F;AACA,UAAQ;AAAA,IACN,GAAG,cAAc,aAAa,UAAU,QAAQ,OAAO,SAAS,SAAS,KAAK,OAAO;AAAA,EACvF;AAEA,QAAM,gBAAgB,IAAI;AAAA,IACxB,KAAK,MAAM,IAAI,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,OAAO,CAAC,MAAmB,CAAC,CAAC,CAAC;AAAA,EAC9E;AACA,aAAW,aAAa,OAAO,YAAY;AACzC,QAAI,CAAC,cAAc,IAAI,UAAU,IAAI,GAAG;AACtC;AAAA,IACF;AACA,UAAM,OAAO,IAAI,MAAM,UAAU,IAAI,GAAG,eAAe,IAAI;AAC3D,eAAW,YAAY,UAAU,OAAO;AACtC,cAAQ,KAAK,MAAM,gBAAgB,QAAQ,aAAa,UAAU,MAAM,UAAU,IAAI,CAAC;AAAA,IACzF;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,cACP,aACA,MACA,UACA,YACA,UACc;AACd,QAAM,UAAwB,CAAC;AAC/B,QAAM,YAAY,oBAAI,IAAqC;AAC3D,aAAW,OAAO,UAAU;AAC1B,UAAM,MAAM,YAAY,KAAK,QAAQ;AACrC,QAAI,QAAQ,QAAW;AACrB,gBAAU,IAAI,KAAK,GAAG;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,aAAa,oBAAI,IAAY;AACnC,aAAW,OAAO,YAAY;AAC5B,UAAM,MAAM,YAAY,KAAK,QAAQ;AACrC,QAAI,QAAQ,QAAW;AACrB;AAAA,IACF;AACA,eAAW,IAAI,GAAG;AAClB,UAAM,UAAU,UAAU,IAAI,GAAG;AACjC,QAAI,CAAC,SAAS;AACZ,cAAQ;AAAA,QACN,MAAM,aAAa,YAAY,SAAS;AAAA,UACtC,QAAQ,EAAE,MAAM,YAAY,QAAQ,EAAE,MAAM,MAAM,IAAI,GAAG,QAAQ,WAAW,QAAQ,IAAI;AAAA,UACxF,SAAS,GAAG,IAAI,KAAK,GAAG;AAAA,UACxB,aACE;AAAA,QACJ,CAAC;AAAA,MACH;AAAA,IACF,WAAW,CAAC,UAAU,KAAK,OAAO,GAAG;AACnC,cAAQ;AAAA,QACN,MAAM,aAAa,UAAU,SAAS;AAAA,UACpC,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,QAAQ,EAAE,MAAM,MAAM,IAAI;AAAA,YAC1B,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,OAAO;AAAA,YACP,YAAY,UAAU,KAAK,OAAO;AAAA,UACpC;AAAA,UACA,SAAS,GAAG,IAAI,KAAK,GAAG;AAAA,UACxB,aAAa;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,aAAW,OAAO,UAAU;AAC1B,UAAM,MAAM,YAAY,KAAK,QAAQ;AACrC,QAAI,QAAQ,UAAa,WAAW,IAAI,GAAG,GAAG;AAC5C;AAAA,IACF;AACA,YAAQ;AAAA,MACN,MAAM,aAAa,YAAY,WAAW;AAAA,QACxC,QAAQ,EAAE,MAAM,YAAY,QAAQ,EAAE,MAAM,MAAM,IAAI,GAAG,QAAQ,SAAS,OAAO,IAAI;AAAA,QACrF,SAAS,GAAG,IAAI,KAAK,GAAG;AAAA,QACxB,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,gBACb,QACA,aACA,MACA,UACA,MACqB;AACrB,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,OAAO;AAAA,MACvB,EAAE,QAAQ,cAAc,QAAQ,EAAE,MAAM,MAAM,WAAW,SAAS,UAAU,EAAE;AAAA,MAC9E;AAAA,IACF;AACA,qBAAiB,iBAAiB,KAAK,IAAI;AAAA,EAC7C,SAAS,KAAK;AACZ,qBAAiB,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,EAC7E;AAEA,QAAM,aAAa,UAAU,SAAS,QAAQ,cAAc;AAC5D,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,WAAW,aAAa,MAAM,SAAS,IAAI;AAAA,EACpD;AAEA,QAAM,YAAY,CAAC,GAAG,IAAI,IAAI,WAAW,QAAQ,CAAC,MAAM,kBAAkB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;AAC9F,QAAM,cACJ,UAAU,SAAS,IACf,2BAA2B,UAAU,KAAK,IAAI,CAAC,iCAAiC,IAAI,2CACpF;AAEN,SAAO,MAAM,aAAa,cAAc,SAAS;AAAA,IAC/C,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,QAAQ,MAAM,MAAM,MAAM,SAAS,KAAK;AAAA,MACxD,QAAQ;AAAA,MACR,QAAQ,SAAS;AAAA,MACjB,OAAO;AAAA,MACP;AAAA,MACA,sBAAsB,UAAU,SAAS,IAAI,YAAY;AAAA,IAC3D;AAAA,IACA,SAAS,SAAS,IAAI,YAAY,SAAS,IAAI;AAAA,IAC/C;AAAA,EACF,CAAC;AACH;AAQA,SAAS,MACP,aACA,MACA,UACA,MACY;AACZ,QAAM,EAAE,OAAO,IAAI,KAAK;AACxB,QAAM,SAAS,OAAO,OAAO,GAAG,OAAO,IAAI,IAAI,OAAO,IAAI,KAAK,OAAO;AACtE,QAAM,SAAS,cAAc,IAAI,UAAU,OAAO,IAAI,IAAI,MAAM;AAChE,QAAMC,WAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA,SAAS,KAAK;AAAA,IACd,aAAa,KAAK;AAAA,IAClB,SAAS;AAAA,IACT,QAAQ,KAAK;AAAA,EACf;AACA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,GAAG,IAAI,iBAAY,OAAO,IAAI,IAAI,OAAO,IAAI;AAAA,IACpD,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,QAAQ,aAAa,UAAU,SAAS;AAAA,IACxC,UAAU,CAACA,QAAO;AAAA,IAClB,YAAY;AAAA,EACd;AACF;AAEA,SAAS,WAAW,aAA0B,MAAc,UAA8B;AACxF,SAAO;AAAA,IACL,QAAQ,yBAAyB,IAAI,IAAI,QAAQ;AAAA,IACjD,OAAO,0BAAqB,IAAI,UAAU,QAAQ;AAAA,IAClD,UAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,IACA,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,UAAU,CAAC;AAAA,IACX,YAAY;AAAA,EACd;AACF;AAEA,eAAe,aAAa,QAAuC;AACjE,QAAM,OAAO,OAAO,sBAAsB;AAC1C,QAAM,QAAQ,MAAM,SACf,MAAM,OAAO,QAAQ,EAAE,QAAQ,cAAc,QAAQ,CAAC,EAAE,GAAG,eAAe,GAAG,QAC9E,CAAC;AACL,QAAM,YAAY,MAAM,aACnB,MAAM,OAAO,QAAQ,EAAE,QAAQ,kBAAkB,QAAQ,CAAC,EAAE,GAAG,mBAAmB,GAChF,YACH,CAAC;AACL,QAAM,UAAU,MAAM,WACjB,MAAM,OAAO,QAAQ,EAAE,QAAQ,gBAAgB,QAAQ,CAAC,EAAE,GAAG,iBAAiB,GAAG,UAClF,CAAC;AACL,SAAO,EAAE,OAAO,WAAW,QAAQ;AACrC;;;ACjPA,SAAS,OAAO,SAAS,UAAU,iBAAiB;AACpD,SAAS,QAAAC,aAAY;AACrB,OAAkB;AAYX,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC,YAAY,SAAiB,OAAiB;AAC5C,UAAM,SAAS,UAAU,SAAY,EAAE,MAAM,IAAI,MAAS;AAC1D,SAAK,OAAO;AAAA,EACd;AACF;AAGA,eAAsB,eAAe,KAAa,KAAmC;AACnF,QAAM,MAAMC,MAAK,KAAK,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD,QAAM,UAAoB,CAAC;AAE3B,QAAM,eAAeA,MAAK,KAAK,eAAe;AAC9C,QAAM,UAAU,cAAc,gBAAgB,IAAI,QAAQ,CAAC;AAC3D,UAAQ,KAAK,YAAY;AAEzB,aAAW,aAAa,CAAC,GAAG,IAAI,UAAU,EAAE,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE,GAAG;AACtF,UAAM,OAAOA,MAAK,KAAK,cAAc,GAAG,UAAU,IAAI,OAAO;AAC7D,UAAM,UAAU,MAAM,gBAAgB,SAAS,CAAC;AAChD,YAAQ,KAAK,IAAI;AAAA,EACnB;AACA,SAAO;AACT;AAGA,eAAsB,cAAc,KAAiC;AACnE,QAAM,eAAeA,MAAK,KAAK,eAAe;AAC9C,MAAI;AACJ,MAAI;AACF,kBAAc,MAAM,SAAS,cAAc,MAAM;AAAA,EACnD,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,yBAAyB,YAAY;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AACA,QAAM,WAAW,YAAY,sBAAsB,aAAa,YAAY;AAE5E,QAAM,aAAgC,CAAC;AACvC,QAAM,gBAAgBA,MAAK,KAAK,YAAY;AAC5C,MAAI,QAAkB,CAAC;AACvB,MAAI;AACF,aAAS,MAAM,QAAQ,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC,EAAE,KAAK;AAAA,EACjF,QAAQ;AACN,YAAQ,CAAC;AAAA,EACX;AACA,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAOA,MAAK,eAAe,IAAI;AACrC,eAAW,KAAK,YAAY,uBAAuB,MAAM,SAAS,MAAM,MAAM,GAAG,IAAI,CAAC;AAAA,EACxF;AAEA,SAAO,EAAE,UAAU,WAAW;AAChC;AAEA,SAAS,YAAe,QAAsB,KAAa,MAAiB;AAC1E,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,SAAS,KAAK;AACZ,UAAM,IAAI,YAAY,aAAa,IAAI,uBAAuB,GAAG;AAAA,EACnE;AAEA,QAAM,SAAS,OAAO,UAAU,IAAI;AACpC,MAAI,OAAO,SAAS;AAClB,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,UAAU,SAAS,IAAI,IAAI,KAAK,eAAe,IAAI;AACzD,MAAI,YAAY,UAAa,YAAY,uBAAuB;AAC9D,UAAM,IAAI;AAAA,MACR,aAAa,IAAI,sBAAsB,OAAO,OAAO,CAAC,4BACjD,qBAAqB;AAAA,IAC5B;AAAA,EACF;AACA,QAAM,SAAS,OAAO,MAAM,OACzB,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,KAAK,GAAG,KAAK,QAAQ,KAAK,EAAE,OAAO,EAAE,EAC9D,KAAK,IAAI;AACZ,QAAM,IAAI,YAAY,aAAa,IAAI;AAAA,EAAmB,MAAM,EAAE;AACpE;","names":["z","z","NONEXISTENT_URI","Client","Client","finding","z","finding","join","join"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vexyo/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Conformance, regression, and diffing engine for testing Model Context Protocol (MCP) servers.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcp",
|
|
7
|
+
"model-context-protocol",
|
|
8
|
+
"testing",
|
|
9
|
+
"conformance",
|
|
10
|
+
"regression",
|
|
11
|
+
"ci",
|
|
12
|
+
"json-rpc"
|
|
13
|
+
],
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/vexyohq/vexyo.git",
|
|
18
|
+
"directory": "packages/core"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/vexyohq/vexyo#readme",
|
|
21
|
+
"private": false,
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
33
|
+
"zod": "^4.0.0"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist"
|
|
37
|
+
],
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup"
|
|
43
|
+
}
|
|
44
|
+
}
|