@revealui/harnesses 0.1.1 → 0.1.3

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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts","../src/adapters/claude-code-adapter.ts","../src/adapters/copilot-adapter.ts","../src/adapters/cursor-adapter.ts","../src/config/config-sync.ts","../src/config/harness-config-paths.ts","../src/coordinator.ts","../src/detection/auto-detector.ts","../src/registry/harness-registry.ts","../src/server/rpc-server.ts","../src/detection/process-detector.ts"],"sourcesContent":["/**\n * @revealui/harnesses — AI Harness Integration System (Server-side)\n *\n * Adapters, registry, workboard coordination, and JSON-RPC server for\n * integrating AI coding tools (Claude Code, Cursor, Copilot) into the\n * RevealUI development workflow.\n *\n * Pro tier feature: gated behind isFeatureEnabled(\"ai\").\n *\n * @packageDocumentation\n */\n\nimport { isFeatureEnabled } from '@revealui/core/features'\nimport { initializeLicense } from '@revealui/core/license'\nimport { logger } from '@revealui/core/observability/logger'\n\n/** Check whether the harnesses feature is licensed for this installation. */\nexport async function checkHarnessesLicense(): Promise<boolean> {\n await initializeLicense()\n if (!isFeatureEnabled('ai')) {\n logger.warn(\n '[@revealui/harnesses] AI harness integration requires a Pro or Enterprise license. ' +\n 'Visit https://revealui.com/pricing for details.',\n { feature: 'ai' },\n )\n return false\n }\n return true\n}\n\n// Adapters\nexport { ClaudeCodeAdapter } from './adapters/claude-code-adapter.js'\nexport { CopilotAdapter } from './adapters/copilot-adapter.js'\nexport { CursorAdapter } from './adapters/cursor-adapter.js'\n\n// Config\nexport {\n diffAllConfigs,\n diffConfig,\n syncAllConfigs,\n syncConfig,\n validateConfigJson,\n} from './config/config-sync.js'\nexport {\n getConfigurableHarnesses,\n getLocalConfigPath,\n getRootConfigPath,\n} from './config/harness-config-paths.js'\nexport type { CoordinatorOptions } from './coordinator.js'\n// Coordinator\nexport { HarnessCoordinator } from './coordinator.js'\n\n// Detection\nexport { autoDetectHarnesses } from './detection/auto-detector.js'\nexport {\n findAllHarnessProcesses,\n findClaudeCodeSockets,\n findHarnessProcesses,\n findProcesses,\n} from './detection/process-detector.js'\n\n// Registry\nexport { HarnessRegistry } from './registry/harness-registry.js'\n\n// Server\nexport { RpcServer } from './server/rpc-server.js'\nexport type { HarnessAdapter } from './types/adapter.js'\n\n// Types — harness core\nexport type {\n ConfigDiffEntry,\n ConfigSyncDirection,\n ConfigSyncResult,\n HarnessCapabilities,\n HarnessCommand,\n HarnessCommandResult,\n HarnessEvent,\n HarnessInfo,\n HarnessProcessInfo,\n HealthCheckResult,\n} from './types/core.js'\n// Workboard\nexport {\n acquireLock,\n atomicWriteSync,\n deriveSessionId,\n detectSessionType,\n lockPathFor,\n releaseLock,\n withLock,\n withLockAsync,\n WorkboardManager,\n} from './workboard/index.js'\n// Types — session identity\nexport type { SessionType } from './workboard/session-identity.js'\n// Types — workboard protocol\nexport type {\n ConflictResult,\n WorkboardEntry,\n WorkboardSession,\n WorkboardState,\n} from './workboard/workboard-protocol.js'\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport type { HarnessAdapter } from '../types/adapter.js'\nimport type {\n HarnessCapabilities,\n HarnessCommand,\n HarnessCommandResult,\n HarnessEvent,\n HarnessInfo,\n} from '../types/core.js'\nimport { WorkboardManager } from '../workboard/workboard-manager.js'\n\nconst execFileAsync = promisify(execFile)\n\n/**\n * Adapter for Anthropic Claude Code (CLI: `claude`).\n *\n * Claude Code communicates via its CLI. Config lives at\n * ~/.claude/settings.json and project-level .claude/settings.json.\n * MCP integration is handled separately by @revealui/mcp.\n *\n * Workboard read/write requires REVEALUI_WORKBOARD_PATH to be set to the\n * absolute path of the workboard.md file.\n */\nexport class ClaudeCodeAdapter implements HarnessAdapter {\n readonly id = 'claude-code'\n readonly name = 'Claude Code'\n\n private readonly eventHandlers = new Set<(event: HarnessEvent) => void>()\n private readonly workboardPath: string | undefined\n\n constructor(workboardPath?: string) {\n this.workboardPath = workboardPath ?? process.env.REVEALUI_WORKBOARD_PATH\n }\n\n getCapabilities(): HarnessCapabilities {\n return {\n generateCode: false, // interactive only — no headless CLI interface\n analyzeCode: false, // interactive only — no headless CLI interface\n applyEdit: false, // interactive only — edits are applied inside Claude Code sessions\n applyConfig: false, // config managed interactively via ~/.claude/settings.json\n readWorkboard: this.workboardPath !== undefined,\n writeWorkboard: this.workboardPath !== undefined,\n }\n }\n\n async getInfo(): Promise<HarnessInfo> {\n let version: string | undefined\n try {\n const { stdout } = await execFileAsync('claude', ['--version'], {\n timeout: 5000,\n })\n version = stdout.trim().split('\\n')[0]\n } catch {\n // Not installed or version flag unsupported.\n }\n return { id: this.id, name: this.name, version, capabilities: this.getCapabilities() }\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n await execFileAsync('claude', ['--version'], { timeout: 3000 })\n return true\n } catch {\n return false\n }\n }\n\n notifyRegistered(): void {\n this.emit({ type: 'harness-connected', harnessId: this.id })\n }\n\n notifyUnregistering(): void {\n this.emit({ type: 'harness-disconnected', harnessId: this.id })\n }\n\n async execute(command: HarnessCommand): Promise<HarnessCommandResult> {\n try {\n return await this.executeInner(command)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n this.emit({ type: 'error', harnessId: this.id, message })\n return { success: false, command: command.type, message }\n }\n }\n\n private async executeInner(command: HarnessCommand): Promise<HarnessCommandResult> {\n switch (command.type) {\n case 'get-status': {\n const available = await this.isAvailable()\n return { success: true, command: command.type, data: { available } }\n }\n case 'get-running-instances': {\n // Claude Code process enumeration is not supported.\n return { success: true, command: command.type, data: [] }\n }\n case 'generate-code':\n case 'analyze-code': {\n return {\n success: false,\n command: command.type,\n message: `${command.type} is not supported — Claude Code operates interactively`,\n }\n }\n case 'apply-config': {\n return {\n success: false,\n command: command.type,\n message: 'Config is managed interactively via ~/.claude/settings.json',\n }\n }\n case 'read-workboard': {\n if (!this.workboardPath) {\n return {\n success: false,\n command: command.type,\n message: 'REVEALUI_WORKBOARD_PATH is not set',\n }\n }\n const manager = new WorkboardManager(this.workboardPath)\n const state = await manager.readAsync()\n return { success: true, command: command.type, data: state }\n }\n case 'update-workboard': {\n if (!this.workboardPath) {\n return {\n success: false,\n command: command.type,\n message: 'REVEALUI_WORKBOARD_PATH is not set',\n }\n }\n const manager = new WorkboardManager(this.workboardPath)\n manager.updateSession(command.sessionId, {\n ...(command.task !== undefined && { task: command.task }),\n ...(command.files !== undefined && { files: command.files.join(', ') }),\n updated: `${new Date().toISOString().slice(0, 16)}Z`,\n })\n return { success: true, command: command.type }\n }\n default: {\n return {\n success: false,\n command: (command as HarnessCommand).type,\n message: `Command not supported by ${this.name}`,\n }\n }\n }\n }\n\n onEvent(handler: (event: HarnessEvent) => void): () => void {\n this.eventHandlers.add(handler)\n return () => this.eventHandlers.delete(handler)\n }\n\n async dispose(): Promise<void> {\n this.eventHandlers.clear()\n }\n\n private emit(event: HarnessEvent): void {\n for (const handler of this.eventHandlers) {\n try {\n handler(event)\n } catch {\n // Swallow subscriber errors — never let a listener crash the adapter\n }\n }\n }\n}\n","import type { HarnessAdapter } from '../types/adapter.js'\nimport type {\n HarnessCapabilities,\n HarnessCommand,\n HarnessCommandResult,\n HarnessEvent,\n HarnessInfo,\n} from '../types/core.js'\n\n/**\n * Stub adapter for GitHub Copilot.\n *\n * Copilot has no standalone CLI — it runs as a VS Code extension.\n * This adapter is a stub for future integration once Copilot exposes\n * a programmatic interface.\n */\nexport class CopilotAdapter implements HarnessAdapter {\n readonly id = 'copilot'\n readonly name = 'GitHub Copilot'\n\n private readonly eventHandlers = new Set<(event: HarnessEvent) => void>()\n\n getCapabilities(): HarnessCapabilities {\n return {\n generateCode: false, // stub — no CLI available\n analyzeCode: false,\n applyEdit: false,\n applyConfig: false,\n readWorkboard: false,\n writeWorkboard: false,\n }\n }\n\n async getInfo(): Promise<HarnessInfo> {\n return { id: this.id, name: this.name, capabilities: this.getCapabilities() }\n }\n\n async isAvailable(): Promise<boolean> {\n // Copilot is a VS Code extension — treat it as unavailable for standalone harness use.\n return false\n }\n\n notifyRegistered(): void {\n this.emit({ type: 'harness-connected', harnessId: this.id })\n }\n\n notifyUnregistering(): void {\n this.emit({ type: 'harness-disconnected', harnessId: this.id })\n }\n\n async execute(command: HarnessCommand): Promise<HarnessCommandResult> {\n return {\n success: false,\n command: command.type,\n message: 'Copilot adapter is a stub — no standalone CLI available',\n }\n }\n\n onEvent(handler: (event: HarnessEvent) => void): () => void {\n this.eventHandlers.add(handler)\n return () => this.eventHandlers.delete(handler)\n }\n\n async dispose(): Promise<void> {\n this.eventHandlers.clear()\n }\n\n private emit(event: HarnessEvent): void {\n for (const handler of this.eventHandlers) {\n try {\n handler(event)\n } catch {\n // Swallow subscriber errors\n }\n }\n }\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport type { HarnessAdapter } from '../types/adapter.js'\nimport type {\n HarnessCapabilities,\n HarnessCommand,\n HarnessCommandResult,\n HarnessEvent,\n HarnessInfo,\n} from '../types/core.js'\nimport { WorkboardManager } from '../workboard/workboard-manager.js'\n\nconst execFileAsync = promisify(execFile)\n\n/**\n * Adapter for Cursor IDE.\n *\n * Cursor is a VS Code fork with built-in AI capabilities.\n * This adapter detects Cursor via `cursor --version` and provides\n * workboard read/write when REVEALUI_WORKBOARD_PATH is set.\n */\nexport class CursorAdapter implements HarnessAdapter {\n readonly id = 'cursor'\n readonly name = 'Cursor'\n\n private readonly eventHandlers = new Set<(event: HarnessEvent) => void>()\n private readonly workboardPath: string | undefined\n\n constructor(workboardPath?: string) {\n this.workboardPath = workboardPath ?? process.env.REVEALUI_WORKBOARD_PATH\n }\n\n getCapabilities(): HarnessCapabilities {\n return {\n generateCode: false,\n analyzeCode: false,\n applyEdit: false,\n applyConfig: false,\n readWorkboard: this.workboardPath !== undefined,\n writeWorkboard: this.workboardPath !== undefined,\n }\n }\n\n async getInfo(): Promise<HarnessInfo> {\n let version: string | undefined\n try {\n const { stdout } = await execFileAsync('cursor', ['--version'], {\n timeout: 5000,\n })\n version = stdout.trim().split('\\n')[0]\n } catch {\n // Not installed or version flag unsupported.\n }\n return { id: this.id, name: this.name, version, capabilities: this.getCapabilities() }\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n await execFileAsync('cursor', ['--version'], { timeout: 3000 })\n return true\n } catch {\n return false\n }\n }\n\n notifyRegistered(): void {\n this.emit({ type: 'harness-connected', harnessId: this.id })\n }\n\n notifyUnregistering(): void {\n this.emit({ type: 'harness-disconnected', harnessId: this.id })\n }\n\n async execute(command: HarnessCommand): Promise<HarnessCommandResult> {\n try {\n return await this.executeInner(command)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n this.emit({ type: 'error', harnessId: this.id, message })\n return { success: false, command: command.type, message }\n }\n }\n\n private async executeInner(command: HarnessCommand): Promise<HarnessCommandResult> {\n switch (command.type) {\n case 'get-status': {\n const available = await this.isAvailable()\n return { success: true, command: command.type, data: { available } }\n }\n case 'read-workboard': {\n if (!this.workboardPath) {\n return {\n success: false,\n command: command.type,\n message: 'REVEALUI_WORKBOARD_PATH is not set',\n }\n }\n const manager = new WorkboardManager(this.workboardPath)\n const state = await manager.readAsync()\n return { success: true, command: command.type, data: state }\n }\n case 'update-workboard': {\n if (!this.workboardPath) {\n return {\n success: false,\n command: command.type,\n message: 'REVEALUI_WORKBOARD_PATH is not set',\n }\n }\n const manager = new WorkboardManager(this.workboardPath)\n manager.updateSession(command.sessionId, {\n ...(command.task !== undefined && { task: command.task }),\n ...(command.files !== undefined && { files: command.files.join(', ') }),\n updated: `${new Date().toISOString().slice(0, 16)}Z`,\n })\n return { success: true, command: command.type }\n }\n default: {\n return {\n success: false,\n command: (command as HarnessCommand).type,\n message: `Command not supported by ${this.name}`,\n }\n }\n }\n }\n\n onEvent(handler: (event: HarnessEvent) => void): () => void {\n this.eventHandlers.add(handler)\n return () => this.eventHandlers.delete(handler)\n }\n\n async dispose(): Promise<void> {\n this.eventHandlers.clear()\n }\n\n private emit(event: HarnessEvent): void {\n for (const handler of this.eventHandlers) {\n try {\n handler(event)\n } catch {\n // Swallow subscriber errors — never let a listener crash the adapter\n }\n }\n }\n}\n","import { copyFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport type { ConfigDiffEntry, ConfigSyncDirection, ConfigSyncResult } from '../types/core.js'\nimport {\n getConfigurableHarnesses,\n getLocalConfigPath,\n getRootConfigPath,\n} from './harness-config-paths.js'\n\n/**\n * Syncs harness config between local filesystem and root backup.\n * Mirrors config-sync.ts from packages/editors.\n */\nexport function syncConfig(\n harnessId: string,\n direction: ConfigSyncDirection,\n root?: string,\n): ConfigSyncResult {\n const localPath = getLocalConfigPath(harnessId)\n const rootPath = getRootConfigPath(harnessId, root)\n\n if (!(localPath && rootPath)) {\n return {\n success: false,\n harnessId,\n direction,\n message: `No config path known for harness: ${harnessId}`,\n }\n }\n\n try {\n if (direction === 'pull') {\n // Pull: root → local\n if (!existsSync(rootPath)) {\n return { success: false, harnessId, direction, message: `Root config not found: ${rootPath}` }\n }\n mkdirSync(dirname(localPath), { recursive: true })\n backupIfExists(localPath)\n copyFileSync(rootPath, localPath)\n return { success: true, harnessId, direction, message: `Pulled ${rootPath} → ${localPath}` }\n } else {\n // Push: local → root\n if (!existsSync(localPath)) {\n return {\n success: false,\n harnessId,\n direction,\n message: `Local config not found: ${localPath}`,\n }\n }\n mkdirSync(dirname(rootPath), { recursive: true })\n backupIfExists(rootPath)\n copyFileSync(localPath, rootPath)\n return { success: true, harnessId, direction, message: `Pushed ${localPath} → ${rootPath}` }\n }\n } catch (err) {\n return {\n success: false,\n harnessId,\n direction,\n message: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\n/** Compares local vs root config for a harness. */\nexport function diffConfig(harnessId: string, root?: string): ConfigDiffEntry {\n const localPath = getLocalConfigPath(harnessId)\n const rootPath = getRootConfigPath(harnessId, root)\n\n const localExists = !!localPath && existsSync(localPath)\n const ssdExists = !!rootPath && existsSync(rootPath)\n\n if (!(localExists && ssdExists)) {\n return { harnessId, localExists, ssdExists, identical: false }\n }\n\n try {\n const localContent = readFileSync(localPath, 'utf8')\n const ssdContent = readFileSync(rootPath, 'utf8')\n return { harnessId, localExists, ssdExists, identical: localContent === ssdContent }\n } catch {\n return { harnessId, localExists, ssdExists, identical: false }\n }\n}\n\n/**\n * Sync all known harness configs in a given direction.\n * Returns results for each harness.\n */\nexport function syncAllConfigs(\n direction: ConfigSyncDirection,\n root?: string,\n): ConfigSyncResult[] {\n return getConfigurableHarnesses().map((id) => syncConfig(id, direction, root))\n}\n\n/**\n * Diff all known harness configs.\n * Returns diff entries for each harness.\n */\nexport function diffAllConfigs(root?: string): ConfigDiffEntry[] {\n return getConfigurableHarnesses().map((id) => diffConfig(id, root))\n}\n\n/**\n * Validate that a config file contains parseable JSON.\n * Returns null if valid, or an error message if invalid.\n */\nexport function validateConfigJson(harnessId: string): string | null {\n const localPath = getLocalConfigPath(harnessId)\n if (!localPath) return `No config path known for harness: ${harnessId}`\n if (!existsSync(localPath)) return `Config file not found: ${localPath}`\n\n try {\n const content = readFileSync(localPath, 'utf8')\n JSON.parse(content)\n return null\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n}\n\n/** Create a .bak copy of a file if it exists (non-fatal if backup fails). */\nfunction backupIfExists(filePath: string): void {\n try {\n if (existsSync(filePath)) {\n copyFileSync(filePath, `${filePath}.bak`)\n }\n } catch {\n // Backup is best-effort — don't block the sync\n }\n}\n","import { homedir } from 'node:os'\nimport { join } from 'node:path'\n\n/**\n * Config path mappings for AI harnesses.\n * Mirrors editor-config-paths.ts from packages/editors.\n *\n * Local paths: harness config on this machine.\n * Root paths: backup/sync target on the DevPod (ext4 USB) or LTS (NTFS).\n */\n\nconst HOME = homedir()\nconst REVEALUI_ROOT = process.env.REVEALUI_ROOT ?? join(HOME, '.revealui')\n\nconst LOCAL_CONFIG_PATHS: Record<string, string> = {\n 'claude-code': join(HOME, '.claude', 'settings.json'),\n cursor: join(HOME, '.cursor', 'settings.json'),\n copilot: join(HOME, '.config', 'github-copilot', 'hosts.json'),\n}\n\nconst ROOT_CONFIG_FILES: Record<string, string> = {\n 'claude-code': 'settings.json',\n cursor: 'settings.json',\n copilot: 'hosts.json',\n}\n\n/** Returns the local config file path for a given harness id, or undefined if unknown. */\nexport function getLocalConfigPath(harnessId: string): string | undefined {\n return LOCAL_CONFIG_PATHS[harnessId]\n}\n\n/** Returns the root config file path for a given harness id, or undefined if unknown. */\nexport function getRootConfigPath(harnessId: string, root = REVEALUI_ROOT): string | undefined {\n const file = ROOT_CONFIG_FILES[harnessId]\n if (!file) return undefined\n return join(root, 'harness-configs', harnessId, file)\n}\n\n/** Returns ids of all harnesses with known config paths. */\nexport function getConfigurableHarnesses(): string[] {\n return Object.keys(LOCAL_CONFIG_PATHS)\n}\n","import { join } from 'node:path'\nimport { autoDetectHarnesses } from './detection/auto-detector.js'\nimport { HarnessRegistry } from './registry/harness-registry.js'\nimport { RpcServer } from './server/rpc-server.js'\nimport type { HarnessAdapter } from './types/adapter.js'\nimport type { HealthCheckResult } from './types/core.js'\nimport { deriveSessionId, detectSessionType } from './workboard/session-identity.js'\nimport { WorkboardManager } from './workboard/workboard-manager.js'\n\nexport interface CoordinatorOptions {\n /** Absolute path to the project root (where .claude/workboard.md lives) */\n projectRoot: string\n /** Unix socket path for the RPC server */\n socketPath?: string\n /** Session task description shown in the workboard */\n task?: string\n}\n\n/**\n * HarnessCoordinator — single entry point for harness-to-harness coordination.\n *\n * On start:\n * 1. Auto-detects installed AI harnesses and registers them\n * 2. Registers this session in the workboard\n * 3. Starts the RPC server\n *\n * On stop:\n * 1. Unregisters this session from the workboard\n * 2. Stops the RPC server\n * 3. Disposes all adapters\n */\nexport class HarnessCoordinator {\n private readonly registry = new HarnessRegistry()\n private rpcServer: RpcServer | null = null\n private sessionId: string | null = null\n private readonly workboard: WorkboardManager\n\n constructor(private readonly options: CoordinatorOptions) {\n const workboardPath = join(options.projectRoot, '.claude', 'workboard.md')\n this.workboard = new WorkboardManager(workboardPath)\n }\n\n async start(): Promise<void> {\n // 1. Auto-detect harnesses\n await autoDetectHarnesses(this.registry)\n\n // 2. Register in workboard\n const type = detectSessionType()\n const state = this.workboard.read()\n const existingIds = state.sessions.map((s) => s.id)\n this.sessionId = deriveSessionId(type, existingIds)\n\n const envLabels: Record<string, string> = {\n zed: 'Zed/ACP',\n cursor: 'Cursor',\n terminal: 'WSL/bash',\n }\n\n this.workboard.registerSession({\n id: this.sessionId,\n env: envLabels[type] ?? type,\n started: `${new Date().toISOString().slice(0, 16)}Z`,\n task: this.options.task ?? 'Harness coordination active',\n files: '',\n updated: `${new Date().toISOString().slice(0, 16)}Z`,\n })\n\n // 3. Start RPC server\n const socketPath =\n this.options.socketPath ??\n join(process.env.HOME ?? '/tmp', '.local', 'share', 'revealui', 'harness.sock')\n\n this.rpcServer = new RpcServer(this.registry, socketPath)\n this.rpcServer.setHealthCheck(() => this.healthCheck())\n await this.rpcServer.start()\n }\n\n async stop(): Promise<void> {\n // Unregister from workboard\n if (this.sessionId) {\n this.workboard.unregisterSession(this.sessionId)\n this.workboard.addRecentEntry({\n timestamp: new Date().toISOString().slice(0, 16).replace('T', ' '),\n sessionId: this.sessionId,\n description: `Session ended — ${this.options.task ?? 'harness coordination'}`,\n })\n }\n\n // Stop RPC server\n if (this.rpcServer) {\n await this.rpcServer.stop()\n this.rpcServer = null\n }\n\n // Dispose all adapters\n await this.registry.disposeAll()\n }\n\n /** The registry of detected harnesses. Available after start(). */\n getRegistry(): HarnessRegistry {\n return this.registry\n }\n\n /** The workboard manager. */\n getWorkboard(): WorkboardManager {\n return this.workboard\n }\n\n /** Register a custom adapter (must be called before start()). */\n registerAdapter(adapter: HarnessAdapter): void {\n this.registry.register(adapter)\n }\n\n /** Run a health check across all registered harnesses and the workboard. */\n async healthCheck(): Promise<HealthCheckResult> {\n const diagnostics: string[] = []\n const STALE_MS = 4 * 60 * 60 * 1000\n\n // Check registered harnesses\n const allIds = this.registry.listAll()\n const registeredHarnesses = await Promise.all(\n allIds.map(async (harnessId) => {\n const adapter = this.registry.get(harnessId)\n let available = false\n try {\n available = adapter ? await adapter.isAvailable() : false\n } catch (err) {\n diagnostics.push(\n `${harnessId}: availability check failed — ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n if (!available) diagnostics.push(`${harnessId}: not available`)\n return { harnessId, available }\n }),\n )\n\n // Check workboard\n let readable = false\n let sessionCount = 0\n const staleSessionIds: string[] = []\n try {\n const state = this.workboard.read()\n readable = true\n sessionCount = state.sessions.length\n const now = Date.now()\n for (const s of state.sessions) {\n const ts = Date.parse(s.updated)\n if (!Number.isNaN(ts) && now - ts > STALE_MS) {\n staleSessionIds.push(s.id)\n }\n }\n if (staleSessionIds.length > 0) {\n diagnostics.push(`Stale sessions: ${staleSessionIds.join(', ')}`)\n }\n } catch (err) {\n diagnostics.push(\n `Workboard unreadable: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n\n const healthy =\n registeredHarnesses.some((h) => h.available) && readable && staleSessionIds.length === 0\n\n return {\n healthy,\n timestamp: new Date().toISOString(),\n registeredHarnesses,\n workboard: { readable, sessionCount, staleSessionIds },\n diagnostics,\n }\n }\n}\n","import { ClaudeCodeAdapter } from '../adapters/claude-code-adapter.js'\nimport { CopilotAdapter } from '../adapters/copilot-adapter.js'\nimport { CursorAdapter } from '../adapters/cursor-adapter.js'\nimport type { HarnessRegistry } from '../registry/harness-registry.js'\n\n/**\n * Detects available AI harnesses and registers them in the registry.\n * Mirrors autoDetectEditors from packages/editors.\n *\n * Creates an adapter for each known harness, checks isAvailable(),\n * and registers those that respond. Unavailable adapters are disposed.\n */\nexport async function autoDetectHarnesses(registry: HarnessRegistry): Promise<string[]> {\n const candidates = [new ClaudeCodeAdapter(), new CursorAdapter(), new CopilotAdapter()]\n\n const registered: string[] = []\n\n await Promise.all(\n candidates.map(async (adapter) => {\n try {\n if (await adapter.isAvailable()) {\n registry.register(adapter)\n registered.push(adapter.id)\n } else {\n await adapter.dispose()\n }\n } catch {\n await adapter.dispose()\n }\n }),\n )\n\n return registered\n}\n","import type { HarnessAdapter } from '../types/adapter.js'\n\n/**\n * Manages the lifecycle of HarnessAdapter instances.\n * Mirrors EditorRegistry from packages/editors.\n */\nexport class HarnessRegistry {\n private readonly adapters = new Map<string, HarnessAdapter>()\n\n /** Register an adapter. Throws if an adapter with the same id already exists. */\n register(adapter: HarnessAdapter): void {\n if (this.adapters.has(adapter.id)) {\n throw new Error(`Harness adapter already registered: ${adapter.id}`)\n }\n this.adapters.set(adapter.id, adapter)\n adapter.notifyRegistered?.()\n }\n\n /** Unregister an adapter, disposing it in the process. */\n async unregister(id: string): Promise<void> {\n const adapter = this.adapters.get(id)\n if (adapter) {\n adapter.notifyUnregistering?.()\n await adapter.dispose()\n this.adapters.delete(id)\n }\n }\n\n /** Retrieve an adapter by id. */\n get(id: string): HarnessAdapter | undefined {\n return this.adapters.get(id)\n }\n\n /** List all registered adapter ids. */\n listAll(): string[] {\n return Array.from(this.adapters.keys())\n }\n\n /** List ids of adapters that report isAvailable() === true. */\n async listAvailable(): Promise<string[]> {\n const results = await Promise.all(\n Array.from(this.adapters.entries()).map(async ([id, adapter]) => ({\n id,\n available: await adapter.isAvailable(),\n })),\n )\n return results.filter((r) => r.available).map((r) => r.id)\n }\n\n /** Dispose all adapters and clear the registry. */\n async disposeAll(): Promise<void> {\n await Promise.all(Array.from(this.adapters.values()).map((a) => a.dispose()))\n this.adapters.clear()\n }\n}\n","import { createServer } from 'node:net'\nimport { diffConfig, syncConfig } from '../config/config-sync.js'\nimport { findHarnessProcesses } from '../detection/process-detector.js'\nimport type { HarnessRegistry } from '../registry/harness-registry.js'\nimport type { ConfigSyncDirection } from '../types/core.js'\n\ninterface JsonRpcRequest {\n jsonrpc: '2.0'\n id: number | string | null\n method: string\n params?: unknown\n}\n\ninterface JsonRpcResponse {\n jsonrpc: '2.0'\n id: number | string | null\n result?: unknown\n error?: { code: number; message: string; data?: unknown }\n}\n\nconst ERR_PARSE = -32700\nconst ERR_INVALID_PARAMS = -32602\nconst ERR_METHOD_NOT_FOUND = -32601\nconst ERR_INTERNAL = -32603\n\n/**\n * JSON-RPC 2.0 server over a Unix domain socket.\n * Mirrors RpcServer from packages/editors.\n *\n * Methods:\n * harness.list → HarnessInfo[]\n * harness.execute → HarnessCommandResult\n * harness.info → HarnessInfo\n * harness.listRunning → HarnessProcessInfo[]\n * harness.syncConfig → ConfigSyncResult\n * harness.diffConfig → ConfigDiffEntry\n * harness.health → HealthCheckResult\n */\nexport class RpcServer {\n private server = createServer()\n private healthCheckFn: (() => Promise<unknown>) | null = null\n\n constructor(\n private readonly registry: HarnessRegistry,\n private readonly socketPath: string,\n ) {\n this.server.on('connection', (socket) => {\n let buffer = ''\n socket.on('data', (chunk) => {\n buffer += chunk.toString()\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n for (const line of lines) {\n this.handleLine(line.trim(), (response) => {\n socket.write(`${JSON.stringify(response)}\\n`)\n })\n }\n })\n })\n }\n\n private handleLine(line: string, reply: (r: JsonRpcResponse) => void): void {\n let req: JsonRpcRequest\n try {\n req = JSON.parse(line) as JsonRpcRequest\n } catch {\n reply({ jsonrpc: '2.0', id: null, error: { code: ERR_PARSE, message: 'Parse error' } })\n return\n }\n\n this.dispatch(req)\n .then(reply)\n .catch((err) => {\n reply({\n jsonrpc: '2.0',\n id: req.id,\n error: { code: ERR_INTERNAL, message: err instanceof Error ? err.message : String(err) },\n })\n })\n }\n\n private async dispatch(req: JsonRpcRequest): Promise<JsonRpcResponse> {\n const { id, method, params } = req\n const p = (params ?? {}) as Record<string, unknown>\n\n switch (method) {\n case 'harness.list': {\n const ids = await this.registry.listAvailable()\n const infos = await Promise.all(ids.map((id) => this.registry.get(id)?.getInfo()))\n return { jsonrpc: '2.0', id, result: infos }\n }\n\n case 'harness.info': {\n const harnessId = p.harnessId as string | undefined\n if (!harnessId) {\n return {\n jsonrpc: '2.0',\n id,\n error: { code: ERR_INVALID_PARAMS, message: 'harnessId required' },\n }\n }\n const adapter = this.registry.get(harnessId)\n if (!adapter) {\n return {\n jsonrpc: '2.0',\n id,\n error: { code: ERR_INVALID_PARAMS, message: `Harness not found: ${harnessId}` },\n }\n }\n return { jsonrpc: '2.0', id, result: await adapter.getInfo() }\n }\n\n case 'harness.execute': {\n const harnessId = p.harnessId as string | undefined\n const command = p.command as Record<string, unknown> | undefined\n if (!(harnessId && command)) {\n return {\n jsonrpc: '2.0',\n id,\n error: { code: ERR_INVALID_PARAMS, message: 'harnessId and command required' },\n }\n }\n const adapter = this.registry.get(harnessId)\n if (!adapter) {\n return {\n jsonrpc: '2.0',\n id,\n error: { code: ERR_INVALID_PARAMS, message: `Harness not found: ${harnessId}` },\n }\n }\n const result = await adapter.execute(command as Parameters<typeof adapter.execute>[0])\n return { jsonrpc: '2.0', id, result }\n }\n\n case 'harness.syncConfig': {\n const harnessId = p.harnessId as string | undefined\n const direction = p.direction as ConfigSyncDirection | undefined\n if (!(harnessId && direction)) {\n return {\n jsonrpc: '2.0',\n id,\n error: { code: ERR_INVALID_PARAMS, message: 'harnessId and direction required' },\n }\n }\n return { jsonrpc: '2.0', id, result: syncConfig(harnessId, direction) }\n }\n\n case 'harness.diffConfig': {\n const harnessId = p.harnessId as string | undefined\n if (!harnessId) {\n return {\n jsonrpc: '2.0',\n id,\n error: { code: ERR_INVALID_PARAMS, message: 'harnessId required' },\n }\n }\n return { jsonrpc: '2.0', id, result: diffConfig(harnessId) }\n }\n\n case 'harness.listRunning': {\n const harnessId = p.harnessId as string | undefined\n if (!harnessId) {\n return {\n jsonrpc: '2.0',\n id,\n error: { code: ERR_INVALID_PARAMS, message: 'harnessId required' },\n }\n }\n const processes = await findHarnessProcesses(harnessId)\n return { jsonrpc: '2.0', id, result: processes }\n }\n\n case 'harness.health': {\n if (!this.healthCheckFn) {\n return {\n jsonrpc: '2.0',\n id,\n error: { code: ERR_INTERNAL, message: 'Health check not configured' },\n }\n }\n const health = await this.healthCheckFn()\n return { jsonrpc: '2.0', id, result: health }\n }\n\n default:\n return {\n jsonrpc: '2.0',\n id,\n error: { code: ERR_METHOD_NOT_FOUND, message: `Method not found: ${method}` },\n }\n }\n }\n\n /** Set the health check function (called by coordinator after construction). */\n setHealthCheck(fn: () => Promise<unknown>): void {\n this.healthCheckFn = fn\n }\n\n start(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.server.listen(this.socketPath, () => resolve())\n this.server.once('error', reject)\n })\n }\n\n stop(): Promise<void> {\n return new Promise((resolve) => this.server.close(() => resolve()))\n }\n}\n","import { execFile } from 'node:child_process'\nimport { readdir } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { promisify } from 'node:util'\nimport type { HarnessProcessInfo } from '../types/core.js'\n\nconst execFileAsync = promisify(execFile)\n\n/** Finds running processes matching a pattern using pgrep. */\nexport async function findProcesses(pattern: string): Promise<{ pid: number; command: string }[]> {\n try {\n const { stdout } = await execFileAsync('pgrep', ['-a', pattern], { timeout: 3000 })\n return stdout\n .trim()\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const spaceIdx = line.indexOf(' ')\n const pid = parseInt(line.slice(0, spaceIdx), 10)\n const command = line.slice(spaceIdx + 1)\n return { pid, command }\n })\n } catch {\n return []\n }\n}\n\nconst HARNESS_PROCESS_PATTERNS: Record<string, string[]> = {\n 'claude-code': ['claude'],\n cursor: ['cursor', 'Cursor'],\n copilot: ['copilot'],\n}\n\n/** Finds running process instances for a specific harness. */\nexport async function findHarnessProcesses(harnessId: string): Promise<HarnessProcessInfo[]> {\n const patterns = HARNESS_PROCESS_PATTERNS[harnessId]\n if (!patterns) return []\n\n const results = await Promise.all(patterns.map((p) => findProcesses(p)))\n return results.flat().map((p) => ({ ...p, harnessId }))\n}\n\n/** Finds running processes for all known harnesses. */\nexport async function findAllHarnessProcesses(): Promise<HarnessProcessInfo[]> {\n const results = await Promise.all(\n Object.keys(HARNESS_PROCESS_PATTERNS).map((id) => findHarnessProcesses(id)),\n )\n return results.flat()\n}\n\n/** Finds Claude Code Unix socket files (used for IPC). */\nexport async function findClaudeCodeSockets(): Promise<string[]> {\n const dirs = [\n '/tmp',\n process.env.XDG_RUNTIME_DIR,\n join(process.env.HOME ?? '/tmp', '.claude'),\n ].filter(Boolean) as string[]\n\n const sockets: string[] = []\n for (const dir of dirs) {\n try {\n const entries = await readdir(dir)\n for (const entry of entries) {\n if (/^claude.*\\.sock$/.test(entry)) {\n sockets.push(join(dir, entry))\n }\n }\n } catch {\n // Directory not accessible.\n }\n }\n return sockets\n}\n"],"mappings":";;;;;;;AAYA,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC,SAAS,cAAc;;;ACdvB,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAW1B,IAAM,gBAAgB,UAAU,QAAQ;AAYjC,IAAM,oBAAN,MAAkD;AAAA,EAC9C,KAAK;AAAA,EACL,OAAO;AAAA,EAEC,gBAAgB,oBAAI,IAAmC;AAAA,EACvD;AAAA,EAEjB,YAAY,eAAwB;AAClC,SAAK,gBAAgB,iBAAiB,QAAQ,IAAI;AAAA,EACpD;AAAA,EAEA,kBAAuC;AACrC,WAAO;AAAA,MACL,cAAc;AAAA;AAAA,MACd,aAAa;AAAA;AAAA,MACb,WAAW;AAAA;AAAA,MACX,aAAa;AAAA;AAAA,MACb,eAAe,KAAK,kBAAkB;AAAA,MACtC,gBAAgB,KAAK,kBAAkB;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAM,UAAgC;AACpC,QAAI;AACJ,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAM,cAAc,UAAU,CAAC,WAAW,GAAG;AAAA,QAC9D,SAAS;AAAA,MACX,CAAC;AACD,gBAAU,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC;AAAA,IACvC,QAAQ;AAAA,IAER;AACA,WAAO,EAAE,IAAI,KAAK,IAAI,MAAM,KAAK,MAAM,SAAS,cAAc,KAAK,gBAAgB,EAAE;AAAA,EACvF;AAAA,EAEA,MAAM,cAAgC;AACpC,QAAI;AACF,YAAM,cAAc,UAAU,CAAC,WAAW,GAAG,EAAE,SAAS,IAAK,CAAC;AAC9D,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,mBAAyB;AACvB,SAAK,KAAK,EAAE,MAAM,qBAAqB,WAAW,KAAK,GAAG,CAAC;AAAA,EAC7D;AAAA,EAEA,sBAA4B;AAC1B,SAAK,KAAK,EAAE,MAAM,wBAAwB,WAAW,KAAK,GAAG,CAAC;AAAA,EAChE;AAAA,EAEA,MAAM,QAAQ,SAAwD;AACpE,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,OAAO;AAAA,IACxC,SAAS,KAAK;AACZ,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,WAAK,KAAK,EAAE,MAAM,SAAS,WAAW,KAAK,IAAI,QAAQ,CAAC;AACxD,aAAO,EAAE,SAAS,OAAO,SAAS,QAAQ,MAAM,QAAQ;AAAA,IAC1D;AAAA,EACF;AAAA,EAEA,MAAc,aAAa,SAAwD;AACjF,YAAQ,QAAQ,MAAM;AAAA,MACpB,KAAK,cAAc;AACjB,cAAM,YAAY,MAAM,KAAK,YAAY;AACzC,eAAO,EAAE,SAAS,MAAM,SAAS,QAAQ,MAAM,MAAM,EAAE,UAAU,EAAE;AAAA,MACrE;AAAA,MACA,KAAK,yBAAyB;AAE5B,eAAO,EAAE,SAAS,MAAM,SAAS,QAAQ,MAAM,MAAM,CAAC,EAAE;AAAA,MAC1D;AAAA,MACA,KAAK;AAAA,MACL,KAAK,gBAAgB;AACnB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,QAAQ;AAAA,UACjB,SAAS,GAAG,QAAQ,IAAI;AAAA,QAC1B;AAAA,MACF;AAAA,MACA,KAAK,gBAAgB;AACnB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,QAAQ;AAAA,UACjB,SAAS;AAAA,QACX;AAAA,MACF;AAAA,MACA,KAAK,kBAAkB;AACrB,YAAI,CAAC,KAAK,eAAe;AACvB,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,SAAS,QAAQ;AAAA,YACjB,SAAS;AAAA,UACX;AAAA,QACF;AACA,cAAM,UAAU,IAAI,iBAAiB,KAAK,aAAa;AACvD,cAAM,QAAQ,MAAM,QAAQ,UAAU;AACtC,eAAO,EAAE,SAAS,MAAM,SAAS,QAAQ,MAAM,MAAM,MAAM;AAAA,MAC7D;AAAA,MACA,KAAK,oBAAoB;AACvB,YAAI,CAAC,KAAK,eAAe;AACvB,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,SAAS,QAAQ;AAAA,YACjB,SAAS;AAAA,UACX;AAAA,QACF;AACA,cAAM,UAAU,IAAI,iBAAiB,KAAK,aAAa;AACvD,gBAAQ,cAAc,QAAQ,WAAW;AAAA,UACvC,GAAI,QAAQ,SAAS,UAAa,EAAE,MAAM,QAAQ,KAAK;AAAA,UACvD,GAAI,QAAQ,UAAU,UAAa,EAAE,OAAO,QAAQ,MAAM,KAAK,IAAI,EAAE;AAAA,UACrE,SAAS,IAAG,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,QACnD,CAAC;AACD,eAAO,EAAE,SAAS,MAAM,SAAS,QAAQ,KAAK;AAAA,MAChD;AAAA,MACA,SAAS;AACP,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAU,QAA2B;AAAA,UACrC,SAAS,4BAA4B,KAAK,IAAI;AAAA,QAChD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QAAQ,SAAoD;AAC1D,SAAK,cAAc,IAAI,OAAO;AAC9B,WAAO,MAAM,KAAK,cAAc,OAAO,OAAO;AAAA,EAChD;AAAA,EAEA,MAAM,UAAyB;AAC7B,SAAK,cAAc,MAAM;AAAA,EAC3B;AAAA,EAEQ,KAAK,OAA2B;AACtC,eAAW,WAAW,KAAK,eAAe;AACxC,UAAI;AACF,gBAAQ,KAAK;AAAA,MACf,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;;;ACvJO,IAAM,iBAAN,MAA+C;AAAA,EAC3C,KAAK;AAAA,EACL,OAAO;AAAA,EAEC,gBAAgB,oBAAI,IAAmC;AAAA,EAExE,kBAAuC;AACrC,WAAO;AAAA,MACL,cAAc;AAAA;AAAA,MACd,aAAa;AAAA,MACb,WAAW;AAAA,MACX,aAAa;AAAA,MACb,eAAe;AAAA,MACf,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,MAAM,UAAgC;AACpC,WAAO,EAAE,IAAI,KAAK,IAAI,MAAM,KAAK,MAAM,cAAc,KAAK,gBAAgB,EAAE;AAAA,EAC9E;AAAA,EAEA,MAAM,cAAgC;AAEpC,WAAO;AAAA,EACT;AAAA,EAEA,mBAAyB;AACvB,SAAK,KAAK,EAAE,MAAM,qBAAqB,WAAW,KAAK,GAAG,CAAC;AAAA,EAC7D;AAAA,EAEA,sBAA4B;AAC1B,SAAK,KAAK,EAAE,MAAM,wBAAwB,WAAW,KAAK,GAAG,CAAC;AAAA,EAChE;AAAA,EAEA,MAAM,QAAQ,SAAwD;AACpE,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,QAAQ;AAAA,MACjB,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,QAAQ,SAAoD;AAC1D,SAAK,cAAc,IAAI,OAAO;AAC9B,WAAO,MAAM,KAAK,cAAc,OAAO,OAAO;AAAA,EAChD;AAAA,EAEA,MAAM,UAAyB;AAC7B,SAAK,cAAc,MAAM;AAAA,EAC3B;AAAA,EAEQ,KAAK,OAA2B;AACtC,eAAW,WAAW,KAAK,eAAe;AACxC,UAAI;AACF,gBAAQ,KAAK;AAAA,MACf,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;;;AC5EA,SAAS,YAAAA,iBAAgB;AACzB,SAAS,aAAAC,kBAAiB;AAW1B,IAAMC,iBAAgBC,WAAUC,SAAQ;AASjC,IAAM,gBAAN,MAA8C;AAAA,EAC1C,KAAK;AAAA,EACL,OAAO;AAAA,EAEC,gBAAgB,oBAAI,IAAmC;AAAA,EACvD;AAAA,EAEjB,YAAY,eAAwB;AAClC,SAAK,gBAAgB,iBAAiB,QAAQ,IAAI;AAAA,EACpD;AAAA,EAEA,kBAAuC;AACrC,WAAO;AAAA,MACL,cAAc;AAAA,MACd,aAAa;AAAA,MACb,WAAW;AAAA,MACX,aAAa;AAAA,MACb,eAAe,KAAK,kBAAkB;AAAA,MACtC,gBAAgB,KAAK,kBAAkB;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAM,UAAgC;AACpC,QAAI;AACJ,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAMF,eAAc,UAAU,CAAC,WAAW,GAAG;AAAA,QAC9D,SAAS;AAAA,MACX,CAAC;AACD,gBAAU,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC;AAAA,IACvC,QAAQ;AAAA,IAER;AACA,WAAO,EAAE,IAAI,KAAK,IAAI,MAAM,KAAK,MAAM,SAAS,cAAc,KAAK,gBAAgB,EAAE;AAAA,EACvF;AAAA,EAEA,MAAM,cAAgC;AACpC,QAAI;AACF,YAAMA,eAAc,UAAU,CAAC,WAAW,GAAG,EAAE,SAAS,IAAK,CAAC;AAC9D,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,mBAAyB;AACvB,SAAK,KAAK,EAAE,MAAM,qBAAqB,WAAW,KAAK,GAAG,CAAC;AAAA,EAC7D;AAAA,EAEA,sBAA4B;AAC1B,SAAK,KAAK,EAAE,MAAM,wBAAwB,WAAW,KAAK,GAAG,CAAC;AAAA,EAChE;AAAA,EAEA,MAAM,QAAQ,SAAwD;AACpE,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,OAAO;AAAA,IACxC,SAAS,KAAK;AACZ,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,WAAK,KAAK,EAAE,MAAM,SAAS,WAAW,KAAK,IAAI,QAAQ,CAAC;AACxD,aAAO,EAAE,SAAS,OAAO,SAAS,QAAQ,MAAM,QAAQ;AAAA,IAC1D;AAAA,EACF;AAAA,EAEA,MAAc,aAAa,SAAwD;AACjF,YAAQ,QAAQ,MAAM;AAAA,MACpB,KAAK,cAAc;AACjB,cAAM,YAAY,MAAM,KAAK,YAAY;AACzC,eAAO,EAAE,SAAS,MAAM,SAAS,QAAQ,MAAM,MAAM,EAAE,UAAU,EAAE;AAAA,MACrE;AAAA,MACA,KAAK,kBAAkB;AACrB,YAAI,CAAC,KAAK,eAAe;AACvB,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,SAAS,QAAQ;AAAA,YACjB,SAAS;AAAA,UACX;AAAA,QACF;AACA,cAAM,UAAU,IAAI,iBAAiB,KAAK,aAAa;AACvD,cAAM,QAAQ,MAAM,QAAQ,UAAU;AACtC,eAAO,EAAE,SAAS,MAAM,SAAS,QAAQ,MAAM,MAAM,MAAM;AAAA,MAC7D;AAAA,MACA,KAAK,oBAAoB;AACvB,YAAI,CAAC,KAAK,eAAe;AACvB,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,SAAS,QAAQ;AAAA,YACjB,SAAS;AAAA,UACX;AAAA,QACF;AACA,cAAM,UAAU,IAAI,iBAAiB,KAAK,aAAa;AACvD,gBAAQ,cAAc,QAAQ,WAAW;AAAA,UACvC,GAAI,QAAQ,SAAS,UAAa,EAAE,MAAM,QAAQ,KAAK;AAAA,UACvD,GAAI,QAAQ,UAAU,UAAa,EAAE,OAAO,QAAQ,MAAM,KAAK,IAAI,EAAE;AAAA,UACrE,SAAS,IAAG,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,QACnD,CAAC;AACD,eAAO,EAAE,SAAS,MAAM,SAAS,QAAQ,KAAK;AAAA,MAChD;AAAA,MACA,SAAS;AACP,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAU,QAA2B;AAAA,UACrC,SAAS,4BAA4B,KAAK,IAAI;AAAA,QAChD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QAAQ,SAAoD;AAC1D,SAAK,cAAc,IAAI,OAAO;AAC9B,WAAO,MAAM,KAAK,cAAc,OAAO,OAAO;AAAA,EAChD;AAAA,EAEA,MAAM,UAAyB;AAC7B,SAAK,cAAc,MAAM;AAAA,EAC3B;AAAA,EAEQ,KAAK,OAA2B;AACtC,eAAW,WAAW,KAAK,eAAe;AACxC,UAAI;AACF,gBAAQ,KAAK;AAAA,MACf,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;;;ACjJA,SAAS,cAAc,YAAY,WAAW,oBAAoB;AAClE,SAAS,eAAe;;;ACDxB,SAAS,eAAe;AACxB,SAAS,YAAY;AAUrB,IAAM,OAAO,QAAQ;AACrB,IAAM,gBAAgB,QAAQ,IAAI,iBAAiB,KAAK,MAAM,WAAW;AAEzE,IAAM,qBAA6C;AAAA,EACjD,eAAe,KAAK,MAAM,WAAW,eAAe;AAAA,EACpD,QAAQ,KAAK,MAAM,WAAW,eAAe;AAAA,EAC7C,SAAS,KAAK,MAAM,WAAW,kBAAkB,YAAY;AAC/D;AAEA,IAAM,oBAA4C;AAAA,EAChD,eAAe;AAAA,EACf,QAAQ;AAAA,EACR,SAAS;AACX;AAGO,SAAS,mBAAmB,WAAuC;AACxE,SAAO,mBAAmB,SAAS;AACrC;AAGO,SAAS,kBAAkB,WAAmB,OAAO,eAAmC;AAC7F,QAAM,OAAO,kBAAkB,SAAS;AACxC,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,KAAK,MAAM,mBAAmB,WAAW,IAAI;AACtD;AAGO,SAAS,2BAAqC;AACnD,SAAO,OAAO,KAAK,kBAAkB;AACvC;;;AD5BO,SAAS,WACd,WACA,WACA,MACkB;AAClB,QAAM,YAAY,mBAAmB,SAAS;AAC9C,QAAM,WAAW,kBAAkB,WAAW,IAAI;AAElD,MAAI,EAAE,aAAa,WAAW;AAC5B,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,SAAS,qCAAqC,SAAS;AAAA,IACzD;AAAA,EACF;AAEA,MAAI;AACF,QAAI,cAAc,QAAQ;AAExB,UAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,eAAO,EAAE,SAAS,OAAO,WAAW,WAAW,SAAS,0BAA0B,QAAQ,GAAG;AAAA,MAC/F;AACA,gBAAU,QAAQ,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AACjD,qBAAe,SAAS;AACxB,mBAAa,UAAU,SAAS;AAChC,aAAO,EAAE,SAAS,MAAM,WAAW,WAAW,SAAS,UAAU,QAAQ,WAAM,SAAS,GAAG;AAAA,IAC7F,OAAO;AAEL,UAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,eAAO;AAAA,UACL,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA,SAAS,2BAA2B,SAAS;AAAA,QAC/C;AAAA,MACF;AACA,gBAAU,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD,qBAAe,QAAQ;AACvB,mBAAa,WAAW,QAAQ;AAChC,aAAO,EAAE,SAAS,MAAM,WAAW,WAAW,SAAS,UAAU,SAAS,WAAM,QAAQ,GAAG;AAAA,IAC7F;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IAC1D;AAAA,EACF;AACF;AAGO,SAAS,WAAW,WAAmB,MAAgC;AAC5E,QAAM,YAAY,mBAAmB,SAAS;AAC9C,QAAM,WAAW,kBAAkB,WAAW,IAAI;AAElD,QAAM,cAAc,CAAC,CAAC,aAAa,WAAW,SAAS;AACvD,QAAM,YAAY,CAAC,CAAC,YAAY,WAAW,QAAQ;AAEnD,MAAI,EAAE,eAAe,YAAY;AAC/B,WAAO,EAAE,WAAW,aAAa,WAAW,WAAW,MAAM;AAAA,EAC/D;AAEA,MAAI;AACF,UAAM,eAAe,aAAa,WAAW,MAAM;AACnD,UAAM,aAAa,aAAa,UAAU,MAAM;AAChD,WAAO,EAAE,WAAW,aAAa,WAAW,WAAW,iBAAiB,WAAW;AAAA,EACrF,QAAQ;AACN,WAAO,EAAE,WAAW,aAAa,WAAW,WAAW,MAAM;AAAA,EAC/D;AACF;AAMO,SAAS,eACd,WACA,MACoB;AACpB,SAAO,yBAAyB,EAAE,IAAI,CAAC,OAAO,WAAW,IAAI,WAAW,IAAI,CAAC;AAC/E;AAMO,SAAS,eAAe,MAAkC;AAC/D,SAAO,yBAAyB,EAAE,IAAI,CAAC,OAAO,WAAW,IAAI,IAAI,CAAC;AACpE;AAMO,SAAS,mBAAmB,WAAkC;AACnE,QAAM,YAAY,mBAAmB,SAAS;AAC9C,MAAI,CAAC,UAAW,QAAO,qCAAqC,SAAS;AACrE,MAAI,CAAC,WAAW,SAAS,EAAG,QAAO,0BAA0B,SAAS;AAEtE,MAAI;AACF,UAAM,UAAU,aAAa,WAAW,MAAM;AAC9C,SAAK,MAAM,OAAO;AAClB,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,WAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,EACxD;AACF;AAGA,SAAS,eAAe,UAAwB;AAC9C,MAAI;AACF,QAAI,WAAW,QAAQ,GAAG;AACxB,mBAAa,UAAU,GAAG,QAAQ,MAAM;AAAA,IAC1C;AAAA,EACF,QAAQ;AAAA,EAER;AACF;;;AEpIA,SAAS,QAAAG,aAAY;;;ACYrB,eAAsB,oBAAoB,UAA8C;AACtF,QAAM,aAAa,CAAC,IAAI,kBAAkB,GAAG,IAAI,cAAc,GAAG,IAAI,eAAe,CAAC;AAEtF,QAAM,aAAuB,CAAC;AAE9B,QAAM,QAAQ;AAAA,IACZ,WAAW,IAAI,OAAO,YAAY;AAChC,UAAI;AACF,YAAI,MAAM,QAAQ,YAAY,GAAG;AAC/B,mBAAS,SAAS,OAAO;AACzB,qBAAW,KAAK,QAAQ,EAAE;AAAA,QAC5B,OAAO;AACL,gBAAM,QAAQ,QAAQ;AAAA,QACxB;AAAA,MACF,QAAQ;AACN,cAAM,QAAQ,QAAQ;AAAA,MACxB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC3BO,IAAM,kBAAN,MAAsB;AAAA,EACV,WAAW,oBAAI,IAA4B;AAAA;AAAA,EAG5D,SAAS,SAA+B;AACtC,QAAI,KAAK,SAAS,IAAI,QAAQ,EAAE,GAAG;AACjC,YAAM,IAAI,MAAM,uCAAuC,QAAQ,EAAE,EAAE;AAAA,IACrE;AACA,SAAK,SAAS,IAAI,QAAQ,IAAI,OAAO;AACrC,YAAQ,mBAAmB;AAAA,EAC7B;AAAA;AAAA,EAGA,MAAM,WAAW,IAA2B;AAC1C,UAAM,UAAU,KAAK,SAAS,IAAI,EAAE;AACpC,QAAI,SAAS;AACX,cAAQ,sBAAsB;AAC9B,YAAM,QAAQ,QAAQ;AACtB,WAAK,SAAS,OAAO,EAAE;AAAA,IACzB;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,IAAwC;AAC1C,WAAO,KAAK,SAAS,IAAI,EAAE;AAAA,EAC7B;AAAA;AAAA,EAGA,UAAoB;AAClB,WAAO,MAAM,KAAK,KAAK,SAAS,KAAK,CAAC;AAAA,EACxC;AAAA;AAAA,EAGA,MAAM,gBAAmC;AACvC,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,MAAM,KAAK,KAAK,SAAS,QAAQ,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,OAAO,OAAO;AAAA,QAChE;AAAA,QACA,WAAW,MAAM,QAAQ,YAAY;AAAA,MACvC,EAAE;AAAA,IACJ;AACA,WAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,EAC3D;AAAA;AAAA,EAGA,MAAM,aAA4B;AAChC,UAAM,QAAQ,IAAI,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC5E,SAAK,SAAS,MAAM;AAAA,EACtB;AACF;;;ACtDA,SAAS,oBAAoB;;;ACA7B,SAAS,YAAAC,iBAAgB;AACzB,SAAS,eAAe;AACxB,SAAS,QAAAC,aAAY;AACrB,SAAS,aAAAC,kBAAiB;AAG1B,IAAMC,iBAAgBD,WAAUF,SAAQ;AAGxC,eAAsB,cAAc,SAA8D;AAChG,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMG,eAAc,SAAS,CAAC,MAAM,OAAO,GAAG,EAAE,SAAS,IAAK,CAAC;AAClF,WAAO,OACJ,KAAK,EACL,MAAM,IAAI,EACV,OAAO,OAAO,EACd,IAAI,CAAC,SAAS;AACb,YAAM,WAAW,KAAK,QAAQ,GAAG;AACjC,YAAM,MAAM,SAAS,KAAK,MAAM,GAAG,QAAQ,GAAG,EAAE;AAChD,YAAM,UAAU,KAAK,MAAM,WAAW,CAAC;AACvC,aAAO,EAAE,KAAK,QAAQ;AAAA,IACxB,CAAC;AAAA,EACL,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,IAAM,2BAAqD;AAAA,EACzD,eAAe,CAAC,QAAQ;AAAA,EACxB,QAAQ,CAAC,UAAU,QAAQ;AAAA,EAC3B,SAAS,CAAC,SAAS;AACrB;AAGA,eAAsB,qBAAqB,WAAkD;AAC3F,QAAM,WAAW,yBAAyB,SAAS;AACnD,MAAI,CAAC,SAAU,QAAO,CAAC;AAEvB,QAAM,UAAU,MAAM,QAAQ,IAAI,SAAS,IAAI,CAAC,MAAM,cAAc,CAAC,CAAC,CAAC;AACvE,SAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,UAAU,EAAE;AACxD;AAGA,eAAsB,0BAAyD;AAC7E,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,OAAO,KAAK,wBAAwB,EAAE,IAAI,CAAC,OAAO,qBAAqB,EAAE,CAAC;AAAA,EAC5E;AACA,SAAO,QAAQ,KAAK;AACtB;AAGA,eAAsB,wBAA2C;AAC/D,QAAM,OAAO;AAAA,IACX;AAAA,IACA,QAAQ,IAAI;AAAA,IACZF,MAAK,QAAQ,IAAI,QAAQ,QAAQ,SAAS;AAAA,EAC5C,EAAE,OAAO,OAAO;AAEhB,QAAM,UAAoB,CAAC;AAC3B,aAAW,OAAO,MAAM;AACtB,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,GAAG;AACjC,iBAAW,SAAS,SAAS;AAC3B,YAAI,mBAAmB,KAAK,KAAK,GAAG;AAClC,kBAAQ,KAAKA,MAAK,KAAK,KAAK,CAAC;AAAA,QAC/B;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;;;ADpDA,IAAM,YAAY;AAClB,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;AAC7B,IAAM,eAAe;AAed,IAAM,YAAN,MAAgB;AAAA,EAIrB,YACmB,UACA,YACjB;AAFiB;AACA;AAEjB,SAAK,OAAO,GAAG,cAAc,CAAC,WAAW;AACvC,UAAI,SAAS;AACb,aAAO,GAAG,QAAQ,CAAC,UAAU;AAC3B,kBAAU,MAAM,SAAS;AACzB,cAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,iBAAS,MAAM,IAAI,KAAK;AACxB,mBAAW,QAAQ,OAAO;AACxB,eAAK,WAAW,KAAK,KAAK,GAAG,CAAC,aAAa;AACzC,mBAAO,MAAM,GAAG,KAAK,UAAU,QAAQ,CAAC;AAAA,CAAI;AAAA,UAC9C,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EApBQ,SAAS,aAAa;AAAA,EACtB,gBAAiD;AAAA,EAqBjD,WAAW,MAAc,OAA2C;AAC1E,QAAI;AACJ,QAAI;AACF,YAAM,KAAK,MAAM,IAAI;AAAA,IACvB,QAAQ;AACN,YAAM,EAAE,SAAS,OAAO,IAAI,MAAM,OAAO,EAAE,MAAM,WAAW,SAAS,cAAc,EAAE,CAAC;AACtF;AAAA,IACF;AAEA,SAAK,SAAS,GAAG,EACd,KAAK,KAAK,EACV,MAAM,CAAC,QAAQ;AACd,YAAM;AAAA,QACJ,SAAS;AAAA,QACT,IAAI,IAAI;AAAA,QACR,OAAO,EAAE,MAAM,cAAc,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,MACzF,CAAC;AAAA,IACH,CAAC;AAAA,EACL;AAAA,EAEA,MAAc,SAAS,KAA+C;AACpE,UAAM,EAAE,IAAI,QAAQ,OAAO,IAAI;AAC/B,UAAM,IAAK,UAAU,CAAC;AAEtB,YAAQ,QAAQ;AAAA,MACd,KAAK,gBAAgB;AACnB,cAAM,MAAM,MAAM,KAAK,SAAS,cAAc;AAC9C,cAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI,IAAI,CAACG,QAAO,KAAK,SAAS,IAAIA,GAAE,GAAG,QAAQ,CAAC,CAAC;AACjF,eAAO,EAAE,SAAS,OAAO,IAAI,QAAQ,MAAM;AAAA,MAC7C;AAAA,MAEA,KAAK,gBAAgB;AACnB,cAAM,YAAY,EAAE;AACpB,YAAI,CAAC,WAAW;AACd,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,YACA,OAAO,EAAE,MAAM,oBAAoB,SAAS,qBAAqB;AAAA,UACnE;AAAA,QACF;AACA,cAAM,UAAU,KAAK,SAAS,IAAI,SAAS;AAC3C,YAAI,CAAC,SAAS;AACZ,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,YACA,OAAO,EAAE,MAAM,oBAAoB,SAAS,sBAAsB,SAAS,GAAG;AAAA,UAChF;AAAA,QACF;AACA,eAAO,EAAE,SAAS,OAAO,IAAI,QAAQ,MAAM,QAAQ,QAAQ,EAAE;AAAA,MAC/D;AAAA,MAEA,KAAK,mBAAmB;AACtB,cAAM,YAAY,EAAE;AACpB,cAAM,UAAU,EAAE;AAClB,YAAI,EAAE,aAAa,UAAU;AAC3B,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,YACA,OAAO,EAAE,MAAM,oBAAoB,SAAS,iCAAiC;AAAA,UAC/E;AAAA,QACF;AACA,cAAM,UAAU,KAAK,SAAS,IAAI,SAAS;AAC3C,YAAI,CAAC,SAAS;AACZ,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,YACA,OAAO,EAAE,MAAM,oBAAoB,SAAS,sBAAsB,SAAS,GAAG;AAAA,UAChF;AAAA,QACF;AACA,cAAM,SAAS,MAAM,QAAQ,QAAQ,OAAgD;AACrF,eAAO,EAAE,SAAS,OAAO,IAAI,OAAO;AAAA,MACtC;AAAA,MAEA,KAAK,sBAAsB;AACzB,cAAM,YAAY,EAAE;AACpB,cAAM,YAAY,EAAE;AACpB,YAAI,EAAE,aAAa,YAAY;AAC7B,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,YACA,OAAO,EAAE,MAAM,oBAAoB,SAAS,mCAAmC;AAAA,UACjF;AAAA,QACF;AACA,eAAO,EAAE,SAAS,OAAO,IAAI,QAAQ,WAAW,WAAW,SAAS,EAAE;AAAA,MACxE;AAAA,MAEA,KAAK,sBAAsB;AACzB,cAAM,YAAY,EAAE;AACpB,YAAI,CAAC,WAAW;AACd,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,YACA,OAAO,EAAE,MAAM,oBAAoB,SAAS,qBAAqB;AAAA,UACnE;AAAA,QACF;AACA,eAAO,EAAE,SAAS,OAAO,IAAI,QAAQ,WAAW,SAAS,EAAE;AAAA,MAC7D;AAAA,MAEA,KAAK,uBAAuB;AAC1B,cAAM,YAAY,EAAE;AACpB,YAAI,CAAC,WAAW;AACd,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,YACA,OAAO,EAAE,MAAM,oBAAoB,SAAS,qBAAqB;AAAA,UACnE;AAAA,QACF;AACA,cAAM,YAAY,MAAM,qBAAqB,SAAS;AACtD,eAAO,EAAE,SAAS,OAAO,IAAI,QAAQ,UAAU;AAAA,MACjD;AAAA,MAEA,KAAK,kBAAkB;AACrB,YAAI,CAAC,KAAK,eAAe;AACvB,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,YACA,OAAO,EAAE,MAAM,cAAc,SAAS,8BAA8B;AAAA,UACtE;AAAA,QACF;AACA,cAAM,SAAS,MAAM,KAAK,cAAc;AACxC,eAAO,EAAE,SAAS,OAAO,IAAI,QAAQ,OAAO;AAAA,MAC9C;AAAA,MAEA;AACE,eAAO;AAAA,UACL,SAAS;AAAA,UACT;AAAA,UACA,OAAO,EAAE,MAAM,sBAAsB,SAAS,qBAAqB,MAAM,GAAG;AAAA,QAC9E;AAAA,IACJ;AAAA,EACF;AAAA;AAAA,EAGA,eAAe,IAAkC;AAC/C,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,QAAuB;AACrB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,WAAK,OAAO,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AACnD,WAAK,OAAO,KAAK,SAAS,MAAM;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,OAAsB;AACpB,WAAO,IAAI,QAAQ,CAAC,YAAY,KAAK,OAAO,MAAM,MAAM,QAAQ,CAAC,CAAC;AAAA,EACpE;AACF;;;AHjLO,IAAM,qBAAN,MAAyB;AAAA,EAM9B,YAA6B,SAA6B;AAA7B;AAC3B,UAAM,gBAAgBC,MAAK,QAAQ,aAAa,WAAW,cAAc;AACzE,SAAK,YAAY,IAAI,iBAAiB,aAAa;AAAA,EACrD;AAAA,EARiB,WAAW,IAAI,gBAAgB;AAAA,EACxC,YAA8B;AAAA,EAC9B,YAA2B;AAAA,EAClB;AAAA,EAOjB,MAAM,QAAuB;AAE3B,UAAM,oBAAoB,KAAK,QAAQ;AAGvC,UAAM,OAAO,kBAAkB;AAC/B,UAAM,QAAQ,KAAK,UAAU,KAAK;AAClC,UAAM,cAAc,MAAM,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE;AAClD,SAAK,YAAY,gBAAgB,MAAM,WAAW;AAElD,UAAM,YAAoC;AAAA,MACxC,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAEA,SAAK,UAAU,gBAAgB;AAAA,MAC7B,IAAI,KAAK;AAAA,MACT,KAAK,UAAU,IAAI,KAAK;AAAA,MACxB,SAAS,IAAG,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,MACjD,MAAM,KAAK,QAAQ,QAAQ;AAAA,MAC3B,OAAO;AAAA,MACP,SAAS,IAAG,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,IACnD,CAAC;AAGD,UAAM,aACJ,KAAK,QAAQ,cACbA,MAAK,QAAQ,IAAI,QAAQ,QAAQ,UAAU,SAAS,YAAY,cAAc;AAEhF,SAAK,YAAY,IAAI,UAAU,KAAK,UAAU,UAAU;AACxD,SAAK,UAAU,eAAe,MAAM,KAAK,YAAY,CAAC;AACtD,UAAM,KAAK,UAAU,MAAM;AAAA,EAC7B;AAAA,EAEA,MAAM,OAAsB;AAE1B,QAAI,KAAK,WAAW;AAClB,WAAK,UAAU,kBAAkB,KAAK,SAAS;AAC/C,WAAK,UAAU,eAAe;AAAA,QAC5B,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,KAAK,GAAG;AAAA,QACjE,WAAW,KAAK;AAAA,QAChB,aAAa,wBAAmB,KAAK,QAAQ,QAAQ,sBAAsB;AAAA,MAC7E,CAAC;AAAA,IACH;AAGA,QAAI,KAAK,WAAW;AAClB,YAAM,KAAK,UAAU,KAAK;AAC1B,WAAK,YAAY;AAAA,IACnB;AAGA,UAAM,KAAK,SAAS,WAAW;AAAA,EACjC;AAAA;AAAA,EAGA,cAA+B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,eAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,gBAAgB,SAA+B;AAC7C,SAAK,SAAS,SAAS,OAAO;AAAA,EAChC;AAAA;AAAA,EAGA,MAAM,cAA0C;AAC9C,UAAM,cAAwB,CAAC;AAC/B,UAAM,WAAW,IAAI,KAAK,KAAK;AAG/B,UAAM,SAAS,KAAK,SAAS,QAAQ;AACrC,UAAM,sBAAsB,MAAM,QAAQ;AAAA,MACxC,OAAO,IAAI,OAAO,cAAc;AAC9B,cAAM,UAAU,KAAK,SAAS,IAAI,SAAS;AAC3C,YAAI,YAAY;AAChB,YAAI;AACF,sBAAY,UAAU,MAAM,QAAQ,YAAY,IAAI;AAAA,QACtD,SAAS,KAAK;AACZ,sBAAY;AAAA,YACV,GAAG,SAAS,sCAAiC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAC/F;AAAA,QACF;AACA,YAAI,CAAC,UAAW,aAAY,KAAK,GAAG,SAAS,iBAAiB;AAC9D,eAAO,EAAE,WAAW,UAAU;AAAA,MAChC,CAAC;AAAA,IACH;AAGA,QAAI,WAAW;AACf,QAAI,eAAe;AACnB,UAAM,kBAA4B,CAAC;AACnC,QAAI;AACF,YAAM,QAAQ,KAAK,UAAU,KAAK;AAClC,iBAAW;AACX,qBAAe,MAAM,SAAS;AAC9B,YAAM,MAAM,KAAK,IAAI;AACrB,iBAAW,KAAK,MAAM,UAAU;AAC9B,cAAM,KAAK,KAAK,MAAM,EAAE,OAAO;AAC/B,YAAI,CAAC,OAAO,MAAM,EAAE,KAAK,MAAM,KAAK,UAAU;AAC5C,0BAAgB,KAAK,EAAE,EAAE;AAAA,QAC3B;AAAA,MACF;AACA,UAAI,gBAAgB,SAAS,GAAG;AAC9B,oBAAY,KAAK,mBAAmB,gBAAgB,KAAK,IAAI,CAAC,EAAE;AAAA,MAClE;AAAA,IACF,SAAS,KAAK;AACZ,kBAAY;AAAA,QACV,yBAAyB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MAC3E;AAAA,IACF;AAEA,UAAM,UACJ,oBAAoB,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,YAAY,gBAAgB,WAAW;AAEzF,WAAO;AAAA,MACL;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,MACA,WAAW,EAAE,UAAU,cAAc,gBAAgB;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;;;AN1JA,eAAsB,wBAA0C;AAC9D,QAAM,kBAAkB;AACxB,MAAI,CAAC,iBAAiB,IAAI,GAAG;AAC3B,WAAO;AAAA,MACL;AAAA,MAEA,EAAE,SAAS,KAAK;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;","names":["execFile","promisify","execFileAsync","promisify","execFile","join","execFile","join","promisify","execFileAsync","id","join"]}