UNPKG

@dollhousemcp/mcp-server

Version:

DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.

121 lines 17.7 kB
/** * PolicyExportService - Exports tool classification policies for bridge consumption * * Writes a JSON policy file to ~/.dollhouse/bridge/imports/policies/ so the * DollhouseBridge permission-prompt server can evaluate permissions locally. * * Write-only: publishes and forgets. Skips silently if the bridge folder * doesn't exist (bridge may not be installed). * * @see https://github.com/DollhouseMCP/mcp-server-v2-refactor/issues/762 */ import { writeFile, access } from 'node:fs/promises'; import { join } from 'node:path'; import { homedir } from 'node:os'; import { getStaticPolicyData } from '../handlers/mcp-aql/policies/ToolClassification.js'; import { logger } from '../utils/logger.js'; import { env } from '../config/env.js'; const POLICY_DIR = join(homedir(), '.dollhouse', 'bridge', 'imports', 'policies'); const POLICY_FILENAME = 'dollhousemcp-crude-policies.json'; export class PolicyExportService { deps; constructor(deps) { this.deps = deps; } /** * Export current policy state to the bridge imports folder. * * Gathers static classification rules and active element policies, * writes a single JSON file conforming to bridge policy schema v1.0. * * Skips silently if the bridge imports directory doesn't exist. */ async exportPolicies() { if (!env.DOLLHOUSE_POLICY_EXPORT_ENABLED) { return; } try { // Check if bridge imports directory exists — skip if not await access(POLICY_DIR); } catch { // Bridge not installed or imports dir not created — skip silently return; } try { const staticRules = getStaticPolicyData(); const activeElements = await this.deps.getActiveElementsForPolicy(); const version = this.deps.getServerVersion(); const elementPolicies = this.buildElementPolicies(activeElements); const policy = { schema_version: '1.0', server: { name: 'DollhouseMCP-V2-Refactor CRUDE', version, }, exported_at: new Date().toISOString(), static_rules: { safe_tools: staticRules.safe_tools, safe_bash_patterns: staticRules.safe_bash_patterns, dangerous_bash_patterns: staticRules.dangerous_bash_patterns, blocked_bash_patterns: staticRules.blocked_bash_patterns, irreversible_patterns: staticRules.irreversible_patterns, sensitive_path_prefixes: staticRules.sensitive_path_prefixes, gatekeeper_essential_operations: staticRules.gatekeeper_essential_operations, safe_mcp_operations: staticRules.safe_mcp_operations, }, element_policies: elementPolicies, risk_scores: staticRules.risk_scores, }; const filePath = join(POLICY_DIR, POLICY_FILENAME); await writeFile(filePath, JSON.stringify(policy, null, 2), 'utf-8'); logger.info('[PolicyExportService] Policies exported', { filePath, elementCount: elementPolicies.active_element_count }); } catch (err) { // Non-fatal: log and continue logger.warn('[PolicyExportService] Failed to export policies', { error: err.message }); } } buildElementPolicies(activeElements) { const elements = []; const combinedAllow = []; const combinedConfirm = []; const combinedDeny = []; let ensembleName; for (const element of activeElements) { if (element.type === 'ensemble') { ensembleName = element.name; } const gatekeeper = element.metadata?.gatekeeper; const external = gatekeeper?.externalRestrictions; const allowPatterns = Array.isArray(external?.allowPatterns) ? external.allowPatterns.filter((p) => typeof p === 'string') : []; const confirmPatterns = Array.isArray(external?.confirmPatterns) ? external.confirmPatterns.filter((p) => typeof p === 'string') : []; const denyPatterns = Array.isArray(external?.denyPatterns) ? external.denyPatterns.filter((p) => typeof p === 'string') : []; elements.push({ type: element.type, name: element.name, allow_patterns: allowPatterns, confirm_patterns: confirmPatterns, deny_patterns: denyPatterns, }); combinedAllow.push(...allowPatterns); combinedConfirm.push(...confirmPatterns); combinedDeny.push(...denyPatterns); } return { active_element_count: elements.length, ...(ensembleName ? { ensemble_name: ensembleName } : {}), elements, combined_allow_patterns: [...new Set(combinedAllow)], combined_confirm_patterns: [...new Set(combinedConfirm)], combined_deny_patterns: [...new Set(combinedDeny)], }; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUG9saWN5RXhwb3J0U2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9Qb2xpY3lFeHBvcnRTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7O0dBVUc7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDakMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNsQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvREFBb0QsQ0FBQztBQUN6RixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDNUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXZDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUNsRixNQUFNLGVBQWUsR0FBRyxrQ0FBa0MsQ0FBQztBQWUzRCxNQUFNLE9BQU8sbUJBQW1CO0lBQ3RCLElBQUksQ0FBbUI7SUFFL0IsWUFBWSxJQUFzQjtRQUNoQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxjQUFjO1FBQ2xCLElBQUksQ0FBQyxHQUFHLENBQUMsK0JBQStCLEVBQUUsQ0FBQztZQUN6QyxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILHlEQUF5RDtZQUN6RCxNQUFNLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMzQixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1Asa0VBQWtFO1lBQ2xFLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxXQUFXLEdBQUcsbUJBQW1CLEVBQUUsQ0FBQztZQUMxQyxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztZQUNwRSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFFN0MsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBRWxFLE1BQU0sTUFBTSxHQUFHO2dCQUNiLGNBQWMsRUFBRSxLQUFLO2dCQUNyQixNQUFNLEVBQUU7b0JBQ04sSUFBSSxFQUFFLGdDQUFnQztvQkFDdEMsT0FBTztpQkFDUjtnQkFDRCxXQUFXLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7Z0JBQ3JDLFlBQVksRUFBRTtvQkFDWixVQUFVLEVBQUUsV0FBVyxDQUFDLFVBQVU7b0JBQ2xDLGtCQUFrQixFQUFFLFdBQVcsQ0FBQyxrQkFBa0I7b0JBQ2xELHVCQUF1QixFQUFFLFdBQVcsQ0FBQyx1QkFBdUI7b0JBQzVELHFCQUFxQixFQUFFLFdBQVcsQ0FBQyxxQkFBcUI7b0JBQ3hELHFCQUFxQixFQUFFLFdBQVcsQ0FBQyxxQkFBcUI7b0JBQ3hELHVCQUF1QixFQUFFLFdBQVcsQ0FBQyx1QkFBdUI7b0JBQzVELCtCQUErQixFQUFFLFdBQVcsQ0FBQywrQkFBK0I7b0JBQzVFLG1CQUFtQixFQUFFLFdBQVcsQ0FBQyxtQkFBbUI7aUJBQ3JEO2dCQUNELGdCQUFnQixFQUFFLGVBQWU7Z0JBQ2pDLFdBQVcsRUFBRSxXQUFXLENBQUMsV0FBVzthQUNyQyxDQUFDO1lBRUYsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUNuRCxNQUFNLFNBQVMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ3BFLE1BQU0sQ0FBQyxJQUFJLENBQUMseUNBQXlDLEVBQUUsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLGVBQWUsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUM7UUFDM0gsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYiw4QkFBOEI7WUFDOUIsTUFBTSxDQUFDLElBQUksQ0FBQyxpREFBaUQsRUFBRSxFQUFFLEtBQUssRUFBRyxHQUFhLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNwRyxDQUFDO0lBQ0gsQ0FBQztJQUVPLG9CQUFvQixDQUFDLGNBQXdGO1FBQ25ILE1BQU0sUUFBUSxHQUF5QixFQUFFLENBQUM7UUFDMUMsTUFBTSxhQUFhLEdBQWEsRUFBRSxDQUFDO1FBQ25DLE1BQU0sZUFBZSxHQUFhLEVBQUUsQ0FBQztRQUNyQyxNQUFNLFlBQVksR0FBYSxFQUFFLENBQUM7UUFDbEMsSUFBSSxZQUFnQyxDQUFDO1FBRXJDLEtBQUssTUFBTSxPQUFPLElBQUksY0FBYyxFQUFFLENBQUM7WUFDckMsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRSxDQUFDO2dCQUNoQyxZQUFZLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztZQUM5QixDQUFDO1lBRUQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLFFBQVEsRUFBRSxVQUFpRCxDQUFDO1lBQ3ZGLE1BQU0sUUFBUSxHQUFHLFVBQVUsRUFBRSxvQkFBMkQsQ0FBQztZQUV6RixNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxhQUFhLENBQUM7Z0JBQzFELENBQUMsQ0FBRSxRQUFRLENBQUMsYUFBMkIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQWUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFFBQVEsQ0FBQztnQkFDekYsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNQLE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLGVBQWUsQ0FBQztnQkFDOUQsQ0FBQyxDQUFFLFFBQVEsQ0FBQyxlQUE2QixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBZSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssUUFBUSxDQUFDO2dCQUMzRixDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ1AsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsWUFBWSxDQUFDO2dCQUN4RCxDQUFDLENBQUUsUUFBUSxDQUFDLFlBQTBCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFlLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxRQUFRLENBQUM7Z0JBQ3hGLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFFUCxRQUFRLENBQUMsSUFBSSxDQUFDO2dCQUNaLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtnQkFDbEIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO2dCQUNsQixjQUFjLEVBQUUsYUFBYTtnQkFDN0IsZ0JBQWdCLEVBQUUsZUFBZTtnQkFDakMsYUFBYSxFQUFFLFlBQVk7YUFDNUIsQ0FBQyxDQUFDO1lBRUgsYUFBYSxDQUFDLElBQUksQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDO1lBQ3JDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQztZQUN6QyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUVELE9BQU87WUFDTCxvQkFBb0IsRUFBRSxRQUFRLENBQUMsTUFBTTtZQUNyQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3hELFFBQVE7WUFDUix1QkFBdUIsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDcEQseUJBQXlCLEVBQUUsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3hELHNCQUFzQixFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUNuRCxDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQb2xpY3lFeHBvcnRTZXJ2aWNlIC0gRXhwb3J0cyB0b29sIGNsYXNzaWZpY2F0aW9uIHBvbGljaWVzIGZvciBicmlkZ2UgY29uc3VtcHRpb25cbiAqXG4gKiBXcml0ZXMgYSBKU09OIHBvbGljeSBmaWxlIHRvIH4vLmRvbGxob3VzZS9icmlkZ2UvaW1wb3J0cy9wb2xpY2llcy8gc28gdGhlXG4gKiBEb2xsaG91c2VCcmlkZ2UgcGVybWlzc2lvbi1wcm9tcHQgc2VydmVyIGNhbiBldmFsdWF0ZSBwZXJtaXNzaW9ucyBsb2NhbGx5LlxuICpcbiAqIFdyaXRlLW9ubHk6IHB1Ymxpc2hlcyBhbmQgZm9yZ2V0cy4gU2tpcHMgc2lsZW50bHkgaWYgdGhlIGJyaWRnZSBmb2xkZXJcbiAqIGRvZXNuJ3QgZXhpc3QgKGJyaWRnZSBtYXkgbm90IGJlIGluc3RhbGxlZCkuXG4gKlxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vRG9sbGhvdXNlTUNQL21jcC1zZXJ2ZXItdjItcmVmYWN0b3IvaXNzdWVzLzc2MlxuICovXG5cbmltcG9ydCB7IHdyaXRlRmlsZSwgYWNjZXNzIH0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7IGhvbWVkaXIgfSBmcm9tICdub2RlOm9zJztcbmltcG9ydCB7IGdldFN0YXRpY1BvbGljeURhdGEgfSBmcm9tICcuLi9oYW5kbGVycy9tY3AtYXFsL3BvbGljaWVzL1Rvb2xDbGFzc2lmaWNhdGlvbi5qcyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW52IH0gZnJvbSAnLi4vY29uZmlnL2Vudi5qcyc7XG5cbmNvbnN0IFBPTElDWV9ESVIgPSBqb2luKGhvbWVkaXIoKSwgJy5kb2xsaG91c2UnLCAnYnJpZGdlJywgJ2ltcG9ydHMnLCAncG9saWNpZXMnKTtcbmNvbnN0IFBPTElDWV9GSUxFTkFNRSA9ICdkb2xsaG91c2VtY3AtY3J1ZGUtcG9saWNpZXMuanNvbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUG9saWN5RXhwb3J0RGVwcyB7XG4gIGdldEFjdGl2ZUVsZW1lbnRzRm9yUG9saWN5OiAoKSA9PiBQcm9taXNlPEFycmF5PHsgdHlwZTogc3RyaW5nOyBuYW1lOiBzdHJpbmc7IG1ldGFkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9Pj47XG4gIGdldFNlcnZlclZlcnNpb246ICgpID0+IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIEVsZW1lbnRQb2xpY3lFbnRyeSB7XG4gIHR5cGU6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBhbGxvd19wYXR0ZXJuczogc3RyaW5nW107XG4gIGNvbmZpcm1fcGF0dGVybnM6IHN0cmluZ1tdO1xuICBkZW55X3BhdHRlcm5zOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGNsYXNzIFBvbGljeUV4cG9ydFNlcnZpY2Uge1xuICBwcml2YXRlIGRlcHM6IFBvbGljeUV4cG9ydERlcHM7XG5cbiAgY29uc3RydWN0b3IoZGVwczogUG9saWN5RXhwb3J0RGVwcykge1xuICAgIHRoaXMuZGVwcyA9IGRlcHM7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3J0IGN1cnJlbnQgcG9saWN5IHN0YXRlIHRvIHRoZSBicmlkZ2UgaW1wb3J0cyBmb2xkZXIuXG4gICAqXG4gICAqIEdhdGhlcnMgc3RhdGljIGNsYXNzaWZpY2F0aW9uIHJ1bGVzIGFuZCBhY3RpdmUgZWxlbWVudCBwb2xpY2llcyxcbiAgICogd3JpdGVzIGEgc2luZ2xlIEpTT04gZmlsZSBjb25mb3JtaW5nIHRvIGJyaWRnZSBwb2xpY3kgc2NoZW1hIHYxLjAuXG4gICAqXG4gICAqIFNraXBzIHNpbGVudGx5IGlmIHRoZSBicmlkZ2UgaW1wb3J0cyBkaXJlY3RvcnkgZG9lc24ndCBleGlzdC5cbiAgICovXG4gIGFzeW5jIGV4cG9ydFBvbGljaWVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghZW52LkRPTExIT1VTRV9QT0xJQ1lfRVhQT1JUX0VOQUJMRUQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgLy8gQ2hlY2sgaWYgYnJpZGdlIGltcG9ydHMgZGlyZWN0b3J5IGV4aXN0cyDigJQgc2tpcCBpZiBub3RcbiAgICAgIGF3YWl0IGFjY2VzcyhQT0xJQ1lfRElSKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIEJyaWRnZSBub3QgaW5zdGFsbGVkIG9yIGltcG9ydHMgZGlyIG5vdCBjcmVhdGVkIOKAlCBza2lwIHNpbGVudGx5XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0YXRpY1J1bGVzID0gZ2V0U3RhdGljUG9saWN5RGF0YSgpO1xuICAgICAgY29uc3QgYWN0aXZlRWxlbWVudHMgPSBhd2FpdCB0aGlzLmRlcHMuZ2V0QWN0aXZlRWxlbWVudHNGb3JQb2xpY3koKTtcbiAgICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLmRlcHMuZ2V0U2VydmVyVmVyc2lvbigpO1xuXG4gICAgICBjb25zdCBlbGVtZW50UG9saWNpZXMgPSB0aGlzLmJ1aWxkRWxlbWVudFBvbGljaWVzKGFjdGl2ZUVsZW1lbnRzKTtcblxuICAgICAgY29uc3QgcG9saWN5ID0ge1xuICAgICAgICBzY2hlbWFfdmVyc2lvbjogJzEuMCcsXG4gICAgICAgIHNlcnZlcjoge1xuICAgICAgICAgIG5hbWU6ICdEb2xsaG91c2VNQ1AtVjItUmVmYWN0b3IgQ1JVREUnLFxuICAgICAgICAgIHZlcnNpb24sXG4gICAgICAgIH0sXG4gICAgICAgIGV4cG9ydGVkX2F0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIHN0YXRpY19ydWxlczoge1xuICAgICAgICAgIHNhZmVfdG9vbHM6IHN0YXRpY1J1bGVzLnNhZmVfdG9vbHMsXG4gICAgICAgICAgc2FmZV9iYXNoX3BhdHRlcm5zOiBzdGF0aWNSdWxlcy5zYWZlX2Jhc2hfcGF0dGVybnMsXG4gICAgICAgICAgZGFuZ2Vyb3VzX2Jhc2hfcGF0dGVybnM6IHN0YXRpY1J1bGVzLmRhbmdlcm91c19iYXNoX3BhdHRlcm5zLFxuICAgICAgICAgIGJsb2NrZWRfYmFzaF9wYXR0ZXJuczogc3RhdGljUnVsZXMuYmxvY2tlZF9iYXNoX3BhdHRlcm5zLFxuICAgICAgICAgIGlycmV2ZXJzaWJsZV9wYXR0ZXJuczogc3RhdGljUnVsZXMuaXJyZXZlcnNpYmxlX3BhdHRlcm5zLFxuICAgICAgICAgIHNlbnNpdGl2ZV9wYXRoX3ByZWZpeGVzOiBzdGF0aWNSdWxlcy5zZW5zaXRpdmVfcGF0aF9wcmVmaXhlcyxcbiAgICAgICAgICBnYXRla2VlcGVyX2Vzc2VudGlhbF9vcGVyYXRpb25zOiBzdGF0aWNSdWxlcy5nYXRla2VlcGVyX2Vzc2VudGlhbF9vcGVyYXRpb25zLFxuICAgICAgICAgIHNhZmVfbWNwX29wZXJhdGlvbnM6IHN0YXRpY1J1bGVzLnNhZmVfbWNwX29wZXJhdGlvbnMsXG4gICAgICAgIH0sXG4gICAgICAgIGVsZW1lbnRfcG9saWNpZXM6IGVsZW1lbnRQb2xpY2llcyxcbiAgICAgICAgcmlza19zY29yZXM6IHN0YXRpY1J1bGVzLnJpc2tfc2NvcmVzLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgZmlsZVBhdGggPSBqb2luKFBPTElDWV9ESVIsIFBPTElDWV9GSUxFTkFNRSk7XG4gICAgICBhd2FpdCB3cml0ZUZpbGUoZmlsZVBhdGgsIEpTT04uc3RyaW5naWZ5KHBvbGljeSwgbnVsbCwgMiksICd1dGYtOCcpO1xuICAgICAgbG9nZ2VyLmluZm8oJ1tQb2xpY3lFeHBvcnRTZXJ2aWNlXSBQb2xpY2llcyBleHBvcnRlZCcsIHsgZmlsZVBhdGgsIGVsZW1lbnRDb3VudDogZWxlbWVudFBvbGljaWVzLmFjdGl2ZV9lbGVtZW50X2NvdW50IH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgLy8gTm9uLWZhdGFsOiBsb2cgYW5kIGNvbnRpbnVlXG4gICAgICBsb2dnZXIud2FybignW1BvbGljeUV4cG9ydFNlcnZpY2VdIEZhaWxlZCB0byBleHBvcnQgcG9saWNpZXMnLCB7IGVycm9yOiAoZXJyIGFzIEVycm9yKS5tZXNzYWdlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRFbGVtZW50UG9saWNpZXMoYWN0aXZlRWxlbWVudHM6IEFycmF5PHsgdHlwZTogc3RyaW5nOyBuYW1lOiBzdHJpbmc7IG1ldGFkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9Pikge1xuICAgIGNvbnN0IGVsZW1lbnRzOiBFbGVtZW50UG9saWN5RW50cnlbXSA9IFtdO1xuICAgIGNvbnN0IGNvbWJpbmVkQWxsb3c6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgY29tYmluZWRDb25maXJtOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IGNvbWJpbmVkRGVueTogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgZW5zZW1ibGVOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgYWN0aXZlRWxlbWVudHMpIHtcbiAgICAgIGlmIChlbGVtZW50LnR5cGUgPT09ICdlbnNlbWJsZScpIHtcbiAgICAgICAgZW5zZW1ibGVOYW1lID0gZWxlbWVudC5uYW1lO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBnYXRla2VlcGVyID0gZWxlbWVudC5tZXRhZGF0YT8uZ2F0ZWtlZXBlciBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IGV4dGVybmFsID0gZ2F0ZWtlZXBlcj8uZXh0ZXJuYWxSZXN0cmljdGlvbnMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQ7XG5cbiAgICAgIGNvbnN0IGFsbG93UGF0dGVybnMgPSBBcnJheS5pc0FycmF5KGV4dGVybmFsPy5hbGxvd1BhdHRlcm5zKVxuICAgICAgICA/IChleHRlcm5hbC5hbGxvd1BhdHRlcm5zIGFzIHVua25vd25bXSkuZmlsdGVyKChwKTogcCBpcyBzdHJpbmcgPT4gdHlwZW9mIHAgPT09ICdzdHJpbmcnKVxuICAgICAgICA6IFtdO1xuICAgICAgY29uc3QgY29uZmlybVBhdHRlcm5zID0gQXJyYXkuaXNBcnJheShleHRlcm5hbD8uY29uZmlybVBhdHRlcm5zKVxuICAgICAgICA/IChleHRlcm5hbC5jb25maXJtUGF0dGVybnMgYXMgdW5rbm93bltdKS5maWx0ZXIoKHApOiBwIGlzIHN0cmluZyA9PiB0eXBlb2YgcCA9PT0gJ3N0cmluZycpXG4gICAgICAgIDogW107XG4gICAgICBjb25zdCBkZW55UGF0dGVybnMgPSBBcnJheS5pc0FycmF5KGV4dGVybmFsPy5kZW55UGF0dGVybnMpXG4gICAgICAgID8gKGV4dGVybmFsLmRlbnlQYXR0ZXJucyBhcyB1bmtub3duW10pLmZpbHRlcigocCk6IHAgaXMgc3RyaW5nID0+IHR5cGVvZiBwID09PSAnc3RyaW5nJylcbiAgICAgICAgOiBbXTtcblxuICAgICAgZWxlbWVudHMucHVzaCh7XG4gICAgICAgIHR5cGU6IGVsZW1lbnQudHlwZSxcbiAgICAgICAgbmFtZTogZWxlbWVudC5uYW1lLFxuICAgICAgICBhbGxvd19wYXR0ZXJuczogYWxsb3dQYXR0ZXJucyxcbiAgICAgICAgY29uZmlybV9wYXR0ZXJuczogY29uZmlybVBhdHRlcm5zLFxuICAgICAgICBkZW55X3BhdHRlcm5zOiBkZW55UGF0dGVybnMsXG4gICAgICB9KTtcblxuICAgICAgY29tYmluZWRBbGxvdy5wdXNoKC4uLmFsbG93UGF0dGVybnMpO1xuICAgICAgY29tYmluZWRDb25maXJtLnB1c2goLi4uY29uZmlybVBhdHRlcm5zKTtcbiAgICAgIGNvbWJpbmVkRGVueS5wdXNoKC4uLmRlbnlQYXR0ZXJucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFjdGl2ZV9lbGVtZW50X2NvdW50OiBlbGVtZW50cy5sZW5ndGgsXG4gICAgICAuLi4oZW5zZW1ibGVOYW1lID8geyBlbnNlbWJsZV9uYW1lOiBlbnNlbWJsZU5hbWUgfSA6IHt9KSxcbiAgICAgIGVsZW1lbnRzLFxuICAgICAgY29tYmluZWRfYWxsb3dfcGF0dGVybnM6IFsuLi5uZXcgU2V0KGNvbWJpbmVkQWxsb3cpXSxcbiAgICAgIGNvbWJpbmVkX2NvbmZpcm1fcGF0dGVybnM6IFsuLi5uZXcgU2V0KGNvbWJpbmVkQ29uZmlybSldLFxuICAgICAgY29tYmluZWRfZGVueV9wYXR0ZXJuczogWy4uLm5ldyBTZXQoY29tYmluZWREZW55KV0sXG4gICAgfTtcbiAgfVxufVxuIl19