@vostride/agent-qa-plugin-kit 0.0.1 → 0.3.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","names":[],"sources":["../src/protocol/messages.ts","../src/protocol/manifest.ts","../src/emit.ts","../src/package-root.ts","../src/protocol/environment.ts","../src/protocol/framing.ts","../src/testing/conformance.ts","../src/testing/loopback-fake.ts","../src/testing/scripted-plugin.ts"],"sourcesContent":["import { z } from 'zod'\n\nexport const PLUGIN_PROTOCOL_VERSION = 1\n\nexport const PLUGIN_METHODS = [\n 'initialize',\n 'check',\n 'acquire',\n 'uploadApp',\n 'started',\n 'end',\n 'release',\n 'shutdown',\n] as const\nexport type PluginMethod = (typeof PLUGIN_METHODS)[number]\n\nexport const OPTIONAL_PLUGIN_METHODS = ['check', 'uploadApp', 'started', 'end'] as const\nexport type OptionalPluginMethod = (typeof OPTIONAL_PLUGIN_METHODS)[number]\n\nexport const PLUGIN_SERVES = ['playwright', 'cdp', 'appium'] as const\nexport type PluginServe = (typeof PLUGIN_SERVES)[number]\n\nexport const PLUGIN_RUN_FACTS = ['testName', 'runId', 'failure'] as const\nexport type PluginRunFact = (typeof PLUGIN_RUN_FACTS)[number]\n\nexport const PLUGIN_FAILURE_KINDS = [\n 'unreachable',\n 'auth',\n 'capacity',\n 'timeout',\n 'version',\n 'refused',\n 'ended',\n 'lost',\n] as const\nexport type PluginFailureKind = (typeof PLUGIN_FAILURE_KINDS)[number]\n\nexport const PLUGIN_ERROR_CODES = {\n parse: -32700,\n invalidRequest: -32600,\n methodNotFound: -32601,\n invalidParams: -32602,\n plugin: -32000,\n cancelled: -32800,\n} as const\n\nexport const CANCEL_METHOD = '$/cancel'\nexport const PROGRESS_METHOD = '$/progress'\n\nexport const MAX_MESSAGE_BYTES = 1024 * 1024\n\nconst JsonObjectSchema = z.record(z.string(), z.unknown())\nconst HandleSchema = z.json()\nconst RequestIdSchema = z.union([z.string(), z.number()])\n\nexport const InitializeParamsSchema = z.object({\n protocolVersions: z.array(z.number().int()),\n host: z.object({\n pid: z.number().int(),\n agentQaVersion: z.string(),\n playwrightVersion: z.string(),\n webdriverioVersion: z.string(),\n }),\n entry: z.string(),\n options: JsonObjectSchema,\n runFacts: z.object({ runId: z.string().optional() }).optional(),\n})\nexport type InitializeParams = z.infer<typeof InitializeParamsSchema>\n\nexport const InitializeResultSchema = z.object({\n protocolVersion: z.number().int(),\n plugin: z.object({ name: z.string(), version: z.string() }),\n serves: z.array(z.enum(PLUGIN_SERVES)),\n methods: z.array(z.enum(OPTIONAL_PLUGIN_METHODS)),\n})\nexport type InitializeResult = z.infer<typeof InitializeResultSchema>\n\nexport const CheckParamsSchema = z.object({\n remotes: z.array(z.object({ name: z.string(), settings: JsonObjectSchema })),\n})\nexport type CheckParams = z.infer<typeof CheckParamsSchema>\n\nexport const CheckResultSchema = z.object({\n state: z.enum(['ok', 'warn']),\n lines: z.array(z.string()),\n})\nexport type CheckResult = z.infer<typeof CheckResultSchema>\n\nconst WebSessionSchema = z.object({\n platform: z.literal('web'),\n engine: z.enum(['chromium', 'firefox', 'webkit']),\n context: z.enum(['new', 'reuse']),\n})\n\nconst DeviceSessionSchema = z.object({\n platform: z.enum(['android', 'ios']),\n capabilities: JsonObjectSchema,\n})\n\nexport const AcquireParamsSchema = z.object({\n remote: z.string(),\n settings: JsonObjectSchema,\n session: z.discriminatedUnion('platform', [WebSessionSchema, DeviceSessionSchema]),\n run: z.object({ testName: z.string().optional() }).optional(),\n})\nexport type AcquireParams = z.infer<typeof AcquireParamsSchema>\n\nexport const AcquireResultSchema = z.object({\n handle: HandleSchema,\n protocol: z.enum(PLUGIN_SERVES),\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n capabilities: JsonObjectSchema.optional(),\n mask: z.array(z.string()).optional(),\n link: z.string().optional(),\n})\nexport type AcquireResult = z.infer<typeof AcquireResultSchema>\n\nexport const UploadAppParamsSchema = z.object({\n remote: z.string(),\n settings: JsonObjectSchema,\n platform: z.enum(['android', 'ios']),\n path: z.string(),\n sha256: z.string(),\n size: z.number().int().nonnegative(),\n})\nexport type UploadAppParams = z.infer<typeof UploadAppParamsSchema>\n\nexport const UploadAppResultSchema = z.object({ ref: z.string() })\nexport type UploadAppResult = z.infer<typeof UploadAppResultSchema>\n\nexport const StartedParamsSchema = z.object({\n handle: HandleSchema,\n sessionId: z.string().optional(),\n})\nexport type StartedParams = z.infer<typeof StartedParamsSchema>\n\nexport const StartedResultSchema = z.object({\n link: z.string().optional(),\n appiumVersion: z.string().optional(),\n})\nexport type StartedResult = z.infer<typeof StartedResultSchema>\n\nexport const EndParamsSchema = z.object({\n handle: HandleSchema,\n outcome: z.enum(['passed', 'failed', 'error', 'cancelled']),\n reason: z.string().optional(),\n})\nexport type EndParams = z.infer<typeof EndParamsSchema>\n\nexport const ReleaseParamsSchema = z.object({ handle: HandleSchema })\nexport type ReleaseParams = z.infer<typeof ReleaseParamsSchema>\n\nexport const CancelParamsSchema = z.object({ id: RequestIdSchema })\nexport type CancelParams = z.infer<typeof CancelParamsSchema>\n\nexport const ProgressParamsSchema = z.object({\n id: RequestIdSchema,\n message: z.string(),\n queued: z.number().int().nonnegative().optional(),\n percent: z.number().min(0).max(100).optional(),\n})\nexport type ProgressParams = z.infer<typeof ProgressParamsSchema>\n\nexport const PluginErrorDataSchema = z.object({\n kind: z.enum(PLUGIN_FAILURE_KINDS),\n path: z.string().optional(),\n handle: HandleSchema.optional(),\n supported: z.array(z.number().int()).optional(),\n requested: z.array(z.number().int()).optional(),\n})\nexport type PluginErrorData = z.infer<typeof PluginErrorDataSchema>\n","import { z } from 'zod'\nimport { OPTIONAL_PLUGIN_METHODS, PLUGIN_RUN_FACTS, PLUGIN_SERVES } from './messages.js'\n\n// The manifest sits at package.json[\"agent-qa\"].plugin.\nexport const PLUGIN_MANIFEST_FIELD = 'agent-qa'\n\nconst PackagePathSchema = z.string().min(1)\n\nconst RemotePluginManifestSchema = z.strictObject({\n kind: z.literal('remote'),\n runs: z.literal('process'),\n protocol: z.number().int().positive(),\n entry: PackagePathSchema,\n serves: z.array(z.enum(PLUGIN_SERVES)).nonempty(),\n methods: z.array(z.enum(OPTIONAL_PLUGIN_METHODS)),\n options: PackagePathSchema,\n settings: PackagePathSchema,\n runFacts: z.array(z.enum(PLUGIN_RUN_FACTS)).optional(),\n skill: PackagePathSchema.optional(),\n})\n\nconst ModelAuthManifestSchema = z.strictObject({\n kind: z.literal('model-auth'),\n runs: z.literal('in-process'),\n entry: PackagePathSchema,\n options: PackagePathSchema.optional(),\n})\n\nconst ModelProviderManifestSchema = z.strictObject({\n kind: z.literal('model-provider'),\n runs: z.literal('in-process'),\n entry: PackagePathSchema,\n options: PackagePathSchema.optional(),\n})\n\nexport const PluginManifestSchema = z.discriminatedUnion('kind', [\n RemotePluginManifestSchema,\n ModelAuthManifestSchema,\n ModelProviderManifestSchema,\n])\nexport type PluginManifest = z.infer<typeof PluginManifestSchema>\nexport type RemotePluginManifest = z.infer<typeof RemotePluginManifestSchema>\n","import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { isDeepStrictEqual } from 'node:util'\nimport { z } from 'zod'\nimport type { PluginDefinition } from './define-plugin.js'\nimport {\n PLUGIN_MANIFEST_FIELD,\n PluginManifestSchema,\n type RemotePluginManifest,\n} from './protocol/manifest.js'\nimport { PLUGIN_PROTOCOL_VERSION } from './protocol/messages.js'\n\nexport interface EmitPluginFilesInput<\n OptionsSchema extends z.ZodType,\n SettingsSchema extends z.ZodType,\n> {\n definition: PluginDefinition<OptionsSchema, SettingsSchema>\n packageDir: string\n}\n\nexport interface EmittedPluginFiles {\n manifest: RemotePluginManifest\n optionsSchemaFile: string\n settingsSchemaFile: string\n packageJsonChanged: boolean\n}\n\nconst OPTIONS_SCHEMA_PATH = './dist/options.schema.json'\nconst SETTINGS_SCHEMA_PATH = './dist/settings.schema.json'\n\nexport function pluginManifest<OptionsSchema extends z.ZodType, SettingsSchema extends z.ZodType>(\n definition: PluginDefinition<OptionsSchema, SettingsSchema>,\n): RemotePluginManifest {\n const manifest = PluginManifestSchema.parse({\n protocol: PLUGIN_PROTOCOL_VERSION,\n kind: 'remote',\n runs: 'process',\n entry: './dist/main.js',\n serves: [...definition.serves],\n methods: [...definition.methods],\n options: OPTIONS_SCHEMA_PATH,\n settings: SETTINGS_SCHEMA_PATH,\n ...(definition.runFacts === undefined ? {} : { runFacts: [...definition.runFacts] }),\n ...(definition.skill === undefined ? {} : { skill: definition.skill }),\n })\n if (manifest.kind !== 'remote') throw new Error('a plugin built with the kit is remote')\n return manifest\n}\n\nfunction schemaText(schema: z.ZodType): string {\n return `${JSON.stringify(z.toJSONSchema(schema, { io: 'input', target: 'draft-2020-12' }), null, 2)}\\n`\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport function emitPluginFiles<OptionsSchema extends z.ZodType, SettingsSchema extends z.ZodType>(\n input: EmitPluginFilesInput<OptionsSchema, SettingsSchema>,\n): EmittedPluginFiles {\n const { definition, packageDir } = input\n const manifest = pluginManifest(definition)\n const optionsSchemaFile = join(packageDir, OPTIONS_SCHEMA_PATH)\n const settingsSchemaFile = join(packageDir, SETTINGS_SCHEMA_PATH)\n mkdirSync(join(packageDir, 'dist'), { recursive: true })\n writeFileSync(optionsSchemaFile, schemaText(definition.options))\n writeFileSync(settingsSchemaFile, schemaText(definition.settings))\n\n const packageJsonFile = join(packageDir, 'package.json')\n const parsed: unknown = JSON.parse(readFileSync(packageJsonFile, 'utf8'))\n if (!isRecord(parsed)) throw new Error(`${packageJsonFile} is not a JSON object`)\n const field = isRecord(parsed[PLUGIN_MANIFEST_FIELD]) ? parsed[PLUGIN_MANIFEST_FIELD] : {}\n const packageJsonChanged = !isDeepStrictEqual(field.plugin, manifest)\n if (packageJsonChanged) {\n const next = { ...parsed, [PLUGIN_MANIFEST_FIELD]: { ...field, plugin: manifest } }\n writeFileSync(packageJsonFile, `${JSON.stringify(next, null, 2)}\\n`)\n }\n return { manifest, optionsSchemaFile, settingsSchemaFile, packageJsonChanged }\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\n\nexport function findPackageRoot(fromDir: string): string | undefined {\n let dir = fromDir\n for (;;) {\n if (existsSync(join(dir, 'package.json'))) return dir\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport function readPackageJson(packageRoot: string): Record<string, unknown> {\n const parsed: unknown = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'))\n return typeof parsed === 'object' && parsed !== null ? (parsed as Record<string, unknown>) : {}\n}\n","const PROXY_NAMES = ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY', 'ALL_PROXY'] as const\n\nexport const PLUGIN_ENVIRONMENT_NAMES = [\n 'PATH',\n 'HOME',\n 'TMPDIR',\n 'TEMP',\n 'TMP',\n 'LANG',\n 'TZ',\n ...PROXY_NAMES,\n ...PROXY_NAMES.map((name) => name.toLowerCase()),\n 'NODE_EXTRA_CA_CERTS',\n 'SSL_CERT_FILE',\n] as const\n\nexport const PLUGIN_WINDOWS_ENVIRONMENT_NAMES = [\n 'SystemRoot',\n 'ComSpec',\n 'PATHEXT',\n 'USERPROFILE',\n 'APPDATA',\n 'LOCALAPPDATA',\n] as const\n\n// Secrets reach a plugin only in initialize, so nothing else from the host's environment passes.\nexport function pluginEnvironment(\n env: Readonly<Record<string, string | undefined>>,\n platform: string,\n): Record<string, string> {\n const windows = platform === 'win32'\n const names = new Set<string>(PLUGIN_ENVIRONMENT_NAMES)\n if (windows) {\n for (const name of PLUGIN_WINDOWS_ENVIRONMENT_NAMES) names.add(name.toUpperCase())\n }\n const passes = (key: string): boolean => {\n if (key.startsWith('LC_')) return true\n if (names.has(key)) return true\n // Windows names are case-insensitive: Path is PATH there.\n return windows && names.has(key.toUpperCase())\n }\n const out: Record<string, string> = {}\n for (const [key, value] of Object.entries(env)) {\n if (value === undefined || key.toUpperCase() === 'NODE_OPTIONS') continue\n if (passes(key)) out[key] = value\n }\n return out\n}\n","export function encodeMessage(message: unknown): string {\n return `${JSON.stringify(message)}\\n`\n}\n\nexport interface LineDecoderOptions {\n maxLineBytes: number\n onLine: (line: string) => void\n onOverflow: () => void\n}\n\nexport interface LineDecoder {\n push(chunk: Uint8Array | string): void\n end(): void\n}\n\nconst NEWLINE = 0x0a\n\nexport function createLineDecoder({\n maxLineBytes,\n onLine,\n onOverflow,\n}: LineDecoderOptions): LineDecoder {\n const encoder = new TextEncoder()\n const decoder = new TextDecoder()\n let parts: Uint8Array[] = []\n let size = 0\n let discarding = false\n\n const append = (segment: Uint8Array) => {\n if (discarding || segment.length === 0) return\n if (size + segment.length > maxLineBytes) {\n discarding = true\n parts = []\n size = 0\n onOverflow()\n return\n }\n parts.push(new Uint8Array(segment))\n size += segment.length\n }\n\n const finishLine = () => {\n const wasDiscarding = discarding\n const lineParts = parts\n const lineSize = size\n parts = []\n size = 0\n discarding = false\n if (wasDiscarding || lineSize === 0) return\n const bytes = new Uint8Array(lineSize)\n let offset = 0\n for (const part of lineParts) {\n bytes.set(part, offset)\n offset += part.length\n }\n const line = decoder.decode(bytes).replace(/\\r$/, '')\n if (line.trim() !== '') onLine(line)\n }\n\n return {\n push(chunk) {\n const bytes = typeof chunk === 'string' ? encoder.encode(chunk) : chunk\n let start = 0\n while (start <= bytes.length) {\n const newline = bytes.indexOf(NEWLINE, start)\n if (newline === -1) {\n append(bytes.subarray(start))\n return\n }\n append(bytes.subarray(start, newline))\n finishLine()\n start = newline + 1\n }\n },\n end() {\n finishLine()\n },\n }\n}\n","import { spawn } from 'node:child_process'\nimport { existsSync, readFileSync, realpathSync } from 'node:fs'\nimport { dirname, isAbsolute, join, relative, sep } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { isDeepStrictEqual } from 'node:util'\nimport type { z } from 'zod'\nimport type { PluginDefinition } from '../define-plugin.js'\nimport { pluginManifest } from '../emit.js'\nimport { findPackageRoot, readPackageJson } from '../package-root.js'\nimport { pluginEnvironment } from '../protocol/environment.js'\nimport { createLineDecoder, encodeMessage } from '../protocol/framing.js'\nimport {\n PLUGIN_MANIFEST_FIELD,\n PluginManifestSchema,\n type RemotePluginManifest,\n} from '../protocol/manifest.js'\nimport {\n AcquireResultSchema,\n CANCEL_METHOD,\n InitializeResultSchema,\n MAX_MESSAGE_BYTES,\n PLUGIN_ERROR_CODES,\n PLUGIN_PROTOCOL_VERSION,\n PluginErrorDataSchema,\n type AcquireParams,\n type InitializeParams,\n} from '../protocol/messages.js'\n\nexport type ConformanceCheckName =\n | 'manifest'\n | 'handshake'\n | 'unknown-method'\n | 'idempotent-release'\n | 'answered-cancel'\n | 'clean-stdout'\n | 'exit-on-stdin-close'\n\nexport interface ConformanceCheck {\n name: ConformanceCheckName\n ok: boolean\n detail?: string\n}\n\nexport interface ConformanceReport {\n ok: boolean\n checks: ConformanceCheck[]\n}\n\nexport interface ConformanceInput {\n packageDir: string\n options: Record<string, unknown>\n settings?: Record<string, unknown>\n session?: AcquireParams['session']\n host?: Partial<InitializeParams['host']>\n quick?: boolean\n timeoutMs?: number\n}\n\nconst DEFAULT_CALL_TIMEOUT_MS = 10_000\nconst CANCEL_ANSWER_WINDOW_MS = 5_000\nconst EXIT_WINDOW_MS = 5_000\nconst STDIO_DRAIN_MS = 1_000\nconst DRAFT_2020_12 = /^https:\\/\\/json-schema\\.org\\/draft\\/2020-12\\/schema#?$/\nconst DEFAULT_SESSION: AcquireParams['session'] = {\n platform: 'web',\n engine: 'chromium',\n context: 'new',\n}\n\ninterface RpcAnswer {\n result?: unknown\n error?: { code: number; message: string; data?: unknown }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nfunction kitVersion(): string {\n const root = findPackageRoot(dirname(fileURLToPath(import.meta.url)))\n const version = root === undefined ? undefined : readPackageJson(root).version\n return typeof version === 'string' ? version : 'unknown'\n}\n\nfunction hostIdentity(host: ConformanceInput['host']): InitializeParams['host'] {\n return {\n pid: process.pid,\n agentQaVersion: kitVersion(),\n playwrightVersion: 'unknown',\n webdriverioVersion: 'unknown',\n ...host,\n }\n}\n\nfunction readManifestField(packageDir: string): unknown {\n const parsed: unknown = JSON.parse(readFileSync(join(packageDir, 'package.json'), 'utf8'))\n const field = isRecord(parsed) ? parsed[PLUGIN_MANIFEST_FIELD] : undefined\n return isRecord(field) ? field.plugin : undefined\n}\n\nfunction insidePackage(packageRoot: string, path: string): string | undefined {\n const target = join(packageRoot, path)\n if (!existsSync(target)) return undefined\n const real = realpathSync(target)\n const fromRoot = relative(packageRoot, real)\n if (fromRoot === '..' || fromRoot.startsWith(`..${sep}`) || isAbsolute(fromRoot)) return undefined\n return real\n}\n\ninterface CheckedManifest {\n check: ConformanceCheck\n manifest?: RemotePluginManifest\n entry?: string\n}\n\nfunction checkManifest(packageDir: string): CheckedManifest {\n const failed = (detail: string): CheckedManifest => ({\n check: { name: 'manifest', ok: false, detail },\n })\n let packageRoot: string\n let field: unknown\n try {\n packageRoot = realpathSync(packageDir)\n field = readManifestField(packageRoot)\n } catch (error) {\n return failed(`package.json could not be read: ${errorText(error)}`)\n }\n if (field === undefined) return failed(`package.json has no ${PLUGIN_MANIFEST_FIELD}.plugin`)\n const parsed = PluginManifestSchema.safeParse(field)\n if (!parsed.success) {\n return failed(\n parsed.error.issues\n .map(\n (issue) =>\n `${[PLUGIN_MANIFEST_FIELD, 'plugin', ...issue.path.map(String)].join('.')}: ${issue.message}`,\n )\n .join('; '),\n )\n }\n const manifest = parsed.data\n if (manifest.kind !== 'remote') {\n return failed(`a conformance run checks a remote plugin, and this one is ${manifest.kind}`)\n }\n\n const problems: string[] = []\n const resolved = (key: 'entry' | 'options' | 'settings' | 'skill', path: string) => {\n const real = insidePackage(packageRoot, path)\n if (real === undefined) problems.push(`${key} ${path} does not resolve inside the package`)\n return real\n }\n const entry = resolved('entry', manifest.entry)\n for (const key of ['options', 'settings'] as const) {\n const file = resolved(key, manifest[key])\n if (file === undefined) continue\n try {\n const schema: unknown = JSON.parse(readFileSync(file, 'utf8'))\n if (!isRecord(schema) || typeof schema.$schema !== 'string') {\n problems.push(`${key} ${manifest[key]} names no $schema`)\n } else if (!DRAFT_2020_12.test(schema.$schema)) {\n problems.push(`${key} ${manifest[key]} is ${schema.$schema}, not JSON Schema draft 2020-12`)\n }\n } catch (error) {\n problems.push(`${key} ${manifest[key]} is not JSON: ${errorText(error)}`)\n }\n }\n if (manifest.skill !== undefined) resolved('skill', manifest.skill)\n if (problems.length > 0) return failed(problems.join('; '))\n return { check: { name: 'manifest', ok: true }, manifest, ...(entry ? { entry } : {}) }\n}\n\ninterface PluginProcess {\n request(method: string, params: unknown, timeoutMs: number): Promise<RpcAnswer>\n send(method: string, params: unknown): { id: number; answered: Promise<RpcAnswer> }\n notify(method: string, params: unknown): void\n stdoutProblems(): string[]\n closeStdin(): void\n exitedWithin(ms: number): Promise<{ exited: boolean; code: number | null }>\n drained(ms: number): Promise<void>\n hasExited(): boolean\n kill(): void\n}\n\nfunction within<T>(promise: Promise<T>, ms: number, what: string): Promise<T> {\n let timer: NodeJS.Timeout | undefined\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(`${what} got no answer within ${ms} ms`)), ms)\n })\n return Promise.race([promise, timeout]).finally(() => clearTimeout(timer))\n}\n\nfunction startPlugin(entry: string, cwd: string): PluginProcess {\n const child = spawn(process.execPath, [entry], {\n cwd,\n env: pluginEnvironment(process.env, process.platform),\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n const waiting = new Map<number, (answer: RpcAnswer) => void>()\n const problems: string[] = []\n let stderr = ''\n let exitCode: number | null = null\n let exited = false\n child.stdin.on('error', () => {})\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString()\n })\n const decoder = createLineDecoder({\n maxLineBytes: MAX_MESSAGE_BYTES,\n onLine: (line) => {\n let message: unknown\n try {\n message = JSON.parse(line)\n } catch {\n problems.push(line)\n return\n }\n if (!isRecord(message) || message.jsonrpc !== '2.0') {\n problems.push(line)\n return\n }\n const resolve = typeof message.id === 'number' ? waiting.get(message.id) : undefined\n if (resolve === undefined || typeof message.id !== 'number') return\n waiting.delete(message.id)\n resolve(message as RpcAnswer)\n },\n onOverflow: () => problems.push(`a line longer than ${MAX_MESSAGE_BYTES} bytes`),\n })\n child.stdout.on('data', (chunk: Buffer) => decoder.push(chunk))\n const exit = new Promise<number | null>((resolve) =>\n child.on('exit', (code) => {\n exited = true\n exitCode = code\n resolve(code)\n }),\n )\n // 'exit' can come before stdout delivers its last chunks; 'close' comes after the streams end.\n const closed = new Promise<void>((resolve) => child.on('close', () => resolve()))\n let next = 0\n\n const plugin: PluginProcess = {\n send(method, params) {\n next += 1\n const id = next\n const answered = new Promise<RpcAnswer>((resolve, reject) => {\n waiting.set(id, resolve)\n void exit.then((code) => {\n const reason = stderr.trim().split('\\n')[0] ?? ''\n reject(new Error(`the plugin exited with ${code} before answering ${method} ${reason}`))\n })\n })\n answered.catch(() => {})\n child.stdin.write(encodeMessage({ jsonrpc: '2.0', id, method, params }))\n return { id, answered }\n },\n request(method, params, timeoutMs) {\n return within(plugin.send(method, params).answered, timeoutMs, method)\n },\n notify(method, params) {\n child.stdin.write(encodeMessage({ jsonrpc: '2.0', method, params }))\n },\n stdoutProblems() {\n return [...problems]\n },\n closeStdin() {\n child.stdin.end()\n },\n async exitedWithin(ms) {\n if (exited) return { exited: true, code: exitCode }\n try {\n const code = await within(exit, ms, 'exit')\n return { exited: true, code }\n } catch {\n return { exited: false, code: null }\n }\n },\n async drained(ms) {\n await within(closed, ms, 'stdout').catch(() => {})\n decoder.end()\n },\n hasExited() {\n return exited\n },\n kill() {\n if (!exited) child.kill('SIGKILL')\n },\n }\n return plugin\n}\n\nfunction describeError(answer: RpcAnswer): string {\n if (answer.error === undefined) return `answered ${JSON.stringify(answer.result)}`\n const data = PluginErrorDataSchema.safeParse(answer.error.data)\n const kind = data.success ? ` (kind ${data.data.kind})` : ''\n return `answered ${answer.error.code}: ${answer.error.message}${kind}`\n}\n\nfunction errorHandle(answer: RpcAnswer): unknown {\n const data = answer.error?.data\n return isRecord(data) ? data.handle : undefined\n}\n\nasync function checkHandshake(\n plugin: PluginProcess,\n manifest: RemotePluginManifest,\n input: ConformanceInput,\n timeoutMs: number,\n): Promise<ConformanceCheck> {\n const name = 'handshake'\n let answer: RpcAnswer\n try {\n answer = await plugin.request(\n 'initialize',\n {\n protocolVersions: [PLUGIN_PROTOCOL_VERSION],\n host: hostIdentity(input.host),\n entry: 'conformance',\n options: input.options,\n },\n timeoutMs,\n )\n } catch (error) {\n return { name, ok: false, detail: errorText(error) }\n }\n if (answer.error !== undefined) {\n const refusal =\n answer.error.code === PLUGIN_ERROR_CODES.plugin &&\n typeof answer.error.message === 'string' &&\n answer.error.message !== '' &&\n PluginErrorDataSchema.safeParse(answer.error.data).success\n if (input.quick === true && refusal) {\n return { name, ok: true, detail: `initialize refused: ${describeError(answer)}` }\n }\n return { name, ok: false, detail: `initialize ${describeError(answer)}` }\n }\n const result = InitializeResultSchema.safeParse(answer.result)\n if (!result.success) {\n return {\n name,\n ok: false,\n detail: `initialize answered a malformed result: ${result.error.message}`,\n }\n }\n const sorted = (values: readonly string[]) => [...values].sort()\n const problems: string[] = []\n if (result.data.protocolVersion !== PLUGIN_PROTOCOL_VERSION) {\n problems.push(`protocol ${result.data.protocolVersion}, not ${PLUGIN_PROTOCOL_VERSION}`)\n }\n if (!isDeepStrictEqual(sorted(result.data.serves), sorted(manifest.serves))) {\n problems.push(\n `serves ${result.data.serves.join(', ')}, and the manifest says ${manifest.serves.join(', ')}`,\n )\n }\n if (!isDeepStrictEqual(sorted(result.data.methods), sorted(manifest.methods))) {\n problems.push(\n `methods ${result.data.methods.join(', ') || 'none'}, and the manifest says ${manifest.methods.join(', ') || 'none'}`,\n )\n }\n return problems.length === 0\n ? { name, ok: true }\n : { name, ok: false, detail: `initialize answered ${problems.join('; ')}` }\n}\n\nasync function checkUnknownMethod(\n plugin: PluginProcess,\n timeoutMs: number,\n): Promise<ConformanceCheck> {\n const name = 'unknown-method'\n try {\n const answer = await plugin.request('agent-qa/none', {}, timeoutMs)\n return answer.error?.code === PLUGIN_ERROR_CODES.methodNotFound\n ? { name, ok: true }\n : {\n name,\n ok: false,\n detail: `agent-qa/none ${describeError(answer)}, not ${PLUGIN_ERROR_CODES.methodNotFound}`,\n }\n } catch (error) {\n return { name, ok: false, detail: errorText(error) }\n }\n}\n\nasync function release(plugin: PluginProcess, handle: unknown, timeoutMs: number) {\n return plugin.request('release', { handle }, timeoutMs)\n}\n\nasync function checkIdempotentRelease(\n plugin: PluginProcess,\n acquireParams: AcquireParams,\n timeoutMs: number,\n): Promise<ConformanceCheck> {\n const name = 'idempotent-release'\n try {\n const acquired = await plugin.request('acquire', acquireParams, timeoutMs)\n if (acquired.error !== undefined) {\n const handle = errorHandle(acquired)\n if (handle !== undefined) await release(plugin, handle, timeoutMs).catch(() => {})\n return { name, ok: false, detail: `acquire ${describeError(acquired)}` }\n }\n const result = AcquireResultSchema.safeParse(acquired.result)\n if (!result.success) {\n return {\n name,\n ok: false,\n detail: `acquire answered a malformed result: ${result.error.message}`,\n }\n }\n for (const attempt of ['first', 'second']) {\n const released = await release(plugin, result.data.handle, timeoutMs)\n if (released.error !== undefined || !isDeepStrictEqual(released.result, {})) {\n return { name, ok: false, detail: `the ${attempt} release ${describeError(released)}` }\n }\n }\n return { name, ok: true }\n } catch (error) {\n return { name, ok: false, detail: errorText(error) }\n }\n}\n\nasync function checkAnsweredCancel(\n plugin: PluginProcess,\n acquireParams: AcquireParams,\n timeoutMs: number,\n): Promise<ConformanceCheck> {\n const name = 'answered-cancel'\n try {\n const acquire = plugin.send('acquire', acquireParams)\n plugin.notify(CANCEL_METHOD, { id: acquire.id })\n const answer = await within(acquire.answered, CANCEL_ANSWER_WINDOW_MS, 'a cancelled acquire')\n if (answer.error === undefined) {\n const result = AcquireResultSchema.safeParse(answer.result)\n if (result.success) await release(plugin, result.data.handle, timeoutMs).catch(() => {})\n return result.success\n ? { name, ok: true }\n : { name, ok: false, detail: 'a cancelled acquire answered a malformed result' }\n }\n const handle = errorHandle(answer)\n if (handle !== undefined) await release(plugin, handle, timeoutMs).catch(() => {})\n return answer.error.code === PLUGIN_ERROR_CODES.cancelled\n ? { name, ok: true }\n : {\n name,\n ok: false,\n detail: `a cancelled acquire ${describeError(answer)}, not a result or ${PLUGIN_ERROR_CODES.cancelled}`,\n }\n } catch (error) {\n return { name, ok: false, detail: errorText(error) }\n }\n}\n\nasync function checkExitOnStdinClose(plugin: PluginProcess): Promise<ConformanceCheck> {\n const name = 'exit-on-stdin-close'\n if (plugin.hasExited()) {\n return { name, ok: false, detail: 'the plugin exited before its stdin closed' }\n }\n plugin.closeStdin()\n const { exited } = await plugin.exitedWithin(EXIT_WINDOW_MS)\n return exited\n ? { name, ok: true }\n : {\n name,\n ok: false,\n detail: `the plugin was still running ${EXIT_WINDOW_MS} ms after stdin closed`,\n }\n}\n\nexport async function runConformance(input: ConformanceInput): Promise<ConformanceReport> {\n const timeoutMs = input.timeoutMs ?? DEFAULT_CALL_TIMEOUT_MS\n const checked = checkManifest(input.packageDir)\n const checks: ConformanceCheck[] = [checked.check]\n if (checked.manifest === undefined || checked.entry === undefined) {\n return { ok: false, checks }\n }\n\n const plugin = startPlugin(checked.entry, input.packageDir)\n try {\n checks.push(await checkHandshake(plugin, checked.manifest, input, timeoutMs))\n checks.push(await checkUnknownMethod(plugin, timeoutMs))\n if (input.quick !== true) {\n const acquireParams: AcquireParams = {\n remote: 'conformance',\n settings: input.settings ?? {},\n session: input.session ?? DEFAULT_SESSION,\n }\n checks.push(await checkIdempotentRelease(plugin, acquireParams, timeoutMs))\n checks.push(await checkAnsweredCancel(plugin, acquireParams, timeoutMs))\n }\n const exitCheck = await checkExitOnStdinClose(plugin)\n if (exitCheck.ok) await plugin.drained(STDIO_DRAIN_MS)\n const unclean = plugin.stdoutProblems()\n checks.push(\n unclean.length === 0\n ? { name: 'clean-stdout', ok: true }\n : {\n name: 'clean-stdout',\n ok: false,\n detail: `stdout carried ${unclean.length} line(s) that are not JSON-RPC, the first: ${unclean[0]?.slice(0, 200)}`,\n },\n )\n checks.push(exitCheck)\n } finally {\n plugin.kill()\n }\n return { ok: checks.every((check) => check.ok), checks }\n}\n\nexport function expectManifestCurrent<\n OptionsSchema extends z.ZodType,\n SettingsSchema extends z.ZodType,\n>(packageDir: string, definition: PluginDefinition<OptionsSchema, SettingsSchema>): void {\n const expected: Record<string, unknown> = { ...pluginManifest(definition) }\n const field = readManifestField(packageDir)\n const actual: Record<string, unknown> = isRecord(field) ? field : {}\n const keys = [...new Set([...Object.keys(expected), ...Object.keys(actual)])].sort()\n const differing = keys.filter((key) => !isDeepStrictEqual(actual[key], expected[key]))\n if (differing.length > 0) {\n throw new Error(\n `package.json's ${PLUGIN_MANIFEST_FIELD}.plugin differs from the definition in ${differing.join(', ')}; run the build's emit step`,\n )\n }\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport type { AddressInfo, Socket } from 'node:net'\n\nexport type LoopbackReply =\n | 'hold'\n | {\n status: number\n json?: unknown\n text?: string\n headers?: Record<string, string>\n }\n\nexport interface LoopbackRequest {\n method: string\n path: string\n query: Record<string, string>\n params: Record<string, string>\n headers: Record<string, string>\n body: unknown\n}\n\nexport type LoopbackRoute = readonly LoopbackReply[] | ((request: LoopbackRequest) => LoopbackReply)\n\nexport interface LoopbackFakeInput {\n // Keyed by 'METHOD /path'; a ':name' segment matches any one segment.\n routes: Record<string, LoopbackRoute>\n}\n\nexport interface LoopbackFake {\n url: string\n origin: string\n requests: readonly LoopbackRequest[]\n routeCalls(key: string): readonly LoopbackRequest[]\n close(): Promise<void>\n}\n\ninterface CompiledRoute {\n key: string\n method: string\n segments: string[]\n route: LoopbackRoute\n calls: LoopbackRequest[]\n}\n\nfunction splitPath(path: string): string[] {\n return path.split('/').filter((segment) => segment !== '')\n}\n\nfunction compile(key: string, route: LoopbackRoute): CompiledRoute {\n const match = /^([A-Z]+) (\\/\\S*)$/.exec(key)\n if (match?.[1] === undefined || match[2] === undefined) {\n throw new Error(`a loopback route is 'METHOD /path', not '${key}'`)\n }\n if (Array.isArray(route) && route.length === 0) {\n throw new Error(`the loopback route '${key}' has no replies`)\n }\n return { key, method: match[1], segments: splitPath(match[2]), route, calls: [] }\n}\n\nfunction decodeSegment(segment: string): string {\n try {\n return decodeURIComponent(segment)\n } catch {\n return segment\n }\n}\n\nfunction matchParams(route: CompiledRoute, method: string, path: string) {\n if (route.method !== method) return undefined\n const segments = splitPath(path)\n if (segments.length !== route.segments.length) return undefined\n const params: Record<string, string> = {}\n for (const [index, expected] of route.segments.entries()) {\n const actual = segments[index] ?? ''\n if (expected.startsWith(':')) params[expected.slice(1)] = decodeSegment(actual)\n else if (expected !== actual) return undefined\n }\n return params\n}\n\nfunction lowerCasedHeaders(request: IncomingMessage): Record<string, string> {\n const headers: Record<string, string> = {}\n for (const [name, value] of Object.entries(request.headers)) {\n if (value === undefined) continue\n headers[name.toLowerCase()] = Array.isArray(value) ? value.join(', ') : value\n }\n return headers\n}\n\nfunction parseBody(text: string): unknown {\n if (text.length === 0) return undefined\n try {\n return JSON.parse(text) as unknown\n } catch {\n return text\n }\n}\n\nfunction send(response: ServerResponse, reply: Exclude<LoopbackReply, 'hold'>): void {\n const [contentType, text] =\n reply.json !== undefined\n ? ['application/json; charset=utf-8', JSON.stringify(reply.json)]\n : ['text/plain; charset=utf-8', reply.text ?? '']\n response.writeHead(reply.status, {\n 'content-type': contentType,\n 'content-length': Buffer.byteLength(text),\n ...reply.headers,\n })\n response.end(text)\n}\n\nexport async function startLoopbackFake(input: LoopbackFakeInput): Promise<LoopbackFake> {\n const routes = Object.entries(input.routes).map(([key, route]) => compile(key, route))\n const requests: LoopbackRequest[] = []\n const sockets = new Set<Socket>()\n let routeFailure: unknown\n\n const answer = (record: LoopbackRequest, response: ServerResponse) => {\n for (const route of routes) {\n const params = matchParams(route, record.method, record.path)\n if (params === undefined) continue\n const request = { ...record, params }\n requests.push(request)\n route.calls.push(request)\n const reply =\n typeof route.route === 'function'\n ? route.route(request)\n : (route.route[Math.min(route.calls.length, route.route.length) - 1] ?? 'hold')\n if (reply !== 'hold') send(response, reply)\n return\n }\n requests.push(record)\n send(response, { status: 404, json: { message: 'no route' } })\n }\n\n const server = createServer((request, response) => {\n const chunks: Buffer[] = []\n request.on('data', (chunk: Buffer) => chunks.push(chunk))\n request.on('end', () => {\n const url = new URL(request.url ?? '/', 'http://127.0.0.1')\n const record: LoopbackRequest = {\n method: request.method ?? 'GET',\n path: url.pathname,\n query: Object.fromEntries(url.searchParams),\n params: {},\n headers: lowerCasedHeaders(request),\n body: parseBody(Buffer.concat(chunks).toString('utf8')),\n }\n try {\n answer(record, response)\n } catch (error) {\n // A route that throws, such as an expect() on a header, fails the test at close.\n routeFailure ??= error\n if (!response.headersSent) {\n send(response, { status: 500, json: { message: `the route threw: ${String(error)}` } })\n }\n }\n })\n })\n server.on('connection', (socket: Socket) => {\n sockets.add(socket)\n socket.on('close', () => sockets.delete(socket))\n })\n await new Promise<void>((ready, failed) => {\n server.once('error', failed)\n server.listen(0, '127.0.0.1', () => ready())\n })\n const { port } = server.address() as AddressInfo\n const origin = `http://127.0.0.1:${String(port)}`\n let closing: Promise<void> | undefined\n\n return {\n url: origin,\n origin,\n requests,\n routeCalls(key) {\n return [...(routes.find((route) => route.key === key)?.calls ?? [])]\n },\n close() {\n closing ??= new Promise<void>((closed, failed) => {\n for (const socket of sockets) socket.destroy()\n server.close(() => (routeFailure === undefined ? closed() : failed(routeFailure)))\n })\n return closing\n },\n }\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { findPackageRoot } from '../package-root.js'\nimport { PLUGIN_MANIFEST_FIELD, PluginManifestSchema } from '../protocol/manifest.js'\nimport {\n OPTIONAL_PLUGIN_METHODS,\n PLUGIN_PROTOCOL_VERSION,\n PLUGIN_SERVES,\n type OptionalPluginMethod,\n type PluginRunFact,\n type PluginServe,\n} from '../protocol/messages.js'\n\nexport interface ScriptedPluginInput {\n packageName?: string\n version?: string\n serves?: readonly PluginServe[]\n methods?: readonly OptionalPluginMethod[]\n runFacts?: readonly PluginRunFact[]\n timing?: ScriptedPluginTiming\n}\n\nexport interface ScriptedPluginTiming {\n cancelAnswerGraceMs?: number\n hostPidPollMs?: number\n}\n\nexport interface ScriptedPlugin {\n dir: string\n entry: string\n}\n\nconst OPEN_OBJECT_SCHEMA = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n type: 'object',\n}\n\nconst SKILL = `---\nname: scripted\ndescription: A scripted agent-qa plugin that answers each call as its options say.\n---\n\n# Scripted plugin\n\nEach call follows \\`options.script[method]\\`: \\`ok\\`, \\`hold\\`, \\`ignoreCancel\\`, \\`crash\\`,\n\\`uncaught\\` (a Node deprecation warning, then an exception nothing catches), \\`noise\\`,\n\\`consoleLog\\`, \\`{ delayMs }\\`, \\`{ error }\\` or \\`{ errorAfterCreate }\\`. A list of\nsteps gives each call the next one, and the last repeats. \\`options.stderr[method]\\` is written\nto stderr before the step. Acquire answers \\`options.answer\\`, or the JSON in the file\n\\`options.answerFile\\` names.\nWith \\`options.recordProcess\\`, the initialize ledger line also records the process, its\nenvironment's names, its options, the host and the run facts. With \\`options.recordParams\\`, the\nacquire line also records the session and run, the uploadApp line the settings, platform, path,\nsha256 and size, the started line the session id, and the end line the outcome and reason.\nAcquire and uploadApp send \\`options.progress\\`, or \\`options.progressByRemote[remote]\\`, as\nprogress before their step, and with \\`options.progressEveryMs\\` send them again, one each\ninterval, until they answer. uploadApp answers \\`options.upload\\`.\n`\n\nfunction scriptedMainFile(): string {\n const kitRoot = findPackageRoot(dirname(fileURLToPath(import.meta.url)))\n const file = kitRoot === undefined ? undefined : join(kitRoot, 'dist', 'scripted-plugin.js')\n if (file === undefined || !existsSync(file)) {\n throw new Error('the scripted plugin needs the kit built: run pnpm build in the plugin kit')\n }\n return file\n}\n\nexport function writeScriptedPlugin(dir: string, input: ScriptedPluginInput = {}): ScriptedPlugin {\n const manifest = PluginManifestSchema.parse({\n kind: 'remote',\n runs: 'process',\n protocol: PLUGIN_PROTOCOL_VERSION,\n entry: './main.mjs',\n serves: [...(input.serves ?? PLUGIN_SERVES)],\n methods: [...(input.methods ?? OPTIONAL_PLUGIN_METHODS)],\n options: './options.schema.json',\n settings: './settings.schema.json',\n ...(input.runFacts === undefined ? {} : { runFacts: [...input.runFacts] }),\n skill: './skill',\n })\n const packageJson = {\n name: input.packageName ?? '@acme/agent-qa-plugin-scripted',\n version: input.version ?? '1.0.0',\n private: true,\n type: 'module',\n keywords: ['agent-qa-plugin'],\n exports: { './package.json': './package.json' },\n [PLUGIN_MANIFEST_FIELD]: { plugin: manifest },\n }\n const mainUrl = pathToFileURL(scriptedMainFile()).href\n\n mkdirSync(join(dir, 'skill'), { recursive: true })\n writeFileSync(join(dir, 'package.json'), `${JSON.stringify(packageJson, null, 2)}\\n`)\n const openSchema = `${JSON.stringify(OPEN_OBJECT_SCHEMA, null, 2)}\\n`\n writeFileSync(join(dir, 'options.schema.json'), openSchema)\n writeFileSync(join(dir, 'settings.schema.json'), openSchema)\n writeFileSync(join(dir, 'skill', 'SKILL.md'), SKILL)\n const timing = {\n ...(input.timing?.cancelAnswerGraceMs === undefined\n ? {}\n : { cancelAnswerGraceMs: input.timing.cancelAnswerGraceMs }),\n ...(input.timing?.hostPidPollMs === undefined\n ? {}\n : { hostPidPollMs: input.timing.hostPidPollMs }),\n }\n writeFileSync(\n join(dir, 'main.mjs'),\n `import { startScriptedPlugin } from ${JSON.stringify(mainUrl)}\\n\\nstartScriptedPlugin(${JSON.stringify(timing)})\\n`,\n )\n return { dir, entry: join(dir, 'main.mjs') }\n}\n"],"mappings":";;;;;;;;AAgBA,MAAa,0BAA0B;CAAC;CAAS;CAAa;CAAW;AAAK;AAG9E,MAAa,gBAAgB;CAAC;CAAc;CAAO;AAAQ;AAG3D,MAAa,mBAAmB;CAAC;CAAY;CAAS;AAAS;AAG/D,MAAa,uBAAuB;CAClC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAGA,MAAa,qBAAqB;CAChC,OAAO;CACP,gBAAgB;CAChB,gBAAgB;CAChB,eAAe;CACf,QAAQ;CACR,WAAW;AACb;AAEA,MAAa,gBAAgB;AAG7B,MAAa,oBAAoB;AAEjC,MAAM,mBAAmB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AACzD,MAAM,eAAe,EAAE,KAAK;AAC5B,MAAM,kBAAkB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAElB,EAAE,OAAO;CAC7C,kBAAkB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CAC1C,MAAM,EAAE,OAAO;EACb,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI;EACpB,gBAAgB,EAAE,OAAO;EACzB,mBAAmB,EAAE,OAAO;EAC5B,oBAAoB,EAAE,OAAO;CAC/B,CAAC;CACD,OAAO,EAAE,OAAO;CAChB,SAAS;CACT,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS;AAChE,CAAC;AAGD,MAAa,yBAAyB,EAAE,OAAO;CAC7C,iBAAiB,EAAE,OAAO,CAAC,CAAC,IAAI;CAChC,QAAQ,EAAE,OAAO;EAAE,MAAM,EAAE,OAAO;EAAG,SAAS,EAAE,OAAO;CAAE,CAAC;CAC1D,QAAQ,EAAE,MAAM,EAAE,KAAK,aAAa,CAAC;CACrC,SAAS,EAAE,MAAM,EAAE,KAAK,uBAAuB,CAAC;AAClD,CAAC;AAGgC,EAAE,OAAO,EACxC,SAAS,EAAE,MAAM,EAAE,OAAO;CAAE,MAAM,EAAE,OAAO;CAAG,UAAU;AAAiB,CAAC,CAAC,EAC7E,CAAC;AAGgC,EAAE,OAAO;CACxC,OAAO,EAAE,KAAK,CAAC,MAAM,MAAM,CAAC;CAC5B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;AAC3B,CAAC;AAGD,MAAM,mBAAmB,EAAE,OAAO;CAChC,UAAU,EAAE,QAAQ,KAAK;CACzB,QAAQ,EAAE,KAAK;EAAC;EAAY;EAAW;CAAQ,CAAC;CAChD,SAAS,EAAE,KAAK,CAAC,OAAO,OAAO,CAAC;AAClC,CAAC;AAED,MAAM,sBAAsB,EAAE,OAAO;CACnC,UAAU,EAAE,KAAK,CAAC,WAAW,KAAK,CAAC;CACnC,cAAc;AAChB,CAAC;AAEkC,EAAE,OAAO;CAC1C,QAAQ,EAAE,OAAO;CACjB,UAAU;CACV,SAAS,EAAE,mBAAmB,YAAY,CAAC,kBAAkB,mBAAmB,CAAC;CACjF,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS;AAC9D,CAAC;AAGD,MAAa,sBAAsB,EAAE,OAAO;CAC1C,QAAQ;CACR,UAAU,EAAE,KAAK,aAAa;CAC9B,KAAK,EAAE,OAAO;CACd,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;CACnD,cAAc,iBAAiB,SAAS;CACxC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;CACnC,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;AAC5B,CAAC;AAGoC,EAAE,OAAO;CAC5C,QAAQ,EAAE,OAAO;CACjB,UAAU;CACV,UAAU,EAAE,KAAK,CAAC,WAAW,KAAK,CAAC;CACnC,MAAM,EAAE,OAAO;CACf,QAAQ,EAAE,OAAO;CACjB,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY;AACrC,CAAC;AAGoC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAG9B,EAAE,OAAO;CAC1C,QAAQ;CACR,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;AAGkC,EAAE,OAAO;CAC1C,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,eAAe,EAAE,OAAO,CAAC,CAAC,SAAS;AACrC,CAAC;AAG8B,EAAE,OAAO;CACtC,QAAQ;CACR,SAAS,EAAE,KAAK;EAAC;EAAU;EAAU;EAAS;CAAW,CAAC;CAC1D,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS;AAC9B,CAAC;AAGkC,EAAE,OAAO,EAAE,QAAQ,aAAa,CAAC;AAGlC,EAAE,OAAO,EAAE,IAAI,gBAAgB,CAAC;AAG9B,EAAE,OAAO;CAC3C,IAAI;CACJ,SAAS,EAAE,OAAO;CAClB,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS;CAChD,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,SAAS;AAC/C,CAAC;AAGD,MAAa,wBAAwB,EAAE,OAAO;CAC5C,MAAM,EAAE,KAAK,oBAAoB;CACjC,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,QAAQ,aAAa,SAAS;CAC9B,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CAC9C,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;AAChD,CAAC;;ACtKD,MAAa,wBAAwB;AAErC,MAAM,oBAAoB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;AAE1C,MAAM,6BAA6B,EAAE,aAAa;CAChD,MAAM,EAAE,QAAQ,QAAQ;CACxB,MAAM,EAAE,QAAQ,SAAS;CACzB,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;CACpC,OAAO;CACP,QAAQ,EAAE,MAAM,EAAE,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS;CAChD,SAAS,EAAE,MAAM,EAAE,KAAK,uBAAuB,CAAC;CAChD,SAAS;CACT,UAAU;CACV,UAAU,EAAE,MAAM,EAAE,KAAK,gBAAgB,CAAC,CAAC,CAAC,SAAS;CACrD,OAAO,kBAAkB,SAAS;AACpC,CAAC;AAED,MAAM,0BAA0B,EAAE,aAAa;CAC7C,MAAM,EAAE,QAAQ,YAAY;CAC5B,MAAM,EAAE,QAAQ,YAAY;CAC5B,OAAO;CACP,SAAS,kBAAkB,SAAS;AACtC,CAAC;AAED,MAAM,8BAA8B,EAAE,aAAa;CACjD,MAAM,EAAE,QAAQ,gBAAgB;CAChC,MAAM,EAAE,QAAQ,YAAY;CAC5B,OAAO;CACP,SAAS,kBAAkB,SAAS;AACtC,CAAC;AAED,MAAa,uBAAuB,EAAE,mBAAmB,QAAQ;CAC/D;CACA;CACA;AACF,CAAC;;ACZD,MAAM,sBAAsB;AAC5B,MAAM,uBAAuB;AAE7B,SAAgB,eACd,YACsB;CACtB,MAAM,WAAW,qBAAqB,MAAM;EAC1C,UAAA;EACA,MAAM;EACN,MAAM;EACN,OAAO;EACP,QAAQ,CAAC,GAAG,WAAW,MAAM;EAC7B,SAAS,CAAC,GAAG,WAAW,OAAO;EAC/B,SAAS;EACT,UAAU;EACV,GAAI,WAAW,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,WAAW,QAAQ,EAAE;EAClF,GAAI,WAAW,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,WAAW,MAAM;CACtE,CAAC;CACD,IAAI,SAAS,SAAS,UAAU,MAAM,IAAI,MAAM,uCAAuC;CACvF,OAAO;AACT;;AC5CA,SAAgB,gBAAgB,SAAqC;CACnE,IAAI,MAAM;CACV,SAAS;EACP,IAAI,WAAW,KAAK,KAAK,cAAc,CAAC,GAAG,OAAO;EAClD,MAAM,SAAS,QAAQ,GAAG;EAC1B,IAAI,WAAW,KAAK,OAAO,KAAA;EAC3B,MAAM;CACR;AACF;AAEA,SAAgB,gBAAgB,aAA8C;CAC5E,MAAM,SAAkB,KAAK,MAAM,aAAa,KAAK,aAAa,cAAc,GAAG,MAAM,CAAC;CAC1F,OAAO,OAAO,WAAW,YAAY,WAAW,OAAQ,SAAqC,CAAC;AAChG;;AChBA,MAAM,cAAc;CAAC;CAAc;CAAe;CAAY;AAAW;AAEzE,MAAa,2BAA2B;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA,GAAG;CACH,GAAG,YAAY,KAAK,SAAS,KAAK,YAAY,CAAC;CAC/C;CACA;AACF;AAEA,MAAa,mCAAmC;CAC9C;CACA;CACA;CACA;CACA;CACA;AACF;AAGA,SAAgB,kBACd,KACA,UACwB;CACxB,MAAM,UAAU,aAAa;CAC7B,MAAM,QAAQ,IAAI,IAAY,wBAAwB;CACtD,IAAI,SACF,KAAK,MAAM,QAAQ,kCAAkC,MAAM,IAAI,KAAK,YAAY,CAAC;CAEnF,MAAM,UAAU,QAAyB;EACvC,IAAI,IAAI,WAAW,KAAK,GAAG,OAAO;EAClC,IAAI,MAAM,IAAI,GAAG,GAAG,OAAO;EAE3B,OAAO,WAAW,MAAM,IAAI,IAAI,YAAY,CAAC;CAC/C;CACA,MAAM,MAA8B,CAAC;CACrC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GAAG,GAAG;EAC9C,IAAI,UAAU,KAAA,KAAa,IAAI,YAAY,MAAM,gBAAgB;EACjE,IAAI,OAAO,GAAG,GAAG,IAAI,OAAO;CAC9B;CACA,OAAO;AACT;;AC/CA,SAAgB,cAAc,SAA0B;CACtD,OAAO,GAAG,KAAK,UAAU,OAAO,EAAE;AACpC;AAaA,MAAM,UAAU;AAEhB,SAAgB,kBAAkB,EAChC,cACA,QACA,cACkC;CAClC,MAAM,UAAU,IAAI,YAAY;CAChC,MAAM,UAAU,IAAI,YAAY;CAChC,IAAI,QAAsB,CAAC;CAC3B,IAAI,OAAO;CACX,IAAI,aAAa;CAEjB,MAAM,UAAU,YAAwB;EACtC,IAAI,cAAc,QAAQ,WAAW,GAAG;EACxC,IAAI,OAAO,QAAQ,SAAS,cAAc;GACxC,aAAa;GACb,QAAQ,CAAC;GACT,OAAO;GACP,WAAW;GACX;EACF;EACA,MAAM,KAAK,IAAI,WAAW,OAAO,CAAC;EAClC,QAAQ,QAAQ;CAClB;CAEA,MAAM,mBAAmB;EACvB,MAAM,gBAAgB;EACtB,MAAM,YAAY;EAClB,MAAM,WAAW;EACjB,QAAQ,CAAC;EACT,OAAO;EACP,aAAa;EACb,IAAI,iBAAiB,aAAa,GAAG;EACrC,MAAM,QAAQ,IAAI,WAAW,QAAQ;EACrC,IAAI,SAAS;EACb,KAAK,MAAM,QAAQ,WAAW;GAC5B,MAAM,IAAI,MAAM,MAAM;GACtB,UAAU,KAAK;EACjB;EACA,MAAM,OAAO,QAAQ,OAAO,KAAK,CAAC,CAAC,QAAQ,OAAO,EAAE;EACpD,IAAI,KAAK,KAAK,MAAM,IAAI,OAAO,IAAI;CACrC;CAEA,OAAO;EACL,KAAK,OAAO;GACV,MAAM,QAAQ,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK,IAAI;GAClE,IAAI,QAAQ;GACZ,OAAO,SAAS,MAAM,QAAQ;IAC5B,MAAM,UAAU,MAAM,QAAQ,SAAS,KAAK;IAC5C,IAAI,YAAY,IAAI;KAClB,OAAO,MAAM,SAAS,KAAK,CAAC;KAC5B;IACF;IACA,OAAO,MAAM,SAAS,OAAO,OAAO,CAAC;IACrC,WAAW;IACX,QAAQ,UAAU;GACpB;EACF;EACA,MAAM;GACJ,WAAW;EACb;CACF;AACF;;ACpBA,MAAM,0BAA0B;AAChC,MAAM,0BAA0B;AAChC,MAAM,iBAAiB;AACvB,MAAM,iBAAiB;AACvB,MAAM,gBAAgB;AACtB,MAAM,kBAA4C;CAChD,UAAU;CACV,QAAQ;CACR,SAAS;AACX;AAOA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,UAAU,OAAwB;CACzC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,SAAS,aAAqB;CAC5B,MAAM,OAAO,gBAAgB,QAAQ,cAAc,YAAY,GAAG,CAAC,CAAC;CACpE,MAAM,UAAU,SAAS,KAAA,IAAY,KAAA,IAAY,gBAAgB,IAAI,CAAC,CAAC;CACvE,OAAO,OAAO,YAAY,WAAW,UAAU;AACjD;AAEA,SAAS,aAAa,MAA0D;CAC9E,OAAO;EACL,KAAK,QAAQ;EACb,gBAAgB,WAAW;EAC3B,mBAAmB;EACnB,oBAAoB;EACpB,GAAG;CACL;AACF;AAEA,SAAS,kBAAkB,YAA6B;CACtD,MAAM,SAAkB,KAAK,MAAM,aAAa,KAAK,YAAY,cAAc,GAAG,MAAM,CAAC;CACzF,MAAM,QAAQ,SAAS,MAAM,IAAI,OAAO,yBAAyB,KAAA;CACjE,OAAO,SAAS,KAAK,IAAI,MAAM,SAAS,KAAA;AAC1C;AAEA,SAAS,cAAc,aAAqB,MAAkC;CAC5E,MAAM,SAAS,KAAK,aAAa,IAAI;CACrC,IAAI,CAAC,WAAW,MAAM,GAAG,OAAO,KAAA;CAChC,MAAM,OAAO,aAAa,MAAM;CAChC,MAAM,WAAW,SAAS,aAAa,IAAI;CAC3C,IAAI,aAAa,QAAQ,SAAS,WAAW,KAAK,KAAK,KAAK,WAAW,QAAQ,GAAG,OAAO,KAAA;CACzF,OAAO;AACT;AAQA,SAAS,cAAc,YAAqC;CAC1D,MAAM,UAAU,YAAqC,EACnD,OAAO;EAAE,MAAM;EAAY,IAAI;EAAO;CAAO,EAC/C;CACA,IAAI;CACJ,IAAI;CACJ,IAAI;EACF,cAAc,aAAa,UAAU;EACrC,QAAQ,kBAAkB,WAAW;CACvC,SAAS,OAAO;EACd,OAAO,OAAO,mCAAmC,UAAU,KAAK,GAAG;CACrE;CACA,IAAI,UAAU,KAAA,GAAW,OAAO,OAAO,uBAAuB,sBAAsB,QAAQ;CAC5F,MAAM,SAAS,qBAAqB,UAAU,KAAK;CACnD,IAAI,CAAC,OAAO,SACV,OAAO,OACL,OAAO,MAAM,OACV,KACE,UACC,GAAG;EAAC;EAAuB;EAAU,GAAG,MAAM,KAAK,IAAI,MAAM;CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,IAAI,MAAM,SACxF,CAAC,CACA,KAAK,IAAI,CACd;CAEF,MAAM,WAAW,OAAO;CACxB,IAAI,SAAS,SAAS,UACpB,OAAO,OAAO,6DAA6D,SAAS,MAAM;CAG5F,MAAM,WAAqB,CAAC;CAC5B,MAAM,YAAY,KAAiD,SAAiB;EAClF,MAAM,OAAO,cAAc,aAAa,IAAI;EAC5C,IAAI,SAAS,KAAA,GAAW,SAAS,KAAK,GAAG,IAAI,GAAG,KAAK,qCAAqC;EAC1F,OAAO;CACT;CACA,MAAM,QAAQ,SAAS,SAAS,SAAS,KAAK;CAC9C,KAAK,MAAM,OAAO,CAAC,WAAW,UAAU,GAAY;EAClD,MAAM,OAAO,SAAS,KAAK,SAAS,IAAI;EACxC,IAAI,SAAS,KAAA,GAAW;EACxB,IAAI;GACF,MAAM,SAAkB,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC;GAC7D,IAAI,CAAC,SAAS,MAAM,KAAK,OAAO,OAAO,YAAY,UACjD,SAAS,KAAK,GAAG,IAAI,GAAG,SAAS,KAAK,kBAAkB;QACnD,IAAI,CAAC,cAAc,KAAK,OAAO,OAAO,GAC3C,SAAS,KAAK,GAAG,IAAI,GAAG,SAAS,KAAK,MAAM,OAAO,QAAQ,gCAAgC;EAE/F,SAAS,OAAO;GACd,SAAS,KAAK,GAAG,IAAI,GAAG,SAAS,KAAK,gBAAgB,UAAU,KAAK,GAAG;EAC1E;CACF;CACA,IAAI,SAAS,UAAU,KAAA,GAAW,SAAS,SAAS,SAAS,KAAK;CAClE,IAAI,SAAS,SAAS,GAAG,OAAO,OAAO,SAAS,KAAK,IAAI,CAAC;CAC1D,OAAO;EAAE,OAAO;GAAE,MAAM;GAAY,IAAI;EAAK;EAAG;EAAU,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;CAAG;AACxF;AAcA,SAAS,OAAU,SAAqB,IAAY,MAA0B;CAC5E,IAAI;CACJ,MAAM,UAAU,IAAI,SAAgB,GAAG,WAAW;EAChD,QAAQ,iBAAiB,uBAAO,IAAI,MAAM,GAAG,KAAK,wBAAwB,GAAG,IAAI,CAAC,GAAG,EAAE;CACzF,CAAC;CACD,OAAO,QAAQ,KAAK,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,cAAc,aAAa,KAAK,CAAC;AAC3E;AAEA,SAAS,YAAY,OAAe,KAA4B;CAC9D,MAAM,QAAQ,MAAM,QAAQ,UAAU,CAAC,KAAK,GAAG;EAC7C;EACA,KAAK,kBAAkB,QAAQ,KAAK,QAAQ,QAAQ;EACpD,OAAO;GAAC;GAAQ;GAAQ;EAAM;CAChC,CAAC;CACD,MAAM,0BAAU,IAAI,IAAyC;CAC7D,MAAM,WAAqB,CAAC;CAC5B,IAAI,SAAS;CACb,IAAI,WAA0B;CAC9B,IAAI,SAAS;CACb,MAAM,MAAM,GAAG,eAAe,CAAC,CAAC;CAChC,MAAM,OAAO,GAAG,SAAS,UAAkB;EACzC,UAAU,MAAM,SAAS;CAC3B,CAAC;CACD,MAAM,UAAU,kBAAkB;EAChC,cAAc;EACd,SAAS,SAAS;GAChB,IAAI;GACJ,IAAI;IACF,UAAU,KAAK,MAAM,IAAI;GAC3B,QAAQ;IACN,SAAS,KAAK,IAAI;IAClB;GACF;GACA,IAAI,CAAC,SAAS,OAAO,KAAK,QAAQ,YAAY,OAAO;IACnD,SAAS,KAAK,IAAI;IAClB;GACF;GACA,MAAM,UAAU,OAAO,QAAQ,OAAO,WAAW,QAAQ,IAAI,QAAQ,EAAE,IAAI,KAAA;GAC3E,IAAI,YAAY,KAAA,KAAa,OAAO,QAAQ,OAAO,UAAU;GAC7D,QAAQ,OAAO,QAAQ,EAAE;GACzB,QAAQ,OAAoB;EAC9B;EACA,kBAAkB,SAAS,KAAK,sBAAsB,kBAAkB,OAAO;CACjF,CAAC;CACD,MAAM,OAAO,GAAG,SAAS,UAAkB,QAAQ,KAAK,KAAK,CAAC;CAC9D,MAAM,OAAO,IAAI,SAAwB,YACvC,MAAM,GAAG,SAAS,SAAS;EACzB,SAAS;EACT,WAAW;EACX,QAAQ,IAAI;CACd,CAAC,CACH;CAEA,MAAM,SAAS,IAAI,SAAe,YAAY,MAAM,GAAG,eAAe,QAAQ,CAAC,CAAC;CAChF,IAAI,OAAO;CAEX,MAAM,SAAwB;EAC5B,KAAK,QAAQ,QAAQ;GACnB,QAAQ;GACR,MAAM,KAAK;GACX,MAAM,WAAW,IAAI,SAAoB,SAAS,WAAW;IAC3D,QAAQ,IAAI,IAAI,OAAO;IACvB,KAAU,MAAM,SAAS;KACvB,MAAM,SAAS,OAAO,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM;KAC/C,uBAAO,IAAI,MAAM,0BAA0B,KAAK,oBAAoB,OAAO,GAAG,QAAQ,CAAC;IACzF,CAAC;GACH,CAAC;GACD,SAAS,YAAY,CAAC,CAAC;GACvB,MAAM,MAAM,MAAM,cAAc;IAAE,SAAS;IAAO;IAAI;IAAQ;GAAO,CAAC,CAAC;GACvE,OAAO;IAAE;IAAI;GAAS;EACxB;EACA,QAAQ,QAAQ,QAAQ,WAAW;GACjC,OAAO,OAAO,OAAO,KAAK,QAAQ,MAAM,CAAC,CAAC,UAAU,WAAW,MAAM;EACvE;EACA,OAAO,QAAQ,QAAQ;GACrB,MAAM,MAAM,MAAM,cAAc;IAAE,SAAS;IAAO;IAAQ;GAAO,CAAC,CAAC;EACrE;EACA,iBAAiB;GACf,OAAO,CAAC,GAAG,QAAQ;EACrB;EACA,aAAa;GACX,MAAM,MAAM,IAAI;EAClB;EACA,MAAM,aAAa,IAAI;GACrB,IAAI,QAAQ,OAAO;IAAE,QAAQ;IAAM,MAAM;GAAS;GAClD,IAAI;IAEF,OAAO;KAAE,QAAQ;KAAM,MAAA,MADJ,OAAO,MAAM,IAAI,MAAM;IACd;GAC9B,QAAQ;IACN,OAAO;KAAE,QAAQ;KAAO,MAAM;IAAK;GACrC;EACF;EACA,MAAM,QAAQ,IAAI;GAChB,MAAM,OAAO,QAAQ,IAAI,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC;GACjD,QAAQ,IAAI;EACd;EACA,YAAY;GACV,OAAO;EACT;EACA,OAAO;GACL,IAAI,CAAC,QAAQ,MAAM,KAAK,SAAS;EACnC;CACF;CACA,OAAO;AACT;AAEA,SAAS,cAAc,QAA2B;CAChD,IAAI,OAAO,UAAU,KAAA,GAAW,OAAO,YAAY,KAAK,UAAU,OAAO,MAAM;CAC/E,MAAM,OAAO,sBAAsB,UAAU,OAAO,MAAM,IAAI;CAC9D,MAAM,OAAO,KAAK,UAAU,UAAU,KAAK,KAAK,KAAK,KAAK;CAC1D,OAAO,YAAY,OAAO,MAAM,KAAK,IAAI,OAAO,MAAM,UAAU;AAClE;AAEA,SAAS,YAAY,QAA4B;CAC/C,MAAM,OAAO,OAAO,OAAO;CAC3B,OAAO,SAAS,IAAI,IAAI,KAAK,SAAS,KAAA;AACxC;AAEA,eAAe,eACb,QACA,UACA,OACA,WAC2B;CAC3B,MAAM,OAAO;CACb,IAAI;CACJ,IAAI;EACF,SAAS,MAAM,OAAO,QACpB,cACA;GACE,kBAAkB,CAAA,CAAwB;GAC1C,MAAM,aAAa,MAAM,IAAI;GAC7B,OAAO;GACP,SAAS,MAAM;EACjB,GACA,SACF;CACF,SAAS,OAAO;EACd,OAAO;GAAE;GAAM,IAAI;GAAO,QAAQ,UAAU,KAAK;EAAE;CACrD;CACA,IAAI,OAAO,UAAU,KAAA,GAAW;EAC9B,MAAM,UACJ,OAAO,MAAM,SAAS,mBAAmB,UACzC,OAAO,OAAO,MAAM,YAAY,YAChC,OAAO,MAAM,YAAY,MACzB,sBAAsB,UAAU,OAAO,MAAM,IAAI,CAAC,CAAC;EACrD,IAAI,MAAM,UAAU,QAAQ,SAC1B,OAAO;GAAE;GAAM,IAAI;GAAM,QAAQ,uBAAuB,cAAc,MAAM;EAAI;EAElF,OAAO;GAAE;GAAM,IAAI;GAAO,QAAQ,cAAc,cAAc,MAAM;EAAI;CAC1E;CACA,MAAM,SAAS,uBAAuB,UAAU,OAAO,MAAM;CAC7D,IAAI,CAAC,OAAO,SACV,OAAO;EACL;EACA,IAAI;EACJ,QAAQ,2CAA2C,OAAO,MAAM;CAClE;CAEF,MAAM,UAAU,WAA8B,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK;CAC/D,MAAM,WAAqB,CAAC;CAC5B,IAAI,OAAO,KAAK,oBAAA,GACd,SAAS,KAAK,YAAY,OAAO,KAAK,gBAAgB,QAAiC;CAEzF,IAAI,CAAC,kBAAkB,OAAO,OAAO,KAAK,MAAM,GAAG,OAAO,SAAS,MAAM,CAAC,GACxE,SAAS,KACP,UAAU,OAAO,KAAK,OAAO,KAAK,IAAI,EAAE,0BAA0B,SAAS,OAAO,KAAK,IAAI,GAC7F;CAEF,IAAI,CAAC,kBAAkB,OAAO,OAAO,KAAK,OAAO,GAAG,OAAO,SAAS,OAAO,CAAC,GAC1E,SAAS,KACP,WAAW,OAAO,KAAK,QAAQ,KAAK,IAAI,KAAK,OAAO,0BAA0B,SAAS,QAAQ,KAAK,IAAI,KAAK,QAC/G;CAEF,OAAO,SAAS,WAAW,IACvB;EAAE;EAAM,IAAI;CAAK,IACjB;EAAE;EAAM,IAAI;EAAO,QAAQ,uBAAuB,SAAS,KAAK,IAAI;CAAI;AAC9E;AAEA,eAAe,mBACb,QACA,WAC2B;CAC3B,MAAM,OAAO;CACb,IAAI;EACF,MAAM,SAAS,MAAM,OAAO,QAAQ,iBAAiB,CAAC,GAAG,SAAS;EAClE,OAAO,OAAO,OAAO,SAAS,mBAAmB,iBAC7C;GAAE;GAAM,IAAI;EAAK,IACjB;GACE;GACA,IAAI;GACJ,QAAQ,iBAAiB,cAAc,MAAM,EAAE,QAAQ,mBAAmB;EAC5E;CACN,SAAS,OAAO;EACd,OAAO;GAAE;GAAM,IAAI;GAAO,QAAQ,UAAU,KAAK;EAAE;CACrD;AACF;AAEA,eAAe,QAAQ,QAAuB,QAAiB,WAAmB;CAChF,OAAO,OAAO,QAAQ,WAAW,EAAE,OAAO,GAAG,SAAS;AACxD;AAEA,eAAe,uBACb,QACA,eACA,WAC2B;CAC3B,MAAM,OAAO;CACb,IAAI;EACF,MAAM,WAAW,MAAM,OAAO,QAAQ,WAAW,eAAe,SAAS;EACzE,IAAI,SAAS,UAAU,KAAA,GAAW;GAChC,MAAM,SAAS,YAAY,QAAQ;GACnC,IAAI,WAAW,KAAA,GAAW,MAAM,QAAQ,QAAQ,QAAQ,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC;GACjF,OAAO;IAAE;IAAM,IAAI;IAAO,QAAQ,WAAW,cAAc,QAAQ;GAAI;EACzE;EACA,MAAM,SAAS,oBAAoB,UAAU,SAAS,MAAM;EAC5D,IAAI,CAAC,OAAO,SACV,OAAO;GACL;GACA,IAAI;GACJ,QAAQ,wCAAwC,OAAO,MAAM;EAC/D;EAEF,KAAK,MAAM,WAAW,CAAC,SAAS,QAAQ,GAAG;GACzC,MAAM,WAAW,MAAM,QAAQ,QAAQ,OAAO,KAAK,QAAQ,SAAS;GACpE,IAAI,SAAS,UAAU,KAAA,KAAa,CAAC,kBAAkB,SAAS,QAAQ,CAAC,CAAC,GACxE,OAAO;IAAE;IAAM,IAAI;IAAO,QAAQ,OAAO,QAAQ,WAAW,cAAc,QAAQ;GAAI;EAE1F;EACA,OAAO;GAAE;GAAM,IAAI;EAAK;CAC1B,SAAS,OAAO;EACd,OAAO;GAAE;GAAM,IAAI;GAAO,QAAQ,UAAU,KAAK;EAAE;CACrD;AACF;AAEA,eAAe,oBACb,QACA,eACA,WAC2B;CAC3B,MAAM,OAAO;CACb,IAAI;EACF,MAAM,UAAU,OAAO,KAAK,WAAW,aAAa;EACpD,OAAO,OAAO,eAAe,EAAE,IAAI,QAAQ,GAAG,CAAC;EAC/C,MAAM,SAAS,MAAM,OAAO,QAAQ,UAAU,yBAAyB,qBAAqB;EAC5F,IAAI,OAAO,UAAU,KAAA,GAAW;GAC9B,MAAM,SAAS,oBAAoB,UAAU,OAAO,MAAM;GAC1D,IAAI,OAAO,SAAS,MAAM,QAAQ,QAAQ,OAAO,KAAK,QAAQ,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC;GACvF,OAAO,OAAO,UACV;IAAE;IAAM,IAAI;GAAK,IACjB;IAAE;IAAM,IAAI;IAAO,QAAQ;GAAkD;EACnF;EACA,MAAM,SAAS,YAAY,MAAM;EACjC,IAAI,WAAW,KAAA,GAAW,MAAM,QAAQ,QAAQ,QAAQ,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC;EACjF,OAAO,OAAO,MAAM,SAAS,mBAAmB,YAC5C;GAAE;GAAM,IAAI;EAAK,IACjB;GACE;GACA,IAAI;GACJ,QAAQ,uBAAuB,cAAc,MAAM,EAAE,oBAAoB,mBAAmB;EAC9F;CACN,SAAS,OAAO;EACd,OAAO;GAAE;GAAM,IAAI;GAAO,QAAQ,UAAU,KAAK;EAAE;CACrD;AACF;AAEA,eAAe,sBAAsB,QAAkD;CACrF,MAAM,OAAO;CACb,IAAI,OAAO,UAAU,GACnB,OAAO;EAAE;EAAM,IAAI;EAAO,QAAQ;CAA4C;CAEhF,OAAO,WAAW;CAClB,MAAM,EAAE,WAAW,MAAM,OAAO,aAAa,cAAc;CAC3D,OAAO,SACH;EAAE;EAAM,IAAI;CAAK,IACjB;EACE;EACA,IAAI;EACJ,QAAQ,gCAAgC,eAAe;CACzD;AACN;AAEA,eAAsB,eAAe,OAAqD;CACxF,MAAM,YAAY,MAAM,aAAa;CACrC,MAAM,UAAU,cAAc,MAAM,UAAU;CAC9C,MAAM,SAA6B,CAAC,QAAQ,KAAK;CACjD,IAAI,QAAQ,aAAa,KAAA,KAAa,QAAQ,UAAU,KAAA,GACtD,OAAO;EAAE,IAAI;EAAO;CAAO;CAG7B,MAAM,SAAS,YAAY,QAAQ,OAAO,MAAM,UAAU;CAC1D,IAAI;EACF,OAAO,KAAK,MAAM,eAAe,QAAQ,QAAQ,UAAU,OAAO,SAAS,CAAC;EAC5E,OAAO,KAAK,MAAM,mBAAmB,QAAQ,SAAS,CAAC;EACvD,IAAI,MAAM,UAAU,MAAM;GACxB,MAAM,gBAA+B;IACnC,QAAQ;IACR,UAAU,MAAM,YAAY,CAAC;IAC7B,SAAS,MAAM,WAAW;GAC5B;GACA,OAAO,KAAK,MAAM,uBAAuB,QAAQ,eAAe,SAAS,CAAC;GAC1E,OAAO,KAAK,MAAM,oBAAoB,QAAQ,eAAe,SAAS,CAAC;EACzE;EACA,MAAM,YAAY,MAAM,sBAAsB,MAAM;EACpD,IAAI,UAAU,IAAI,MAAM,OAAO,QAAQ,cAAc;EACrD,MAAM,UAAU,OAAO,eAAe;EACtC,OAAO,KACL,QAAQ,WAAW,IACf;GAAE,MAAM;GAAgB,IAAI;EAAK,IACjC;GACE,MAAM;GACN,IAAI;GACJ,QAAQ,kBAAkB,QAAQ,OAAO,6CAA6C,QAAQ,EAAE,EAAE,MAAM,GAAG,GAAG;EAChH,CACN;EACA,OAAO,KAAK,SAAS;CACvB,UAAU;EACR,OAAO,KAAK;CACd;CACA,OAAO;EAAE,IAAI,OAAO,OAAO,UAAU,MAAM,EAAE;EAAG;CAAO;AACzD;AAEA,SAAgB,sBAGd,YAAoB,YAAmE;CACvF,MAAM,WAAoC,EAAE,GAAG,eAAe,UAAU,EAAE;CAC1E,MAAM,QAAQ,kBAAkB,UAAU;CAC1C,MAAM,SAAkC,SAAS,KAAK,IAAI,QAAQ,CAAC;CAEnE,MAAM,YADO,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,QAAQ,GAAG,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KACzD,CAAC,CAAC,QAAQ,QAAQ,CAAC,kBAAkB,OAAO,MAAM,SAAS,IAAI,CAAC;CACrF,IAAI,UAAU,SAAS,GACrB,MAAM,IAAI,MACR,kBAAkB,sBAAsB,yCAAyC,UAAU,KAAK,IAAI,EAAE,4BACxG;AAEJ;;AC9dA,SAAS,UAAU,MAAwB;CACzC,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC,QAAQ,YAAY,YAAY,EAAE;AAC3D;AAEA,SAAS,QAAQ,KAAa,OAAqC;CACjE,MAAM,QAAQ,qBAAqB,KAAK,GAAG;CAC3C,IAAI,QAAQ,OAAO,KAAA,KAAa,MAAM,OAAO,KAAA,GAC3C,MAAM,IAAI,MAAM,4CAA4C,IAAI,EAAE;CAEpE,IAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAC3C,MAAM,IAAI,MAAM,uBAAuB,IAAI,iBAAiB;CAE9D,OAAO;EAAE;EAAK,QAAQ,MAAM;EAAI,UAAU,UAAU,MAAM,EAAE;EAAG;EAAO,OAAO,CAAC;CAAE;AAClF;AAEA,SAAS,cAAc,SAAyB;CAC9C,IAAI;EACF,OAAO,mBAAmB,OAAO;CACnC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,YAAY,OAAsB,QAAgB,MAAc;CACvE,IAAI,MAAM,WAAW,QAAQ,OAAO,KAAA;CACpC,MAAM,WAAW,UAAU,IAAI;CAC/B,IAAI,SAAS,WAAW,MAAM,SAAS,QAAQ,OAAO,KAAA;CACtD,MAAM,SAAiC,CAAC;CACxC,KAAK,MAAM,CAAC,OAAO,aAAa,MAAM,SAAS,QAAQ,GAAG;EACxD,MAAM,SAAS,SAAS,UAAU;EAClC,IAAI,SAAS,WAAW,GAAG,GAAG,OAAO,SAAS,MAAM,CAAC,KAAK,cAAc,MAAM;OACzE,IAAI,aAAa,QAAQ,OAAO,KAAA;CACvC;CACA,OAAO;AACT;AAEA,SAAS,kBAAkB,SAAkD;CAC3E,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,OAAO,GAAG;EAC3D,IAAI,UAAU,KAAA,GAAW;EACzB,QAAQ,KAAK,YAAY,KAAK,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,IAAI;CAC1E;CACA,OAAO;AACT;AAEA,SAAS,UAAU,MAAuB;CACxC,IAAI,KAAK,WAAW,GAAG,OAAO,KAAA;CAC9B,IAAI;EACF,OAAO,KAAK,MAAM,IAAI;CACxB,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,KAAK,UAA0B,OAA6C;CACnF,MAAM,CAAC,aAAa,QAClB,MAAM,SAAS,KAAA,IACX,CAAC,mCAAmC,KAAK,UAAU,MAAM,IAAI,CAAC,IAC9D,CAAC,6BAA6B,MAAM,QAAQ,EAAE;CACpD,SAAS,UAAU,MAAM,QAAQ;EAC/B,gBAAgB;EAChB,kBAAkB,OAAO,WAAW,IAAI;EACxC,GAAG,MAAM;CACX,CAAC;CACD,SAAS,IAAI,IAAI;AACnB;AAEA,eAAsB,kBAAkB,OAAiD;CACvF,MAAM,SAAS,OAAO,QAAQ,MAAM,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,QAAQ,KAAK,KAAK,CAAC;CACrF,MAAM,WAA8B,CAAC;CACrC,MAAM,0BAAU,IAAI,IAAY;CAChC,IAAI;CAEJ,MAAM,UAAU,QAAyB,aAA6B;EACpE,KAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,SAAS,YAAY,OAAO,OAAO,QAAQ,OAAO,IAAI;GAC5D,IAAI,WAAW,KAAA,GAAW;GAC1B,MAAM,UAAU;IAAE,GAAG;IAAQ;GAAO;GACpC,SAAS,KAAK,OAAO;GACrB,MAAM,MAAM,KAAK,OAAO;GACxB,MAAM,QACJ,OAAO,MAAM,UAAU,aACnB,MAAM,MAAM,OAAO,IAClB,MAAM,MAAM,KAAK,IAAI,MAAM,MAAM,QAAQ,MAAM,MAAM,MAAM,IAAI,MAAM;GAC5E,IAAI,UAAU,QAAQ,KAAK,UAAU,KAAK;GAC1C;EACF;EACA,SAAS,KAAK,MAAM;EACpB,KAAK,UAAU;GAAE,QAAQ;GAAK,MAAM,EAAE,SAAS,WAAW;EAAE,CAAC;CAC/D;CAEA,MAAM,SAAS,cAAc,SAAS,aAAa;EACjD,MAAM,SAAmB,CAAC;EAC1B,QAAQ,GAAG,SAAS,UAAkB,OAAO,KAAK,KAAK,CAAC;EACxD,QAAQ,GAAG,aAAa;GACtB,MAAM,MAAM,IAAI,IAAI,QAAQ,OAAO,KAAK,kBAAkB;GAC1D,MAAM,SAA0B;IAC9B,QAAQ,QAAQ,UAAU;IAC1B,MAAM,IAAI;IACV,OAAO,OAAO,YAAY,IAAI,YAAY;IAC1C,QAAQ,CAAC;IACT,SAAS,kBAAkB,OAAO;IAClC,MAAM,UAAU,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC;GACxD;GACA,IAAI;IACF,OAAO,QAAQ,QAAQ;GACzB,SAAS,OAAO;IAEd,iBAAiB;IACjB,IAAI,CAAC,SAAS,aACZ,KAAK,UAAU;KAAE,QAAQ;KAAK,MAAM,EAAE,SAAS,oBAAoB,OAAO,KAAK,IAAI;IAAE,CAAC;GAE1F;EACF,CAAC;CACH,CAAC;CACD,OAAO,GAAG,eAAe,WAAmB;EAC1C,QAAQ,IAAI,MAAM;EAClB,OAAO,GAAG,eAAe,QAAQ,OAAO,MAAM,CAAC;CACjD,CAAC;CACD,MAAM,IAAI,SAAe,OAAO,WAAW;EACzC,OAAO,KAAK,SAAS,MAAM;EAC3B,OAAO,OAAO,GAAG,mBAAmB,MAAM,CAAC;CAC7C,CAAC;CACD,MAAM,EAAE,SAAS,OAAO,QAAQ;CAChC,MAAM,SAAS,oBAAoB,OAAO,IAAI;CAC9C,IAAI;CAEJ,OAAO;EACL,KAAK;EACL;EACA;EACA,WAAW,KAAK;GACd,OAAO,CAAC,GAAI,OAAO,MAAM,UAAU,MAAM,QAAQ,GAAG,CAAC,EAAE,SAAS,CAAC,CAAE;EACrE;EACA,QAAQ;GACN,YAAY,IAAI,SAAe,QAAQ,WAAW;IAChD,KAAK,MAAM,UAAU,SAAS,OAAO,QAAQ;IAC7C,OAAO,YAAa,iBAAiB,KAAA,IAAY,OAAO,IAAI,OAAO,YAAY,CAAE;GACnF,CAAC;GACD,OAAO;EACT;CACF;AACF;;ACzJA,MAAM,qBAAqB;CACzB,SAAS;CACT,MAAM;AACR;AAEA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;AAsBd,SAAS,mBAA2B;CAClC,MAAM,UAAU,gBAAgB,QAAQ,cAAc,YAAY,GAAG,CAAC,CAAC;CACvE,MAAM,OAAO,YAAY,KAAA,IAAY,KAAA,IAAY,KAAK,SAAS,QAAQ,oBAAoB;CAC3F,IAAI,SAAS,KAAA,KAAa,CAAC,WAAW,IAAI,GACxC,MAAM,IAAI,MAAM,2EAA2E;CAE7F,OAAO;AACT;AAEA,SAAgB,oBAAoB,KAAa,QAA6B,CAAC,GAAmB;CAChG,MAAM,WAAW,qBAAqB,MAAM;EAC1C,MAAM;EACN,MAAM;EACN,UAAA;EACA,OAAO;EACP,QAAQ,CAAC,GAAI,MAAM,UAAU,aAAc;EAC3C,SAAS,CAAC,GAAI,MAAM,WAAW,uBAAwB;EACvD,SAAS;EACT,UAAU;EACV,GAAI,MAAM,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,MAAM,QAAQ,EAAE;EACxE,OAAO;CACT,CAAC;CACD,MAAM,cAAc;EAClB,MAAM,MAAM,eAAe;EAC3B,SAAS,MAAM,WAAW;EAC1B,SAAS;EACT,MAAM;EACN,UAAU,CAAC,iBAAiB;EAC5B,SAAS,EAAE,kBAAkB,iBAAiB;GAC7C,wBAAwB,EAAE,QAAQ,SAAS;CAC9C;CACA,MAAM,UAAU,cAAc,iBAAiB,CAAC,CAAC,CAAC;CAElD,UAAU,KAAK,KAAK,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;CACjD,cAAc,KAAK,KAAK,cAAc,GAAG,GAAG,KAAK,UAAU,aAAa,MAAM,CAAC,EAAE,GAAG;CACpF,MAAM,aAAa,GAAG,KAAK,UAAU,oBAAoB,MAAM,CAAC,EAAE;CAClE,cAAc,KAAK,KAAK,qBAAqB,GAAG,UAAU;CAC1D,cAAc,KAAK,KAAK,sBAAsB,GAAG,UAAU;CAC3D,cAAc,KAAK,KAAK,SAAS,UAAU,GAAG,KAAK;CACnD,MAAM,SAAS;EACb,GAAI,MAAM,QAAQ,wBAAwB,KAAA,IACtC,CAAC,IACD,EAAE,qBAAqB,MAAM,OAAO,oBAAoB;EAC5D,GAAI,MAAM,QAAQ,kBAAkB,KAAA,IAChC,CAAC,IACD,EAAE,eAAe,MAAM,OAAO,cAAc;CAClD;CACA,cACE,KAAK,KAAK,UAAU,GACpB,uCAAuC,KAAK,UAAU,OAAO,EAAE,0BAA0B,KAAK,UAAU,MAAM,EAAE,IAClH;CACA,OAAO;EAAE;EAAK,OAAO,KAAK,KAAK,UAAU;CAAE;AAC7C"}
package/package.json CHANGED
@@ -1,6 +1,83 @@
1
1
  {
2
2
  "name": "@vostride/agent-qa-plugin-kit",
3
- "version": "0.0.1",
4
- "main": "index.js",
5
- "files": []
3
+ "version": "0.3.1",
4
+ "private": false,
5
+ "description": "Build agent-qa plugins: the protocol, definePlugin, the stdio loop and a conformance suite.",
6
+ "keywords": [
7
+ "agent-qa",
8
+ "agent-qa-plugin"
9
+ ],
10
+ "license": "FSL-1.1-ALv2",
11
+ "homepage": "https://github.com/vostride/agent-qa#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/vostride/agent-qa/issues"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/vostride/agent-qa.git",
18
+ "directory": "packages/plugin-kit"
19
+ },
20
+ "engines": {
21
+ "node": ">=24"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public",
25
+ "registry": "https://registry.npmjs.org/"
26
+ },
27
+ "type": "module",
28
+ "exports": {
29
+ ".": {
30
+ "import": {
31
+ "types": "./dist/index.d.ts",
32
+ "default": "./dist/index.js"
33
+ },
34
+ "require": {
35
+ "types": "./dist/index.d.cts",
36
+ "default": "./dist/index.cjs"
37
+ }
38
+ },
39
+ "./protocol": {
40
+ "import": {
41
+ "types": "./dist/protocol.d.ts",
42
+ "default": "./dist/protocol.js"
43
+ },
44
+ "require": {
45
+ "types": "./dist/protocol.d.cts",
46
+ "default": "./dist/protocol.cjs"
47
+ }
48
+ },
49
+ "./testing": {
50
+ "import": {
51
+ "types": "./dist/testing.d.ts",
52
+ "default": "./dist/testing.js"
53
+ },
54
+ "require": {
55
+ "types": "./dist/testing.d.cts",
56
+ "default": "./dist/testing.cjs"
57
+ }
58
+ },
59
+ "./package.json": "./package.json"
60
+ },
61
+ "files": [
62
+ "dist",
63
+ "LICENSE.md",
64
+ "NOTICE.md"
65
+ ],
66
+ "scripts": {
67
+ "build": "tsdown",
68
+ "dev": "tsdown --watch",
69
+ "test": "vitest run",
70
+ "typecheck": "tsc --noEmit",
71
+ "clean": "rm -rf dist .turbo"
72
+ },
73
+ "dependencies": {
74
+ "zod": "4.6.7"
75
+ },
76
+ "devDependencies": {
77
+ "@types/node": "~24.19.2",
78
+ "@vostride/agent-qa-arch": "0.3.1",
79
+ "tsdown": "~0.23.4",
80
+ "typescript": "~7.0.2",
81
+ "vitest": "~5.0.5"
82
+ }
6
83
  }