aai-gateway 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as createGatewayServer } from "./server-
|
|
2
|
+
import { n as createGatewayServer } from "./server-DmOAeOMT.js";
|
|
3
3
|
import { o as AAI_GATEWAY_VERSION, s as logger } from "./acp-DWqg7EhR.js";
|
|
4
4
|
//#region src/cli.ts
|
|
5
5
|
async function main() {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as GuideService, c as getSkillExecutor, d as getMcpExecutor, i as ImportService, l as AppRegistry, n as createGatewayServer, o as ExecutionCoordinator, r as Gateway, s as SkillExecutor, t as AaiGatewayServer, u as McpExecutor } from "./server-
|
|
1
|
+
import { a as GuideService, c as getSkillExecutor, d as getMcpExecutor, i as ImportService, l as AppRegistry, n as createGatewayServer, o as ExecutionCoordinator, r as Gateway, s as SkillExecutor, t as AaiGatewayServer, u as McpExecutor } from "./server-DmOAeOMT.js";
|
|
2
2
|
import { t as AaiError } from "./errors-C3N_hrpx.js";
|
|
3
3
|
import { n as getAcpExecutor, s as logger, t as AcpExecutor } from "./acp-DWqg7EhR.js";
|
|
4
4
|
import { a as FileRegistry, c as parseAaiJson } from "./mcp-registry-CuVFEyIP.js";
|
|
@@ -2931,6 +2931,8 @@ var Gateway = class {
|
|
|
2931
2931
|
if (toolName === "disableApp") return this.handleDisableApp(args, caller);
|
|
2932
2932
|
if (toolName === "enableApp") return this.handleEnableApp(args, caller);
|
|
2933
2933
|
if (toolName === "removeApp") return this.handleRemoveApp(args, caller);
|
|
2934
|
+
if (toolName === "mcp:import") return this.handleMcpImport(parseMcpImportArguments(args), args, caller);
|
|
2935
|
+
if (toolName === "skill:import") return this.handleSkillImport(parseSkillImportArguments(args), args, caller);
|
|
2934
2936
|
throw new AaiError("UNKNOWN_TOOL", `Unknown tool: ${toolName}`);
|
|
2935
2937
|
}
|
|
2936
2938
|
async resolveManagedApp(appId, caller) {
|
|
@@ -3062,6 +3064,13 @@ function buildMissingEnvVarsResult(err) {
|
|
|
3062
3064
|
* Thin protocol layer — handles MCP request/response serialization
|
|
3063
3065
|
* and delegates all business logic to Gateway (core/gateway.ts).
|
|
3064
3066
|
*/
|
|
3067
|
+
var TOOLS_CHANGING_OPERATIONS = new Set([
|
|
3068
|
+
"mcp:import",
|
|
3069
|
+
"skill:import",
|
|
3070
|
+
"disableApp",
|
|
3071
|
+
"enableApp",
|
|
3072
|
+
"removeApp"
|
|
3073
|
+
]);
|
|
3065
3074
|
var AaiGatewayServer = class {
|
|
3066
3075
|
server;
|
|
3067
3076
|
gateway = new Gateway();
|
|
@@ -3101,24 +3110,11 @@ var AaiGatewayServer = class {
|
|
|
3101
3110
|
if (name.startsWith("app:")) return this.toCallToolResult(await this.gateway.handleAppGuide(name.slice(4), caller));
|
|
3102
3111
|
if (name === "aai:exec") {
|
|
3103
3112
|
const payload = args;
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
if (name === "mcp:import") {
|
|
3107
|
-
const rawMap = args;
|
|
3108
|
-
if (!rawMap || Object.keys(rawMap).length === 0) return this.toCallToolResult(this.gateway.handleGatewayToolGuide(name));
|
|
3109
|
-
const parsed = parseMcpImportArguments(rawMap);
|
|
3110
|
-
const result = await this.gateway.handleMcpImport(parsed, rawMap, caller);
|
|
3111
|
-
if (!result.isError) await this.notifyToolsListChanged();
|
|
3112
|
-
return this.toCallToolResult(result);
|
|
3113
|
-
}
|
|
3114
|
-
if (name === "skill:import") {
|
|
3115
|
-
const rawMap = args;
|
|
3116
|
-
if (!rawMap || Object.keys(rawMap).length === 0) return this.toCallToolResult(this.gateway.handleGatewayToolGuide(name));
|
|
3117
|
-
const parsed = parseSkillImportArguments(rawMap);
|
|
3118
|
-
const result = await this.gateway.handleSkillImport(parsed, rawMap, caller);
|
|
3119
|
-
if (!result.isError) await this.notifyToolsListChanged();
|
|
3113
|
+
const result = await this.gateway.handleExec(extra.requestId, payload.app, payload.tool, payload.args ?? {}, caller);
|
|
3114
|
+
if (TOOLS_CHANGING_OPERATIONS.has(payload.tool) && !result.isError) await this.notifyToolsListChanged();
|
|
3120
3115
|
return this.toCallToolResult(result);
|
|
3121
3116
|
}
|
|
3117
|
+
if (name === "mcp:import" || name === "skill:import") return this.toCallToolResult(this.gateway.handleGatewayToolGuide(name));
|
|
3122
3118
|
if (name === "search:discover" || name === "listAllAaiApps" || name === "disableApp" || name === "enableApp" || name === "removeApp") {
|
|
3123
3119
|
const toolArgs = args ?? {};
|
|
3124
3120
|
let result;
|
|
@@ -3182,4 +3178,4 @@ async function createGatewayServer() {
|
|
|
3182
3178
|
//#endregion
|
|
3183
3179
|
export { GuideService as a, getSkillExecutor as c, getMcpExecutor as d, ImportService as i, AppRegistry as l, createGatewayServer as n, ExecutionCoordinator as o, Gateway as r, SkillExecutor as s, AaiGatewayServer as t, McpExecutor as u };
|
|
3184
3180
|
|
|
3185
|
-
//# sourceMappingURL=server-
|
|
3181
|
+
//# sourceMappingURL=server-DmOAeOMT.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-BNj-vVwq.js","names":[],"sources":["../src/utils/dotenv.ts","../src/storage/skill-registry.ts","../src/utils/ids.ts","../src/core/importer.ts","../src/executors/mcp.ts","../src/discovery/checks.ts","../src/storage/managed-registry.ts","../src/storage/agent-state.ts","../src/core/search-guidance.ts","../src/core/parsers.ts","../src/core/tool-definitions.ts","../src/core/app-registry.ts","../src/types/aai-json.ts","../src/executors/skill.ts","../src/core/execution-coordinator.ts","../src/utils/locale.ts","../src/guides/app-guide-generator.ts","../src/core/guide-service.ts","../src/core/import-service.ts","../src/discovery/descriptors/claude-code-agent.ts","../src/discovery/descriptors/codex-agent.ts","../src/discovery/descriptors/opencode-agent.ts","../src/core/seed.ts","../src/core/background/task-manager.ts","../src/core/background/acp-prewarm-task.ts","../src/core/background/turn-cleanup.ts","../src/core/gateway.ts","../src/mcp/server.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\n\nimport { getAaiHomeDir } from './config.js';\n\nexport interface DotenvResult {\n env: Record<string, string>;\n missing: string[];\n}\n\nexport interface SubstitutionResult<T> {\n result: T;\n missing: string[];\n}\n\nexport function getDotenvPath(): string {\n return `${getAaiHomeDir()}/.env`;\n}\n\n/**\n * Load environment variables from ~/.aai-gateway/.env file\n */\nexport async function loadDotenv(): Promise<DotenvResult> {\n const dotenvPath = getDotenvPath();\n\n try {\n const content = await readFile(dotenvPath, 'utf-8');\n const env: Record<string, string> = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n // Skip empty lines and comments\n if (!trimmed || trimmed.startsWith('#')) {\n continue;\n }\n\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) {\n continue;\n }\n\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n\n // Remove surrounding quotes if present\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n\n if (key) {\n env[key] = value;\n }\n }\n\n return { env, missing: [] };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { env: {}, missing: [] };\n }\n throw error;\n }\n}\n\n/**\n * Substitute ${VAR_NAME} placeholders in a string with values from env\n */\nexport function substituteEnvVars(str: string, env: Record<string, string>): string {\n return str.replace(/\\$\\{([^}]+)\\}/g, (_match, varName) => {\n const value = env[varName];\n if (value === undefined) {\n throw new Error(\n `Environment variable \\${${varName}} is not defined in ~/.aai-gateway/.env`\n );\n }\n return value;\n });\n}\n\n/**\n * Find all ${VAR_NAME} placeholders in a string\n */\nexport function findEnvPlaceholders(str: string): string[] {\n const matches: string[] = [];\n const regex = /\\$\\{([^}]+)\\}/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(str)) !== null) {\n matches.push(match[1]);\n }\n return matches;\n}\n\nexport function hasEnvPlaceholders(str: string): boolean {\n return findEnvPlaceholders(str).length > 0;\n}\n\n/**\n * Check if a string value has missing environment variables\n */\nfunction checkMissingVars(value: string, env: Record<string, string>): string[] {\n const placeholders = findEnvPlaceholders(value);\n return placeholders.filter((varName) => env[varName] === undefined);\n}\n\n/**\n * Substitute ${VAR_NAME} placeholders in a config object\n * Returns the substituted config and list of missing variables\n */\nexport function substituteConfigEnvVars(\n config: Record<string, unknown>,\n env: Record<string, string>\n): SubstitutionResult<Record<string, unknown>> {\n const missing: string[] = [];\n const result: Record<string, unknown> = {};\n\n for (const key of Object.keys(config)) {\n const value = config[key];\n if (typeof value === 'string') {\n const missingInValue = checkMissingVars(value, env);\n missing.push(...missingInValue);\n // Don't substitute if there are missing vars - let the caller handle the error\n result[key] = missingInValue.length > 0 ? value : substituteEnvVars(value, env);\n } else if (Array.isArray(value)) {\n // Handle arrays\n const newArray: unknown[] = [];\n for (const item of value) {\n if (typeof item === 'string') {\n const missingInItem = checkMissingVars(item, env);\n missing.push(...missingInItem);\n newArray.push(missingInItem.length > 0 ? item : substituteEnvVars(item, env));\n } else if (typeof item === 'object' && item !== null) {\n // Recursively handle nested objects in arrays\n const { result: subResult, missing: subMissing } = substituteConfigEnvVars(\n item as Record<string, unknown>,\n env\n );\n missing.push(...subMissing);\n newArray.push(subResult);\n } else {\n newArray.push(item);\n }\n }\n result[key] = newArray;\n } else if (typeof value === 'object' && value !== null) {\n // Recursively handle nested objects\n const { result: subResult, missing: subMissing } = substituteConfigEnvVars(\n value as Record<string, unknown>,\n env\n );\n missing.push(...subMissing);\n result[key] = subResult;\n } else {\n result[key] = value;\n }\n }\n\n return { result, missing };\n}\n\nexport function substituteStringRecordEnvVars(\n values: Record<string, string> | undefined,\n env: Record<string, string>\n): SubstitutionResult<Record<string, string>> {\n if (!values) {\n return { result: {}, missing: [] };\n }\n\n const missing: string[] = [];\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(values)) {\n const missingInValue = checkMissingVars(value, env);\n missing.push(...missingInValue);\n result[key] = missingInValue.length > 0 ? value : substituteEnvVars(value, env);\n }\n\n return { result, missing };\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { parseAaiJson } from '../parsers/schema.js';\nimport type { AaiJson, SkillConfig } from '../types/aai-json.js';\n\nimport { getManagedAppDir, getManagedAppsRoot } from './paths.js';\nimport { FileRegistry } from './registry.js';\n\nconst REGISTRY_FILE = 'skill-registry.json';\n\nexport interface SkillRegistryEntry {\n id: string;\n appId: string;\n protocol: 'skill';\n config: SkillConfig;\n exposureMode?: 'summary' | 'keywords';\n descriptorPath: string;\n importedAt: string;\n updatedAt: string;\n}\n\n/**\n * Skill Registry\n *\n * Manages imported skill registrations using the unified FileRegistry.\n */\nexport class SkillRegistry {\n private registry: FileRegistry<SkillRegistryEntry>;\n\n constructor() {\n const registryPath = join(getManagedAppsRoot(), REGISTRY_FILE);\n this.registry = new FileRegistry<SkillRegistryEntry>(\n registryPath,\n (entry) => ({\n id: entry.id,\n appId: entry.appId,\n protocol: entry.protocol,\n config: entry.config,\n exposureMode: entry.exposureMode,\n descriptorPath: entry.descriptorPath,\n importedAt: entry.importedAt,\n updatedAt: entry.updatedAt,\n }),\n (raw) => raw as unknown as SkillRegistryEntry\n );\n }\n\n /**\n * List all skill registry entries\n */\n async list(): Promise<SkillRegistryEntry[]> {\n return this.registry.list();\n }\n\n /**\n * Get a specific skill registry entry by ID\n */\n async get(id: string): Promise<SkillRegistryEntry | null> {\n return this.registry.get(id);\n }\n\n /**\n * Add or update a skill registry entry\n */\n async upsert(\n entry: Omit<SkillRegistryEntry, 'id' | 'descriptorPath' | 'importedAt' | 'updatedAt'>,\n descriptor: AaiJson\n ): Promise<SkillRegistryEntry> {\n const existing = await this.get(entry.appId);\n const now = new Date().toISOString();\n const appDir = getManagedAppDir(entry.appId);\n const descriptorPath = join(appDir, 'aai.json');\n\n await mkdir(appDir, { recursive: true });\n await writeFile(descriptorPath, JSON.stringify(descriptor, null, 2), 'utf-8');\n\n const nextEntry: SkillRegistryEntry = {\n id: entry.appId,\n ...entry,\n descriptorPath,\n importedAt: existing?.importedAt ?? now,\n updatedAt: now,\n };\n\n return this.registry.upsert(nextEntry);\n }\n\n /**\n * Delete a skill registry entry\n */\n async delete(id: string): Promise<boolean> {\n return this.registry.delete(id);\n }\n\n /**\n * Load imported skill apps with their descriptors\n */\n async loadApps(): Promise<Array<{ entry: SkillRegistryEntry; descriptor: AaiJson }>> {\n const entries = await this.list();\n const loaded: Array<{ entry: SkillRegistryEntry; descriptor: AaiJson }> = [];\n\n for (const entry of entries) {\n try {\n const raw = await readFile(entry.descriptorPath, 'utf-8');\n loaded.push({\n entry,\n descriptor: parseAaiJson(JSON.parse(raw)),\n });\n } catch (err) {\n // Skip entries with missing or invalid descriptors\n }\n }\n\n return loaded;\n }\n}\n\nlet skillRegistryInstance: SkillRegistry | null = null;\n\nexport function getSkillRegistry(): SkillRegistry {\n if (!skillRegistryInstance) {\n skillRegistryInstance = new SkillRegistry();\n }\n return skillRegistryInstance;\n}\n\n// Backward compatibility exports\nexport async function listSkillRegistryEntries(): Promise<SkillRegistryEntry[]> {\n return getSkillRegistry().list();\n}\n\nexport async function getSkillRegistryEntry(appId: string): Promise<SkillRegistryEntry | null> {\n return getSkillRegistry().get(appId);\n}\n\nexport async function upsertSkillRegistryEntry(\n entry: Omit<SkillRegistryEntry, 'id' | 'descriptorPath' | 'importedAt' | 'updatedAt'>,\n descriptor: AaiJson\n): Promise<SkillRegistryEntry> {\n return getSkillRegistry().upsert(entry, descriptor);\n}\n\nexport async function loadImportedSkillApps(): Promise<Array<{ entry: SkillRegistryEntry; descriptor: AaiJson }>> {\n return getSkillRegistry().loadApps();\n}\n","import { createHash } from 'node:crypto';\n\nexport function slugify(value: string): string {\n const normalized = value\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n return normalized || 'app';\n}\n\nexport function deriveAppId(seed: string, fallback = 'app'): string {\n const hash = createHash('sha1').update(seed).digest('hex').slice(0, 8);\n return `${fallback}-${hash}`;\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\n\nimport type { McpExecutor, McpListedTool } from '../executors/mcp.js';\nimport {\n getMcpRegistryEntry,\n upsertMcpRegistryEntry,\n type McpRegistryEntry,\n} from '../storage/mcp-registry.js';\nimport { getManagedAppDir } from '../storage/paths.js';\nimport { getSkillRegistryEntry, upsertSkillRegistryEntry } from '../storage/skill-registry.js';\nimport type { AaiJson, McpConfig } from '../types/aai-json.js';\nimport { deriveAppId, slugify } from '../utils/ids.js';\nimport {\n getDotenvPath,\n hasEnvPlaceholders,\n loadDotenv,\n substituteConfigEnvVars,\n} from '../utils/dotenv.js';\n\nexport const IMPORT_LIMITS = {\n nameLength: 128,\n commandLength: 256,\n urlLength: 2048,\n pathLength: 2048,\n timeoutMsMax: 2_147_483_647,\n cwdLength: 2048,\n argCount: 64,\n argLength: 1024,\n envCount: 32,\n envKeyLength: 128,\n envValueLength: 2048,\n} as const;\n\nexport const EXPOSURE_LIMITS = {\n summaryLength: 200,\n} as const;\n\nexport interface SummaryDraft {\n summary: string;\n}\n\nexport interface McpImportConfigInput {\n transport?: 'streamable-http' | 'sse';\n url?: string;\n command?: string;\n timeout?: number;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n headers?: Record<string, string>;\n}\n\nexport interface McpImportPreviewOptions {\n config: McpConfig;\n name?: string;\n}\n\nexport interface McpImportOptions extends McpImportPreviewOptions {\n summary: string;\n}\n\nexport interface McpImportPreview {\n appId: string;\n name: string;\n tools: McpListedTool[];\n}\n\nexport interface McpImportedResult {\n entry: McpRegistryEntry;\n descriptor: AaiJson;\n tools: McpListedTool[];\n warnings?: string[];\n}\n\nexport interface SkillImportSourceInput {\n path?: string;\n}\n\nexport interface SkillImportPreviewOptions extends SkillImportSourceInput {}\n\nexport interface SkillImportOptions extends SkillImportSourceInput {}\n\nexport interface SkillImportPreview {\n appId: string;\n name: string;\n description?: string;\n content: string;\n}\n\ninterface SkillFrontMatter {\n name?: string;\n description?: string;\n body: string;\n}\n\nexport function buildMcpImportConfig(input: McpImportConfigInput): McpConfig {\n validateOptionalStringLength(input.command, 'command', IMPORT_LIMITS.commandLength);\n validateOptionalStringLength(input.url, 'url', IMPORT_LIMITS.urlLength);\n validateOptionalStringLength(input.cwd, 'cwd', IMPORT_LIMITS.cwdLength);\n validateOptionalTimeoutMs(input.timeout, 'timeout', IMPORT_LIMITS.timeoutMsMax);\n validateStringArrayLength(input.args, 'args', IMPORT_LIMITS.argCount, IMPORT_LIMITS.argLength);\n validateStringRecordLength(\n input.env,\n 'env',\n IMPORT_LIMITS.envCount,\n IMPORT_LIMITS.envKeyLength,\n IMPORT_LIMITS.envValueLength\n );\n\n const command = input.command && input.command.length > 0 ? input.command : undefined;\n const url = input.url && input.url.length > 0 ? input.url : undefined;\n\n if (command && url) {\n throw new Error('MCP import accepts either command or url, but not both');\n }\n\n if (command) {\n if (input.transport) {\n throw new Error('Local stdio MCP import does not accept transport');\n }\n\n return {\n transport: 'stdio',\n command,\n ...(input.timeout !== undefined ? { timeout: input.timeout } : {}),\n ...(input.args && input.args.length > 0 ? { args: input.args } : {}),\n ...(input.env && Object.keys(input.env).length > 0 ? { env: input.env } : {}),\n ...(input.cwd ? { cwd: input.cwd } : {}),\n };\n }\n\n if (url) {\n return {\n transport: input.transport ?? 'streamable-http',\n url,\n ...(input.timeout !== undefined ? { timeout: input.timeout } : {}),\n ...(input.headers && Object.keys(input.headers).length > 0 ? { headers: input.headers } : {}),\n };\n }\n\n throw new Error('MCP import requires either command or url');\n}\n\nexport function buildSkillImportSource(input: SkillImportSourceInput): SkillImportSourceInput {\n validateOptionalStringLength(input.path, 'path', IMPORT_LIMITS.pathLength);\n\n const path = input.path && input.path.length > 0 ? input.path : undefined;\n\n if (!path) {\n throw new Error('Skill import requires a local path');\n }\n\n return { path };\n}\n\nexport function normalizeSummaryInput(summaryInput: string): SummaryDraft {\n const summary = summaryInput.trim();\n\n if (summary.length === 0) {\n throw new Error('summary cannot be empty.');\n }\n\n if (summary.length > EXPOSURE_LIMITS.summaryLength) {\n throw new Error(\n `summary is too long. Maximum length is ${EXPOSURE_LIMITS.summaryLength} characters.`\n );\n }\n\n return { summary };\n}\n\nexport async function discoverMcpImport(\n executor: McpExecutor,\n options: McpImportPreviewOptions\n): Promise<McpImportPreview> {\n const requestedName = normalizeImportedAppName(options.name);\n const appId = await deriveUniqueMcpAppId(options.config, requestedName);\n const tools = await executor.listTools({\n appId,\n config: options.config,\n });\n const name =\n requestedName ?? (await deriveImportName(executor, options.config, appId));\n return { appId, name, tools };\n}\n\nexport async function importMcpServer(\n executor: McpExecutor,\n options: McpImportOptions\n): Promise<McpImportedResult> {\n const warnings = buildSensitiveValueWarnings(options);\n const { resolvedConfig, missingVars } = await resolveImportedMcpRuntimeValues(options.config);\n\n if (missingVars.length > 0) {\n const uniqueMissing = [...new Set(missingVars)];\n throw new Error(\n `Missing environment variables in ${getDotenvPath()}: ${uniqueMissing\n .map((v) => `$\\{${v}}`)\n .join(', ')}.`\n );\n }\n\n const preview = await discoverMcpImport(executor, {\n ...options,\n config: resolvedConfig,\n });\n const descriptor = buildImportedMcpDescriptor(\n preview.name,\n options.config,\n normalizeSummaryInput(options.summary)\n );\n\n const entry = await upsertMcpRegistryEntry(\n {\n appId: preview.appId,\n protocol: 'mcp',\n config: options.config,\n },\n descriptor\n );\n\n return { entry, descriptor, tools: preview.tools, ...(warnings.length > 0 ? { warnings } : {}) };\n}\n\nexport async function discoverSkillImport(\n options: SkillImportPreviewOptions\n): Promise<SkillImportPreview> {\n const source = buildSkillImportSource(options);\n const content = await readSkillSourceContent(source);\n const appId = await deriveUniqueSkillAppId(source, content);\n const frontMatter = parseSkillFrontMatter(content);\n return {\n appId,\n name: deriveSkillName(source, content),\n description: frontMatter.description,\n content,\n };\n}\n\nexport async function importSkill(\n options: SkillImportOptions\n): Promise<{ appId: string; descriptor: AaiJson; managedPath: string }> {\n // Load environment variables from ~/.aai-gateway/.env\n const { env: dotenv, missing: missingInEnv } = await loadDotenv();\n\n // Substitute ${VAR_NAME} placeholders in path with values from .env\n let finalOptions = options;\n let missingVars: string[] = [...missingInEnv];\n\n if (Object.keys(dotenv).length > 0) {\n const pathOrUrl = options.path;\n if (pathOrUrl) {\n const { result: substituted, missing } = substituteConfigEnvVars(\n { source: pathOrUrl } as Record<string, unknown>,\n dotenv\n );\n const substitutedSource = substituted.source as string;\n missingVars = [...missingVars, ...missing];\n finalOptions = { ...options, path: substitutedSource };\n }\n }\n\n if (missingVars.length > 0) {\n const uniqueMissing = [...new Set(missingVars)];\n throw new Error(\n `Missing environment variables in ${getDotenvPath()}: ${uniqueMissing\n .map((v) => `$\\{${v}}`)\n .join(', ')}.`\n );\n }\n\n const preview = await discoverSkillImport(finalOptions);\n const source = buildSkillImportSource(finalOptions);\n const finalAppDir = getManagedAppDir(preview.appId);\n const finalManagedSkillDir = join(finalAppDir, 'skill');\n await mkdir(finalAppDir, { recursive: true });\n\n await copyDirectory(source.path!, finalManagedSkillDir);\n\n const descriptor: AaiJson = {\n schemaVersion: '2.0',\n version: '1.0.0',\n app: {\n name: {\n default: preview.name,\n en: preview.name,\n },\n },\n access: {\n protocol: 'skill',\n config: {\n path: finalManagedSkillDir,\n },\n },\n exposure: normalizeSummaryInput(deriveSkillSummary(preview)),\n };\n\n await writeFile(join(finalAppDir, 'aai.json'), JSON.stringify(descriptor, null, 2), 'utf-8');\n await upsertSkillRegistryEntry(\n {\n appId: preview.appId,\n protocol: 'skill',\n config: {\n path: finalManagedSkillDir,\n },\n },\n descriptor\n );\n\n return { appId: preview.appId, descriptor, managedPath: finalManagedSkillDir };\n}\n\nfunction buildSensitiveValueWarnings(options: McpImportOptions): string[] {\n const env = options.config.transport === 'stdio' ? options.config.env : undefined;\n const headers = options.config.transport !== 'stdio' ? (options.config as { headers?: Record<string, string> }).headers : undefined;\n if (containsPlaintextSensitiveValues(env) || containsPlaintextSensitiveValues(headers)) {\n return [\n `Sensitive values were provided directly in this chat. Next time, use \\${VAR_NAME} placeholders and store the real values in ${getDotenvPath()} instead of sending secrets in the conversation.`,\n ];\n }\n return [];\n}\n\nfunction containsPlaintextSensitiveValues(values?: Record<string, string>): boolean {\n if (!values) return false;\n return Object.entries(values).some(\n ([key, value]) => isSensitiveKey(key) && !hasEnvPlaceholders(value)\n );\n}\n\nfunction isSensitiveKey(key: string): boolean {\n const normalized = key.toLowerCase();\n return (\n normalized === 'authorization' ||\n normalized.includes('api-key') ||\n normalized.includes('apikey') ||\n normalized.endsWith('_api_key') ||\n normalized.endsWith('_token') ||\n normalized.endsWith('_secret') ||\n normalized.endsWith('_password')\n );\n}\n\nexport async function resolveImportedMcpRuntimeValues(\n config: McpConfig\n): Promise<{\n resolvedConfig: McpConfig;\n missingVars: string[];\n}> {\n const { env: dotenv, missing: missingInEnv } = await loadDotenv();\n const configAsRecord: Record<string, unknown> = JSON.parse(JSON.stringify(config));\n const { result: substitutedConfig, missing: configMissing } = substituteConfigEnvVars(\n configAsRecord,\n dotenv\n );\n\n const missingVars = [...missingInEnv, ...configMissing];\n return {\n resolvedConfig: substitutedConfig as unknown as McpConfig,\n missingVars,\n };\n}\n\nexport function parseSkillFrontMatter(content: string): SkillFrontMatter {\n const match = content.match(/^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n?([\\s\\S]*)$/);\n if (!match) {\n return { body: content };\n }\n\n const [, rawFrontMatter, body] = match;\n const fields = new Map<string, string>();\n for (const line of rawFrontMatter.split('\\n')) {\n const fieldMatch = line.match(/^([A-Za-z0-9_-]+):\\s*(.+)\\s*$/);\n if (!fieldMatch) {\n continue;\n }\n\n const [, key, value] = fieldMatch;\n fields.set(key.toLowerCase(), value.trim().replace(/^['\"]|['\"]$/g, ''));\n }\n\n return {\n name: fields.get('name'),\n description: fields.get('description'),\n body,\n };\n}\n\nasync function deriveImportName(\n executor: McpExecutor,\n config: McpConfig,\n appId: string\n): Promise<string> {\n const serverInfo = await executor.getServerInfo?.({\n appId,\n config,\n });\n if (serverInfo?.name) {\n return serverInfo.name;\n }\n\n return config.transport === 'stdio' ? basename(config.command) : new URL(config.url).hostname;\n}\n\nfunction buildImportedMcpDescriptor(name: string, config: McpConfig, exposure: SummaryDraft): AaiJson {\n return {\n schemaVersion: '2.0',\n version: '1.0.0',\n app: {\n name: {\n default: name,\n en: name,\n },\n },\n access: {\n protocol: 'mcp',\n config,\n },\n exposure,\n };\n}\n\nasync function deriveUniqueMcpAppId(config: McpConfig, name?: string): Promise<string> {\n const preferred = deriveLocalImportId(config, name);\n const existing = await getMcpRegistryEntry(preferred);\n if (!existing) {\n return preferred;\n }\n\n if (JSON.stringify(existing.config) === JSON.stringify(config)) {\n return preferred;\n }\n\n const seed =\n config.transport === 'stdio'\n ? `mcp:${config.command}:${(config.args ?? []).join(' ')}`\n : `mcp:${config.transport}:${config.url}`;\n return deriveAppId(name ? `${seed}:name:${name}` : seed, preferred);\n}\n\nfunction deriveLocalImportId(config: McpConfig, name?: string): string {\n if (name) {\n return slugify(name) || 'mcp';\n }\n\n const seed =\n config.transport === 'stdio'\n ? deriveStdioImportSlug(config.command, config.args)\n : deriveRemoteImportSlug(config.url);\n return slugify(seed) || 'mcp';\n}\n\nfunction deriveStdioImportSlug(command: string, args?: string[]): string {\n const packageArg = args?.find((arg) => isLikelyPackageReference(arg));\n if (packageArg) {\n return simplifyImportedName(packageArg);\n }\n\n return simplifyImportedName(basename(command));\n}\n\nfunction deriveRemoteImportSlug(url: string): string {\n const parsed = new URL(url);\n const hostname = parsed.hostname.replace(/^mcp\\./, '');\n const hostnameWithoutTld = hostname.split('.').filter(Boolean).slice(0, -1).join('-');\n const pathPart = parsed.pathname\n .split('/')\n .map((part) => part.trim())\n .filter(Boolean)\n .find((part) => part !== 'mcp' && part !== 'sse');\n\n return simplifyImportedName(hostnameWithoutTld || pathPart || hostname);\n}\n\nfunction isLikelyPackageReference(value: string): boolean {\n if (!value || value.startsWith('-')) {\n return false;\n }\n\n if (value.startsWith('/') || value.startsWith('./') || value.startsWith('../') || value.includes('\\\\')) {\n return false;\n }\n\n return value.includes('/') || value.includes('@') || /^[a-z0-9][a-z0-9._-]*$/i.test(value);\n}\n\nfunction simplifyImportedName(value: string): string {\n const trimmed = value.trim();\n const withoutScope = trimmed.startsWith('@') ? trimmed.split('/').slice(1).join('/') : trimmed;\n const lastSegment = withoutScope.split('/').filter(Boolean).pop() ?? withoutScope;\n const normalized = lastSegment\n .replace(/^modelcontextprotocol-/, '')\n .replace(/^mcp-server-/, 'server-')\n .replace(/^mcp-/, '');\n\n return slugify(normalized) || 'mcp';\n}\n\nfunction normalizeImportedAppName(name: string | undefined): string | undefined {\n validateOptionalStringLength(name, 'name', IMPORT_LIMITS.nameLength);\n const normalized = name?.trim();\n return normalized && normalized.length > 0 ? normalized : undefined;\n}\n\nfunction deriveSkillName(options: SkillImportSourceInput, content: string): string {\n const frontMatter = parseSkillFrontMatter(content);\n if (frontMatter.name) return frontMatter.name;\n\n const titleMatch = frontMatter.body.match(/^#\\s+(.+)$/m);\n if (titleMatch?.[1]) return titleMatch[1].trim();\n if (options.path) return basename(options.path);\n return 'Imported Skill';\n}\n\nasync function deriveUniqueSkillAppId(options: SkillImportSourceInput, content: string): Promise<string> {\n const preferred = `skill-${simplifyImportedName(deriveSkillName(options, content))}`;\n const existing = await getSkillRegistryEntry(preferred);\n if (!existing) {\n return preferred;\n }\n\n const seed = `skill:${options.path ?? 'imported-skill'}`;\n return deriveAppId(seed, preferred);\n}\n\nasync function readSkillSourceContent(options: SkillImportSourceInput): Promise<string> {\n if (options.path) {\n return readFile(join(options.path, 'SKILL.md'), 'utf-8');\n }\n\n throw new Error('Skill import requires a local path');\n}\n\nasync function copyDirectory(sourceDir: string, targetDir: string): Promise<void> {\n const fs = await import('node:fs/promises');\n await fs.cp(sourceDir, targetDir, { recursive: true });\n}\n\nfunction deriveSkillSummary(preview: SkillImportPreview): string {\n const preferred = preview.description?.trim() || extractFirstParagraph(preview.content) || `Use ${preview.name} through AAI Gateway.`;\n return normalizeSummaryInput(preferred.slice(0, EXPOSURE_LIMITS.summaryLength)).summary;\n}\n\nfunction extractFirstParagraph(content: string): string {\n const frontMatter = parseSkillFrontMatter(content);\n const cleaned = frontMatter.body\n .replace(/^# .+$/m, '')\n .split(/\\n\\s*\\n/)\n .map((block) => block.replace(/\\s+/g, ' ').trim())\n .find((block) => block.length > 0);\n return cleaned ?? '';\n}\n\nfunction validateOptionalStringLength(\n value: string | undefined,\n field: string,\n maxLength: number\n): void {\n if (value === undefined) {\n return;\n }\n\n if (value.length > maxLength) {\n throw new Error(`${field} is too long. Maximum length is ${maxLength} characters.`);\n }\n}\n\nfunction validateOptionalTimeoutMs(\n value: number | undefined,\n field: string,\n maxValue: number\n): void {\n if (value === undefined) {\n return;\n }\n\n if (!Number.isInteger(value) || value <= 0) {\n throw new Error(`${field} must be a positive integer in milliseconds.`);\n }\n\n if (value > maxValue) {\n throw new Error(`${field} is too large. Maximum value is ${maxValue}.`);\n }\n}\n\nfunction validateStringArrayLength(\n values: string[] | undefined,\n field: string,\n maxItems: number,\n maxItemLength: number\n): void {\n if (!values) {\n return;\n }\n\n if (values.length > maxItems) {\n throw new Error(`${field} has too many items. Maximum item count is ${maxItems}.`);\n }\n\n for (const [index, value] of values.entries()) {\n if (value.length > maxItemLength) {\n throw new Error(`${field}[${index}] is too long. Maximum length is ${maxItemLength} characters.`);\n }\n }\n}\n\nfunction validateStringRecordLength(\n record: Record<string, string> | undefined,\n field: string,\n maxItems: number,\n maxKeyLength: number,\n maxValueLength: number\n): void {\n if (!record) {\n return;\n }\n\n const entries = Object.entries(record);\n if (entries.length > maxItems) {\n throw new Error(`${field} has too many entries. Maximum entry count is ${maxItems}.`);\n }\n\n for (const [key, value] of entries) {\n if (key.length > maxKeyLength) {\n throw new Error(\n `${field} key '${key.slice(0, 32)}' is too long. Maximum key length is ${maxKeyLength} characters.`\n );\n }\n\n if (value.length > maxValueLength) {\n throw new Error(\n `${field} value for '${key.slice(0, 32)}' is too long. Maximum value length is ${maxValueLength} characters.`\n );\n }\n }\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\n\nimport { AaiError } from '../errors/errors.js';\nimport { getDotenvPath } from '../utils/dotenv.js';\nimport type {\n McpConfig,\n ExecutionResult,\n} from '../types/index.js';\nimport type { AppCapabilities } from '../types/capabilities.js';\nimport { logger } from '../utils/logger.js';\nimport { AAI_GATEWAY_NAME, AAI_GATEWAY_VERSION } from '../version.js';\nimport { validateArgs, formatValidationErrors } from '../utils/schema-validator.js';\nimport { resolveImportedMcpRuntimeValues } from '../core/importer.js';\n\nimport type { ExecutionObserver } from './events.js';\nimport type { Executor } from './interface.js';\n\nexport interface McpListedTool {\n name: string;\n description?: string;\n inputSchema: {\n type: 'object';\n properties?: Record<string, object>;\n required?: string[];\n [key: string]: unknown;\n };\n}\n\nexport interface McpConnectionTarget {\n appId: string;\n config: McpConfig;\n}\n\ninterface ClientState {\n client: Client;\n targetKey: string;\n config: McpConfig;\n activityListeners: Set<(message: unknown) => void>;\n}\n\ninterface McpServerInfo {\n name?: string;\n version?: string;\n [key: string]: unknown;\n}\n\nconst MCP_DEFAULT_REQUEST_TIMEOUT_MS = 60_000;\n\n/**\n * MCP Executor implementation\n *\n * Implements the unified Executor interface for MCP servers.\n */\nexport class McpExecutor implements Executor {\n readonly protocol = 'mcp';\n private clients = new Map<string, ClientState>();\n\n // Cache: appId → MCP tools (原始数据,含 inputSchema)\n private toolsCache = new Map<string, McpListedTool[]>();\n\n async connect(appId: string, config: McpConfig): Promise<void> {\n const targetKey = JSON.stringify({ config });\n const existing = this.clients.get(appId);\n if (existing && existing.targetKey === targetKey) {\n return;\n }\n\n if (existing) {\n await this.disconnect(appId);\n }\n\n const client = new Client(\n { name: AAI_GATEWAY_NAME, version: AAI_GATEWAY_VERSION },\n { capabilities: {} }\n );\n const transport = this.createTransport(config);\n const activityListeners = new Set<(message: unknown) => void>();\n transport.onmessage = (message) => {\n for (const listener of Array.from(activityListeners)) {\n listener(message);\n }\n };\n\n try {\n await client.connect(transport);\n this.clients.set(appId, { client, targetKey, config, activityListeners });\n logger.info({ appId, config: summarizeMcpConfig(config) }, 'MCP connection established');\n } catch (err) {\n logger.error({ appId, config: summarizeMcpConfig(config), err }, 'MCP connection failed');\n throw new AaiError(\n 'SERVICE_UNAVAILABLE',\n `Failed to connect MCP app '${appId}': ${String(err)}`\n );\n }\n }\n\n async disconnect(appId: string): Promise<void> {\n const existing = this.clients.get(appId);\n if (!existing) return;\n this.clients.delete(appId);\n try {\n await existing.client.close();\n } catch {\n // ignore\n }\n // Clear tools cache for this appId\n this.toolsCache.delete(appId);\n }\n\n\n /**\n * Load app-level capabilities with full tool schemas\n */\n async loadAppCapabilities(appId: string, config: McpConfig): Promise<AppCapabilities> {\n const result = await this.listTools({ appId, config });\n\n // Cache the full tools data for validation during execute\n this.toolsCache.set(appId, result);\n\n const tools = result.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n inputSchema: t.inputSchema ?? { type: 'object' as const, properties: {} },\n }));\n\n return { title: 'MCP Tools', tools };\n }\n\n async execute(\n appId: string,\n config: McpConfig,\n operation: string,\n args: Record<string, unknown>\n ): Promise<ExecutionResult> {\n // Validate against cached schema if available\n let tools = this.toolsCache.get(appId);\n if (!tools) {\n await this.loadAppCapabilities(appId, config);\n tools = this.toolsCache.get(appId);\n }\n const cachedTool = tools?.find((t) => t.name === operation);\n if (cachedTool) {\n const inputSchema = cachedTool.inputSchema ?? { type: 'object', properties: {} };\n const result = validateArgs(args, inputSchema);\n if (!result.valid) {\n const errorMessage = `参数校验失败 for '${operation}'\\n${formatValidationErrors(result)}`;\n return {\n success: false,\n error: errorMessage,\n schema: inputSchema,\n };\n }\n }\n\n try {\n const data = await this.callTool(\n { appId, config },\n operation,\n args\n );\n return { success: true, data };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n async health(appId: string): Promise<boolean> {\n return this.clients.has(appId);\n }\n\n async listTools(target: McpConnectionTarget): Promise<McpListedTool[]> {\n try {\n const client = await this.connectLegacy(target);\n const result = await client.listTools();\n logger.info(\n { appId: target.appId, config: summarizeMcpConfig(target.config), toolCount: result.tools.length },\n 'MCP tools listed'\n );\n return result.tools as McpListedTool[];\n } catch (err) {\n logger.error(\n { appId: target.appId, config: summarizeMcpConfig(target.config), err },\n 'Failed to list MCP tools'\n );\n throw new AaiError(\n 'EXECUTION_ERROR',\n `Failed to list tools for '${target.appId}': ${String(err)}`\n );\n }\n }\n\n async getServerInfo(target: McpConnectionTarget): Promise<McpServerInfo | undefined> {\n const client = await this.connectLegacy(target);\n return client.getServerVersion() as McpServerInfo | undefined;\n }\n\n async callTool(\n target: McpConnectionTarget,\n toolName: string,\n args: Record<string, unknown>,\n observer?: ExecutionObserver\n ): Promise<unknown> {\n const execute = async (): Promise<unknown> => {\n const client = await this.connectLegacy(target);\n const state = this.clients.get(target.appId);\n if (!state) {\n throw new AaiError('SERVICE_UNAVAILABLE', `MCP app '${target.appId}' is not connected`);\n }\n\n const activityListener = (message: unknown) => {\n const notificationMessage = extractNotificationMessage(message);\n if (notificationMessage) {\n void observer?.onMessage?.({ message: notificationMessage });\n }\n };\n\n state.activityListeners.add(activityListener);\n\n try {\n const timeoutMs = getMcpRequestTimeoutMs(target.config);\n const result = (await client.callTool(\n {\n name: toolName,\n arguments: args,\n },\n undefined,\n {\n timeout: timeoutMs,\n onprogress: (progress) => {\n void observer?.onProgress?.({\n progress: progress.progress,\n ...(progress.message ? { message: progress.message } : {}),\n });\n },\n }\n )) as { content?: unknown };\n\n state.activityListeners.delete(activityListener);\n logger.info(\n {\n appId: target.appId,\n tool: toolName,\n config: summarizeMcpConfig(target.config),\n },\n 'MCP tool call completed'\n );\n return result;\n } catch (err) {\n state.activityListeners.delete(activityListener);\n logger.error(\n {\n appId: target.appId,\n tool: toolName,\n config: summarizeMcpConfig(target.config),\n err,\n },\n 'MCP tool call failed'\n );\n throw err;\n }\n };\n\n try {\n return await execute();\n } catch (err) {\n await this.close(target.appId);\n try {\n return await execute();\n } catch (retryErr) {\n logger.error(\n {\n appId: target.appId,\n tool: toolName,\n config: summarizeMcpConfig(target.config),\n err: retryErr ?? err,\n },\n 'MCP tool call failed after retry'\n );\n throw new AaiError(\n 'EXECUTION_ERROR',\n `MCP tool '${toolName}' failed for '${target.appId}': ${String(retryErr ?? err)}`\n );\n }\n }\n }\n\n async close(appId: string): Promise<void> {\n return this.disconnect(appId);\n }\n\n private createTransport(config: McpConfig) {\n switch (config.transport) {\n case 'stdio':\n return new StdioClientTransport({\n command: config.command,\n args: config.args,\n env: config.env,\n cwd: config.cwd,\n stderr: 'pipe',\n });\n case 'streamable-http':\n return new StreamableHTTPClientTransport(new URL(config.url), {\n requestInit: config.headers ? { headers: config.headers } : undefined,\n });\n case 'sse':\n return new SSEClientTransport(new URL(config.url), {\n requestInit: config.headers ? { headers: config.headers } : undefined,\n });\n }\n }\n\n private async connectLegacy(target: McpConnectionTarget): Promise<Client> {\n const resolvedTarget = await this.resolveTarget(target);\n await this.connect(resolvedTarget.appId, resolvedTarget.config);\n const state = this.clients.get(target.appId);\n if (!state) {\n throw new AaiError('SERVICE_UNAVAILABLE', `MCP app '${target.appId}' is not connected`);\n }\n return state.client;\n }\n\n private async resolveTarget(target: McpConnectionTarget): Promise<McpConnectionTarget> {\n const { resolvedConfig, missingVars } = await resolveImportedMcpRuntimeValues(target.config);\n\n if (missingVars.length > 0) {\n const uniqueMissing = [...new Set(missingVars)];\n throw new AaiError(\n 'INVALID_REQUEST',\n `Missing environment variables for MCP app '${target.appId}': ${uniqueMissing.map((name) => `$\\{${name}}`).join(', ')}`,\n {\n code: 'MISSING_ENV_VARS',\n missingVars: uniqueMissing,\n envFile: getDotenvPath(),\n setupExample: uniqueMissing.map((name) => `${name}=your_value_here`),\n userAction:\n `Do not read ${getDotenvPath()}. Help the user open it and ask them to paste the values themselves.`,\n }\n );\n }\n\n return { appId: target.appId, config: resolvedConfig };\n }\n}\n\nfunction getMcpRequestTimeoutMs(config: McpConfig): number {\n return config.timeout ?? MCP_DEFAULT_REQUEST_TIMEOUT_MS;\n}\n\nfunction extractNotificationMessage(message: unknown): string | null {\n if (!message || typeof message !== 'object') {\n return null;\n }\n\n const method = (message as { method?: unknown }).method;\n if (method !== 'notifications/message') {\n return null;\n }\n\n const params = (message as { params?: unknown }).params;\n if (!params || typeof params !== 'object') {\n return null;\n }\n\n const data = (params as { data?: unknown }).data;\n if (typeof data === 'string' && data.length > 0) {\n return data;\n }\n\n if (data !== undefined) {\n const serialized = JSON.stringify(data);\n return serialized && serialized !== 'null' ? serialized : null;\n }\n\n return null;\n}\n\nfunction summarizeMcpConfig(config: McpConfig): Record<string, unknown> {\n switch (config.transport) {\n case 'stdio':\n return {\n transport: config.transport,\n command: config.command,\n argvLength: config.args?.length ?? 0,\n ...(config.cwd ? { cwd: config.cwd } : {}),\n ...(config.env ? { envKeys: Object.keys(config.env) } : {}),\n ...(config.timeout ? { timeout: config.timeout } : {}),\n };\n case 'streamable-http':\n case 'sse':\n return {\n transport: config.transport,\n url: config.url,\n ...(config.timeout ? { timeout: config.timeout } : {}),\n };\n }\n}\n\nlet singleton: McpExecutor | undefined;\n\nexport function getMcpExecutor(): McpExecutor {\n if (!singleton) {\n singleton = new McpExecutor();\n }\n return singleton;\n}\n","import { exec } from 'node:child_process';\nimport { access, stat } from 'node:fs/promises';\nimport { promisify } from 'node:util';\n\nimport type { AaiJson } from '../types/aai-json.js';\n\nconst execAsync = promisify(exec);\n\nexport interface DiscoveryCheckResult {\n available: boolean;\n location: string | null;\n}\n\nexport async function evaluateDescriptorAvailability(\n descriptor: AaiJson\n): Promise<DiscoveryCheckResult> {\n const checks = descriptor.discovery?.checks;\n if (!checks || checks.length === 0) {\n return { available: true, location: null };\n }\n\n let location: string | null = null;\n\n for (const check of checks) {\n switch (check.kind) {\n case 'command': {\n const commandPath = await resolveCommandPath(check.command);\n if (!commandPath) {\n return { available: false, location: null };\n }\n\n if (!location) {\n location = commandPath;\n }\n break;\n }\n case 'file': {\n const filePath = await resolveFilePath(check.path);\n if (!filePath) {\n return { available: false, location: null };\n }\n\n if (!location) {\n location = filePath;\n }\n break;\n }\n case 'path': {\n const pathLocation = await resolveDirectoryPath(check.path);\n if (!pathLocation) {\n return { available: false, location: null };\n }\n\n if (!location) {\n location = pathLocation;\n }\n break;\n }\n }\n }\n\n return { available: true, location };\n}\n\nasync function resolveCommandPath(command: string): Promise<string | null> {\n try {\n const query = process.platform === 'win32' ? `where ${command}` : `which ${command}`;\n const { stdout } = await execAsync(query);\n return stdout.trim().split('\\n')[0] || null;\n } catch {\n return null;\n }\n}\n\nasync function resolveFilePath(path: string): Promise<string | null> {\n try {\n const fileStat = await stat(path);\n return fileStat.isFile() ? path : null;\n } catch {\n return null;\n }\n}\n\nasync function resolveDirectoryPath(path: string): Promise<string | null> {\n try {\n const pathStat = await stat(path);\n if (pathStat.isDirectory()) {\n await access(path);\n return path;\n }\n return null;\n } catch {\n return null;\n }\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { evaluateDescriptorAvailability } from '../discovery/checks.js';\nimport { parseAaiJson } from '../parsers/schema.js';\nimport type { RuntimeAppRecord } from '../types/aai-json.js';\n\nimport { getManagedAppsRoot } from './paths.js';\n\nexport interface ManagedEntry {\n id: string;\n appId: string;\n protocol: 'mcp' | 'skill' | 'cli' | 'acp-agent';\n descriptorPath: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Managed Registry\n *\n * Manages gateway-managed app descriptors (imported MCP servers, skills, CLI apps, etc.).\n * This registry is based on the file system structure rather than a separate registry file.\n */\nexport class ManagedRegistry {\n /**\n * Scan the managed apps directory and return all valid app records\n */\n async scan(): Promise<RuntimeAppRecord[]> {\n try {\n const records: RuntimeAppRecord[] = [];\n const root = getManagedAppsRoot();\n let entries;\n try {\n entries = await readdir(root, { withFileTypes: true });\n } catch {\n return [];\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue;\n }\n\n try {\n const descriptorPath = join(root, entry.name, 'aai.json');\n const descriptor = parseAaiJson(JSON.parse(await readFile(descriptorPath, 'utf-8')));\n const availability = await evaluateDescriptorAvailability(descriptor);\n if (!availability.available) {\n continue;\n }\n const protocol = descriptor.access.protocol;\n\n let source: RuntimeAppRecord['source'];\n switch (protocol) {\n case 'mcp':\n source = 'mcp-import';\n break;\n case 'skill':\n source = 'skill-import';\n break;\n case 'acp-agent':\n source = 'acp-agent';\n break;\n case 'cli':\n source = 'cli';\n break;\n default:\n continue;\n }\n\n records.push({\n appId: entry.name,\n descriptor,\n source,\n location: availability.location ?? descriptorPath,\n });\n } catch {\n // Skip non-app directories or invalid descriptors\n }\n }\n\n return records;\n } catch {\n return [];\n }\n }\n\n /**\n * Get a specific managed app by appId\n */\n async get(appId: string): Promise<RuntimeAppRecord | null> {\n const records = await this.scan();\n return records.find((r) => r.appId === appId) ?? null;\n }\n\n /**\n * Delete a managed app by appId\n * @deprecated This method is not implemented yet. Use the specific registries (McpRegistry, SkillRegistry) for deletion.\n */\n async delete(_appId: string): Promise<boolean> {\n // This would need to interact with the specific registries\n // For now, we'll return false to indicate it's not implemented\n return false;\n }\n\n /**\n * Check if a managed app exists\n */\n async has(appId: string): Promise<boolean> {\n const app = await this.get(appId);\n return app !== null;\n }\n}\n\n/**\n * Create a singleton Managed registry instance\n */\nlet managedRegistryInstance: ManagedRegistry | null = null;\nexport function getManagedRegistry(): ManagedRegistry {\n if (!managedRegistryInstance) {\n managedRegistryInstance = new ManagedRegistry();\n }\n return managedRegistryInstance;\n}\n\n// Backward compatibility exports\nexport async function loadManagedDescriptors(): Promise<RuntimeAppRecord[]> {\n return getManagedRegistry().scan();\n}\n","import { mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nimport { getAaiHomeDir } from '../utils/config.js';\nimport { slugify } from '../utils/ids.js';\n\nexport interface AgentState {\n agentId: string;\n agentType?: string;\n callerName: string;\n appOverrides: Record<string, 'enabled' | 'disabled'>;\n updatedAt: string;\n}\n\nexport interface AppPolicyState {\n defaultEnabled: 'all' | 'importer-only';\n importerAgentId?: string;\n updatedAt: string;\n}\n\nfunction getAgentsRoot(): string {\n return join(getAaiHomeDir(), 'agents');\n}\n\nfunction getAgentStatePath(agentId: string): string {\n return join(getAgentsRoot(), `${agentId}.json`);\n}\n\nfunction getAppStatePath(appId: string): string {\n return join(getAaiHomeDir(), 'apps', `${appId}.json`);\n}\n\nexport function deriveCallerId(input: { callerId?: string; callerName?: string }): string {\n if (input.callerId && input.callerId.trim().length > 0) {\n return slugify(input.callerId);\n }\n if (input.callerName && input.callerName.trim().length > 0) {\n return slugify(input.callerName);\n }\n return 'unknown-client';\n}\n\nexport async function loadAgentState(agentId: string): Promise<AgentState | null> {\n try {\n const raw = await readFile(getAgentStatePath(agentId), 'utf-8');\n return JSON.parse(raw) as AgentState;\n } catch {\n return null;\n }\n}\n\nexport async function saveAgentState(state: AgentState): Promise<void> {\n const path = getAgentStatePath(state.agentId);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(state, null, 2), 'utf-8');\n}\n\nexport async function upsertAgentState(input: {\n agentId: string;\n callerName: string;\n agentType?: string;\n}): Promise<AgentState> {\n const existing = await loadAgentState(input.agentId);\n const next: AgentState = {\n agentId: input.agentId,\n callerName: input.callerName,\n agentType: input.agentType ?? existing?.agentType,\n appOverrides: existing?.appOverrides ?? {},\n updatedAt: new Date().toISOString(),\n };\n await saveAgentState(next);\n return next;\n}\n\nexport async function disableAppForAgent(agentId: string, appId: string): Promise<AgentState> {\n const state = (await loadAgentState(agentId)) ?? {\n agentId,\n callerName: agentId,\n appOverrides: {},\n updatedAt: new Date().toISOString(),\n };\n\n state.appOverrides[appId] = 'disabled';\n state.updatedAt = new Date().toISOString();\n await saveAgentState(state);\n return state;\n}\n\nexport async function enableAppForAgent(agentId: string, appId: string): Promise<AgentState> {\n const state = await loadAgentState(agentId);\n if (!state) {\n const next: AgentState = {\n agentId,\n callerName: agentId,\n appOverrides: { [appId]: 'enabled' },\n updatedAt: new Date().toISOString(),\n };\n await saveAgentState(next);\n return next;\n }\n\n state.appOverrides[appId] = 'enabled';\n state.updatedAt = new Date().toISOString();\n await saveAgentState(state);\n return state;\n}\n\nexport async function loadAppPolicyState(appId: string): Promise<AppPolicyState | null> {\n try {\n const raw = await readFile(getAppStatePath(appId), 'utf-8');\n return JSON.parse(raw) as AppPolicyState;\n } catch {\n return null;\n }\n}\n\nexport async function saveAppPolicyState(\n appId: string,\n state: AppPolicyState\n): Promise<void> {\n const path = getAppStatePath(appId);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(state, null, 2), 'utf-8');\n}\n\nexport async function deleteAppPolicyState(appId: string): Promise<void> {\n await rm(getAppStatePath(appId), { force: true });\n}\n\nexport async function removeAppFromAllAgents(appId: string): Promise<void> {\n let entries: string[] = [];\n try {\n entries = await readdir(getAgentsRoot());\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (!entry.endsWith('.json')) continue;\n\n const agentId = entry.slice(0, -'.json'.length);\n const state = await loadAgentState(agentId);\n if (!state) continue;\n\n if (state.appOverrides[appId]) {\n delete state.appOverrides[appId];\n state.updatedAt = new Date().toISOString();\n await saveAgentState(state);\n }\n }\n}\n","export const SEARCH_DISCOVER_TOOL_NAME = 'search:discover';\n\nexport const searchDiscoverInputSchema: Record<string, unknown> = {\n type: 'object',\n properties: {},\n additionalProperties: false,\n};\n\nconst SEARCH_DISCOVER_GUIDE = `# MCP & Skill Search Guide\n\nUse this guide when you need to find new MCP servers or skills for the user.\n\n## Where to Search\n\n### MCP Sources\n- Official MCP Registry: https://github.com/modelcontextprotocol/registry\n- Official MCP Servers: https://github.com/modelcontextprotocol/servers\n- GitHub search: repositories, README files, release pages, and installation docs\n\n### Skill Sources\n- OpenAI Skills: https://github.com/openai/skills\n- Anthropic Skills: https://github.com/anthropics/skills\n- OpenClaw Skills: https://github.com/openclaw/skills\n- GitHub search: repositories and real skill directory paths\n- Community skill lists and registries\n\n## What to Collect\n\n### Collect for user-facing comparison\nFor each candidate, collect:\n- Type: MCP or Skill\n- Name\n- Source\n- Trust: official / community / experimental\n- Score: use the rating from the source when available, such as GitHub stars or a platform rating; omit it when no rating is available\n- What it does: one short plain-language summary\n\n### Collect for installation handoff only\nDo not show these details in the main comparison table unless the user asks.\n\nFor MCP candidates, also collect:\n- Install method:\n - local stdio: command + args\n - remote: transport + url\n- Whether headers are required\n- Whether env variables are required\n- The source page that shows the install configuration\n\nFor Skill candidates, also collect:\n- Download source URL\n- The real skill directory path\n- Whether the whole skill directory must be downloaded\n- The source page that shows the download path or repository path\n\n## How to Evaluate Candidates\n\nWhen comparing candidates, consider:\n- Relevance to the user's task\n- Whether the source is official or community-maintained\n- Maintenance quality: recent activity, clear README, usable install docs\n- Source-provided popularity or rating signals when available\n- Safety and clarity of installation requirements\n\n## How to Present Results to the User\n\nAfter searching, show the user a short comparison table.\n\nRecommended columns:\n- Type\n- Name\n- Source\n- Trust\n- Score\n- What it does\n\nKeep the table short and readable.\nDo not put raw install config, headers, env variables, or download payloads into the main user-facing table.\n\n## User Confirmation\n\nAfter showing the comparison table:\n1. Ask the user which MCP or skill they want to install.\n2. Wait for explicit user confirmation.\n3. Only then continue with import.\n\n## Import Next Step\n\nAfter the user confirms a candidate:\n\n- If the user chose an MCP server:\n - Use \\`mcp:import\\`\n\n- If the user chose a skill:\n - First make sure the whole skill directory is available locally\n - Then use \\`skill:import\\`\n\n## Important Notes\n\n- \\`search:discover\\` only provides search guidance.\n- You must perform the actual web search yourself.\n- You must prepare the comparison table yourself.\n- You must ask for user confirmation yourself.\n- You must call the appropriate AAI import tool yourself after confirmation.\n`;\n\nexport function parseSearchDiscoverArguments(args: Record<string, unknown> | undefined): void {\n if (!args || Object.keys(args).length === 0) {\n return;\n }\n\n throw new Error(`${SEARCH_DISCOVER_TOOL_NAME} does not accept arguments`);\n}\n\nexport function buildSearchDiscoverResponse(): string {\n return SEARCH_DISCOVER_GUIDE;\n}\n","/**\n * MCP Argument Parsers\n *\n * Handles parsing and validation of MCP tool call arguments.\n * These are MCP-protocol-specific input normalization functions.\n */\n\nimport type { McpConfig } from '../types/aai-json.js';\nimport { AaiError } from '../errors/errors.js';\nimport {\n buildMcpImportConfig,\n buildSkillImportSource,\n normalizeSummaryInput,\n} from './importer.js';\n\nexport interface ParsedMcpImportArgs {\n name?: string;\n config: McpConfig;\n metadata?: {\n summary: string;\n enableScope: 'current' | 'all';\n };\n}\n\nexport interface ParsedSkillImportArgs {\n path: string;\n}\n\nexport function parseMcpImportArguments(args: Record<string, unknown> | undefined): ParsedMcpImportArgs {\n try {\n // Normalize: when command is an array (common in standard MCP JSON configs),\n // split into command (first element) + args (remaining elements).\n let command = args?.command;\n let argsArray = args?.args;\n if (Array.isArray(command)) {\n const parts = command.filter((item): item is string => typeof item === 'string');\n if (parts.length > 0) {\n command = parts[0];\n if (parts.length > 1) {\n argsArray = [...parts.slice(1), ...(Array.isArray(argsArray) ? argsArray : [])];\n }\n }\n }\n\n // Normalize: accept \"environment\" as an alias for \"env\".\n const env = args?.env ?? args?.environment;\n\n // Normalize: accept \"headers\" for remote MCP imports.\n const headers = args?.headers;\n\n return {\n name: asOptionalString(args?.name),\n config: buildMcpImportConfig({\n transport:\n args?.transport === 'streamable-http' || args?.transport === 'sse'\n ? args.transport\n : undefined,\n url: asOptionalString(args?.url),\n command: asOptionalString(command),\n timeout: asOptionalPositiveInteger(args?.timeout, 'timeout'),\n args: asOptionalStringArray(argsArray, 'args'),\n env: asOptionalStringRecord(env, 'env'),\n cwd: asOptionalString(args?.cwd),\n headers: asOptionalStringRecord(headers, 'headers'),\n }),\n metadata: parseOptionalMcpImportMetadata(args),\n };\n } catch (err) {\n throw new AaiError('INVALID_REQUEST', err instanceof Error ? err.message : String(err));\n }\n}\n\nexport function parseSkillImportArguments(args: Record<string, unknown> | undefined): ParsedSkillImportArgs {\n try {\n const source = buildSkillImportSource({\n path: asOptionalString(args?.path),\n });\n\n return { path: source.path! };\n } catch (err) {\n throw new AaiError('INVALID_REQUEST', err instanceof Error ? err.message : String(err));\n }\n}\n\nfunction parseOptionalMcpImportMetadata(args: Record<string, unknown> | undefined):\n | { summary: string; enableScope: 'current' | 'all' }\n | undefined {\n const hasSummary = args?.summary !== undefined;\n const hasEnableScope = args?.enableScope !== undefined;\n const providedCount = Number(hasSummary) + Number(hasEnableScope);\n\n if (providedCount === 0) return undefined;\n\n if (providedCount !== 2) {\n throw new Error(\n \"MCP import requires 'summary' and 'enableScope' together. Omit both for inspection, or provide both for the final import.\"\n );\n }\n\n const summary = asOptionalString(args?.summary);\n const enableScope = parseEnableScope(args?.enableScope);\n\n if (!summary) {\n throw new Error(\"Import received an empty 'summary'\");\n }\n\n return { ...normalizeSummaryInput(summary), enableScope };\n}\n\nfunction parseEnableScope(value: unknown): 'current' | 'all' {\n if (value === 'current' || value === 'all') return value;\n throw new Error(\"MCP import requires 'enableScope' to be either 'current' or 'all'\");\n}\n\n// ============================================================\n// Primitive type helpers\n// ============================================================\n\nexport function asOptionalString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nexport function asOptionalPositiveInteger(value: unknown, field: string): number | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'number' || !Number.isInteger(value) || value <= 0) {\n throw new Error(`${field} must be a positive integer in milliseconds`);\n }\n return value;\n}\n\nexport function asOptionalStringArray(value: unknown, field: string): string[] | undefined {\n const normalized = tryParseJsonString(value);\n if (normalized === undefined) return undefined;\n if (!Array.isArray(normalized)) {\n throw new AaiError('INVALID_REQUEST', `${field} must be an array of strings`);\n }\n if (normalized.find((item) => typeof item !== 'string') !== undefined) {\n throw new AaiError('INVALID_REQUEST', `${field} must contain only strings`);\n }\n return normalized as string[];\n}\n\nexport function asOptionalStringRecord(value: unknown, field: string): Record<string, string> | undefined {\n const normalized = tryParseJsonString(value);\n if (normalized === undefined) return undefined;\n if (!isStringRecord(normalized)) {\n throw new AaiError('INVALID_REQUEST', `${field} must be an object with string values`);\n }\n return normalized;\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false;\n return Object.values(value).every((item) => typeof item === 'string');\n}\n\nfunction tryParseJsonString(value: unknown): unknown {\n if (typeof value !== 'string') return value;\n const trimmed = value.trim();\n if (trimmed.length === 0 || (!trimmed.startsWith('[') && !trimmed.startsWith('{'))) return value;\n try {\n return JSON.parse(trimmed);\n } catch {\n return value;\n }\n}\n\nexport function normalizeArgumentsWithSchema(value: unknown, schema: Record<string, unknown>): unknown {\n const normalized = parseJsonStringForExpectedType(value, schema);\n const type = schema.type as string | undefined;\n\n if (\n type === 'object' &&\n normalized &&\n typeof normalized === 'object' &&\n !Array.isArray(normalized)\n ) {\n const properties = schema.properties as Record<string, unknown> | undefined;\n const additionalProperties = schema.additionalProperties;\n const result: Record<string, unknown> = {};\n\n for (const [key, item] of Object.entries(normalized as Record<string, unknown>)) {\n const propertySchema = properties?.[key];\n if (propertySchema && typeof propertySchema === 'object' && !Array.isArray(propertySchema)) {\n result[key] = normalizeArgumentsWithSchema(item, propertySchema as Record<string, unknown>);\n continue;\n }\n if (\n additionalProperties &&\n typeof additionalProperties === 'object' &&\n !Array.isArray(additionalProperties)\n ) {\n result[key] = normalizeArgumentsWithSchema(\n item,\n additionalProperties as Record<string, unknown>\n );\n continue;\n }\n result[key] = item;\n }\n return result;\n }\n\n if (type === 'array' && Array.isArray(normalized)) {\n const itemSchema = schema.items;\n if (itemSchema && typeof itemSchema === 'object' && !Array.isArray(itemSchema)) {\n return normalized.map((item) =>\n normalizeArgumentsWithSchema(item, itemSchema as Record<string, unknown>)\n );\n }\n }\n\n return normalized;\n}\n\nfunction parseJsonStringForExpectedType(value: unknown, schema: Record<string, unknown>): unknown {\n if (typeof value !== 'string') return value;\n const expectedType = schema.type as string | undefined;\n const trimmed = value.trim();\n\n if (expectedType === 'object' && trimmed.startsWith('{')) {\n try { return JSON.parse(trimmed); } catch { return value; }\n }\n if (expectedType === 'array' && trimmed.startsWith('[')) {\n try { return JSON.parse(trimmed); } catch { return value; }\n }\n return value;\n}\n\n// ============================================================\n// Log summarization helpers\n// ============================================================\n\nexport function summarizeExecArgs(args: Record<string, unknown>): Record<string, unknown> {\n const summary: Record<string, unknown> = { keys: Object.keys(args) };\n\n if (typeof args.sessionId === 'string') summary.sessionId = args.sessionId;\n if (typeof args.turnId === 'string') summary.turnId = args.turnId;\n\n if (typeof args.text === 'string') {\n summary.textLength = args.text.length;\n summary.textPreview = truncateLogPreview(args.text);\n } else if (typeof args.message === 'string') {\n summary.messageLength = args.message.length;\n summary.messagePreview = truncateLogPreview(args.message);\n } else if (Array.isArray(args.prompt)) {\n summary.promptBlocks = args.prompt.length;\n }\n\n if (typeof args.cwd === 'string') summary.cwd = args.cwd;\n return summary;\n}\n\nexport function summarizeExecResult(result: unknown): Record<string, unknown> | undefined {\n if (!result || typeof result !== 'object' || Array.isArray(result)) return undefined;\n const record = result as Record<string, unknown>;\n const summary: Record<string, unknown> = {};\n\n if (typeof record.turnId === 'string') summary.turnId = record.turnId;\n if (typeof record.sessionId === 'string') summary.sessionId = record.sessionId;\n if (typeof record.done === 'boolean') summary.done = record.done;\n if (typeof record.cancelled === 'boolean') summary.cancelled = record.cancelled;\n if (typeof record.status === 'string') summary.status = record.status;\n if (typeof record.error === 'string') summary.error = truncateLogPreview(record.error);\n if (Array.isArray(record.content)) {\n summary.contentBlocks = record.content.length;\n const textPreview = previewStructuredContent(record.content);\n if (textPreview) summary.textPreview = textPreview;\n }\n\n return Object.keys(summary).length > 0 ? summary : undefined;\n}\n\nexport function summarizeRawImportArgs(\n args: Record<string, unknown> | undefined\n): Record<string, unknown> {\n if (!args) return {};\n return {\n keys: Object.keys(args),\n ...(typeof args.name === 'string' ? { name: args.name } : {}),\n ...(typeof args.command === 'string' ? { command: args.command } : {}),\n ...(Array.isArray(args.args) ? { argvLength: args.args.length } : {}),\n ...(typeof args.cwd === 'string' ? { cwd: args.cwd } : {}),\n ...(typeof args.url === 'string' ? { url: args.url } : {}),\n ...(typeof args.transport === 'string' ? { transport: args.transport } : {}),\n ...(typeof args.path === 'string' ? { path: args.path } : {}),\n ...(typeof args.enableScope === 'string' ? { enableScope: args.enableScope } : {}),\n ...(typeof args.summary === 'string' ? { summaryLength: args.summary.length } : {}),\n ...(args.env && typeof args.env === 'object' && !Array.isArray(args.env)\n ? { envKeys: Object.keys(args.env as Record<string, unknown>) }\n : {}),\n };\n}\n\nexport function summarizeMcpImportRequest(options: ParsedMcpImportArgs): Record<string, unknown> {\n return {\n ...(options.name ? { name: options.name } : {}),\n config: summarizeMcpConfig(options.config),\n ...(options.metadata\n ? { summaryLength: options.metadata.summary.length, enableScope: options.metadata.enableScope }\n : {}),\n };\n}\n\nexport function summarizeSkillImportRequest(options: ParsedSkillImportArgs): Record<string, unknown> {\n return { path: options.path };\n}\n\nfunction summarizeMcpConfig(config: McpConfig): Record<string, unknown> {\n switch (config.transport) {\n case 'stdio':\n return {\n transport: config.transport,\n command: config.command,\n argvLength: config.args?.length ?? 0,\n ...(config.cwd ? { cwd: config.cwd } : {}),\n ...(config.env ? { envKeys: Object.keys(config.env) } : {}),\n ...(config.timeout ? { timeout: config.timeout } : {}),\n };\n case 'streamable-http':\n case 'sse':\n return {\n transport: config.transport,\n url: config.url,\n ...(config.timeout ? { timeout: config.timeout } : {}),\n };\n }\n}\n\nfunction truncateLogPreview(value: string, maxChars = 160): string {\n return value.length <= maxChars ? value : `${value.slice(0, maxChars)}...`;\n}\n\nfunction previewStructuredContent(content: unknown[], maxChars = 160): string | undefined {\n const text = content\n .filter(\n (item): item is { type?: unknown; text?: unknown } =>\n !!item && typeof item === 'object' && !Array.isArray(item)\n )\n .filter((item) => item.type === 'text' && typeof item.text === 'string')\n .map((item) => item.text as string)\n .join('');\n return text.length > 0 ? truncateLogPreview(text, maxChars) : undefined;\n}\n","/**\n * Gateway Tool Definitions\n *\n * Defines the MCP tool schemas exposed by AAI Gateway.\n * Separated from protocol handling for clarity.\n */\n\nimport { EXPOSURE_LIMITS, IMPORT_LIMITS } from './importer.js';\nimport {\n SEARCH_DISCOVER_TOOL_NAME,\n searchDiscoverInputSchema,\n} from './search-guidance.js';\nimport { getDotenvPath } from '../utils/dotenv.js';\n\nexport interface GatewayToolDefinition {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n listInputSchema?: Record<string, unknown>;\n}\n\nexport function buildGatewayToolDefinitions(): GatewayToolDefinition[] {\n return [\n {\n name: 'aai:exec',\n description:\n 'Execute a tool. Read the guide first (e.g. app:*, mcp:import) — it contains the full schema.',\n inputSchema: {\n type: 'object',\n properties: {\n app: {\n type: 'string',\n description: 'Required for app tools, omit or use \"gateway\" for gateway tools.',\n },\n tool: {\n type: 'string',\n description: 'Tool name within the app, not prefixed with app id.',\n },\n args: {\n type: 'object',\n additionalProperties: true,\n description: 'Arguments for the selected tool.',\n },\n },\n required: ['tool'],\n },\n },\n {\n name: 'mcp:import',\n description: 'Call this to import an MCP server. Returns the import workflow and parameters.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: `Optional. Display name for the imported app. Maximum length: ${IMPORT_LIMITS.nameLength} characters.`,\n },\n transport: {\n type: 'string',\n enum: ['streamable-http', 'sse'],\n description:\n 'Optional. Only used with url for remote MCP imports. Defaults to \"streamable-http\".',\n },\n command: {\n type: 'string',\n description: `Use this for a local stdio MCP import. The executable to launch. Maximum length: ${IMPORT_LIMITS.commandLength} characters.`,\n },\n args: {\n type: 'array',\n items: { type: 'string' },\n description: `Optional for local stdio MCP imports. Command arguments. Maximum ${IMPORT_LIMITS.argCount} items, each at most ${IMPORT_LIMITS.argLength} characters.`,\n },\n env: {\n type: 'object',\n additionalProperties: { type: 'string' },\n description: `Optional for local stdio MCP imports. Environment variables. Maximum ${IMPORT_LIMITS.envCount} entries.`,\n },\n cwd: {\n type: 'string',\n description: `Optional for local stdio MCP imports. Working directory. Maximum length: ${IMPORT_LIMITS.cwdLength} characters.`,\n },\n timeout: {\n type: 'integer',\n description: `Optional. MCP tool execution timeout in milliseconds. Default 60000. Maximum: ${IMPORT_LIMITS.timeoutMsMax}.`,\n },\n url: {\n type: 'string',\n description: `Use this for a remote MCP import. The remote MCP endpoint URL. Maximum length: ${IMPORT_LIMITS.urlLength} characters.`,\n },\n headers: {\n type: 'object',\n additionalProperties: { type: 'string' },\n description:\n 'Optional for remote MCP imports. HTTP headers (e.g. Authorization). Use ${VAR_NAME} placeholders for sensitive values.',\n },\n summary: {\n type: 'string',\n description: `Optional on first call, required on second. Short English summary. Maximum length: ${EXPOSURE_LIMITS.summaryLength} characters.`,\n },\n enableScope: {\n type: 'string',\n enum: ['current', 'all'],\n description:\n 'Optional on first call, required on second. \"current\" for current agent only, \"all\" for all agents.',\n },\n },\n examples: [\n {\n name: 'Playwright',\n command: 'npx',\n args: ['@playwright/mcp@latest'],\n },\n {\n name: 'open-websearch',\n command: 'npx',\n args: ['-y', 'open-websearch@latest'],\n env: { MODE: 'stdio', DEFAULT_SEARCH_ENGINE: 'bing' },\n timeout: 30000,\n },\n {\n url: 'https://example.com/mcp',\n summary: 'Use this MCP for Linear issue and project operations.',\n enableScope: 'all',\n },\n {\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '/repo'],\n summary: 'Use this MCP for local filesystem operations.',\n enableScope: 'current',\n },\n ],\n },\n listInputSchema: buildGuideOnlyInputSchema(),\n },\n {\n name: 'skill:import',\n description: 'Call this to import a skill. Returns the import workflow and parameters.',\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: `Required. Path to a local directory containing SKILL.md. Maximum length: ${IMPORT_LIMITS.pathLength} characters.`,\n },\n },\n examples: [{ path: '/absolute/path/to/skill' }],\n },\n listInputSchema: buildGuideOnlyInputSchema(),\n },\n {\n name: 'listAllAaiApps',\n description:\n 'List all apps available to the current agent, excluding AAI Gateway built-in management tools.',\n inputSchema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n },\n {\n name: 'disableApp',\n description: 'Disable one app for the current agent only.',\n inputSchema: {\n type: 'object',\n properties: {\n app: {\n type: 'string',\n description: 'Required. The app id to disable for the current agent.',\n },\n },\n required: ['app'],\n },\n },\n {\n name: 'enableApp',\n description: 'Re-enable one app for the current agent only.',\n inputSchema: {\n type: 'object',\n properties: {\n app: {\n type: 'string',\n description: 'Required. The app id to re-enable for the current agent.',\n },\n },\n required: ['app'],\n },\n },\n {\n name: 'removeApp',\n description: 'Remove one AAI Gateway managed import from all agents.',\n inputSchema: {\n type: 'object',\n properties: {\n app: {\n type: 'string',\n description: 'Required. The imported app id to remove globally.',\n },\n confirm: {\n type: 'boolean',\n description:\n 'Required. Must be true only after the agent explains the global impact and the user explicitly confirms.',\n },\n },\n required: ['app', 'confirm'],\n },\n },\n {\n name: SEARCH_DISCOVER_TOOL_NAME,\n description:\n 'Call this to search for MCP servers or skills. Returns search instructions.',\n inputSchema: searchDiscoverInputSchema,\n listInputSchema: buildGuideOnlyInputSchema(),\n },\n ];\n}\n\nfunction buildGuideOnlyInputSchema(): Record<string, unknown> {\n return {\n type: 'object',\n properties: {},\n additionalProperties: false,\n };\n}\n\nexport function getGatewayToolDefinition(toolName: string): GatewayToolDefinition | undefined {\n return buildGatewayToolDefinitions().find((tool) => tool.name === toolName);\n}\n\nexport function isGatewayExecutionTool(toolName: string): boolean {\n return (\n toolName === 'mcp:import' ||\n toolName === 'skill:import' ||\n toolName === SEARCH_DISCOVER_TOOL_NAME ||\n toolName === 'listAllAaiApps' ||\n toolName === 'disableApp' ||\n toolName === 'enableApp' ||\n toolName === 'removeApp'\n );\n}\n\nexport function generateGatewayToolGuide(tool: GatewayToolDefinition): string {\n if (tool.name === 'mcp:import') {\n return generateMcpImportGuide(tool);\n }\n\n const examples = extractGuideExamples(tool.inputSchema, tool.name);\n return [\n `# ${tool.name}`,\n '',\n `This is only an operation guide for \\`${tool.name}\\`. To perform the actual operation, you must call \\`aai:exec\\`.`,\n '',\n 'The `aai:exec` tool accepts three parameters: `app`, `tool`, and `args`.',\n `For this operation, leave \\`app\\` empty, set \\`tool\\` to \"${tool.name}\", and refer to the examples below for \\`args\\`.`,\n '',\n ...(examples.length > 0\n ? [\n '',\n '## Examples',\n '',\n 'The examples below are complete `aai:exec` calls.',\n '',\n ...examples.flatMap((example) => [\n '```json',\n JSON.stringify(\n { tool: 'aai:exec', args: { tool: tool.name, args: example } },\n null,\n 2\n ),\n '```',\n '',\n ]),\n ]\n : []),\n ].join('\\n');\n}\n\nfunction generateMcpImportGuide(tool: GatewayToolDefinition): string {\n const inspectExample = {\n tool: 'aai:exec',\n args: {\n tool: 'mcp:import',\n args: {\n command: 'npx',\n args: ['-y', '@brave/brave-search-mcp-server'],\n timeout: 60000,\n name: 'brave-search',\n },\n },\n };\n\n const finalizeExample = {\n tool: 'aai:exec',\n args: {\n tool: 'mcp:import',\n args: {\n command: 'npx',\n args: ['-y', '@brave/brave-search-mcp-server'],\n timeout: 60000,\n name: 'brave-search',\n summary: 'Use this MCP for Brave web search.',\n enableScope: 'all',\n },\n },\n };\n\n const envFile = getDotenvPath();\n\n return [\n `# ${tool.name}`,\n '',\n 'This is only an operation guide for `mcp:import`. To perform the actual operation, you must call `aai:exec`.',\n '',\n 'The `aai:exec` tool accepts three parameters: `app`, `tool`, and `args`.',\n 'For this operation, leave `app` empty, set `tool` to `\"mcp:import\"`, and refer to the examples below for `args`.',\n '',\n '## Examples',\n '',\n 'Phase 1 — inspect:',\n '```json',\n JSON.stringify(inspectExample, null, 2),\n '```',\n '',\n 'Phase 2 — finalize import:',\n '```json',\n JSON.stringify(finalizeExample, null, 2),\n '```',\n '',\n '## Parameters',\n '',\n '### Local stdio MCP',\n '',\n '| Parameter | Type | Required | Description |',\n '|-----------|------|----------|-------------|',\n '| `command` | string | yes | The executable only, e.g. `\"npx\"`, `\"uvx\"`, `\"node\"` |',\n '| `args` | string[] | no | Arguments after the executable |',\n '| `env` | object | no | Environment variables as `{ \"KEY\": \"value\" }` pairs |',\n '| `timeout` | integer | no | Tool execution timeout in ms (default 60000) |',\n '| `cwd` | string | no | Working directory for the process |',\n '| `name` | string | no | Display name for the imported app |',\n '| `summary` | string | phase 2 | Short English description of when to use this MCP |',\n '| `enableScope` | `\"current\"` \\\\| `\"all\"` | phase 2 | Enable for current agent or all agents |',\n '',\n 'When converting from a standard MCP JSON config where `command` is an array:',\n '`[\"npx\", \"-y\", \"pkg\"]` → `command: \"npx\"`, `args: [\"-y\", \"pkg\"]`',\n '',\n '### Remote MCP',\n '',\n '| Parameter | Type | Required | Description |',\n '|-----------|------|----------|-------------|',\n '| `url` | string | yes | Remote MCP endpoint URL |',\n '| `transport` | string | no | `\"streamable-http\"` (default) or `\"sse\"` |',\n '| `headers` | object | no | HTTP headers (e.g. `{ \"Authorization\": \"${API_KEY}\" }`). Use `${VAR_NAME}` for secrets. |',\n '| `timeout` | integer | no | Tool execution timeout in ms (default 60000) |',\n '| `name` | string | no | Display name for the imported app |',\n '| `summary` | string | phase 2 | Short English description of when to use this MCP |',\n '| `enableScope` | `\"current\"` \\\\| `\"all\"` | phase 2 | Enable for current agent or all agents |',\n '',\n '## Notes',\n '',\n 'Phase 1 omits `summary` and `enableScope`.',\n 'Phase 2 repeats the same source config and adds `summary` and `enableScope`.',\n '',\n '## Environment variables & API keys',\n '',\n `\\`${envFile}\\` is a sensitive secrets file.`,\n 'Do not read, summarize, or repeat its contents.',\n 'Never ask the user to send API keys, tokens, or any other secret values in chat.',\n `Store sensitive values in \\`${envFile}\\` and reference them with \\${VAR_NAME} placeholders.`,\n '',\n 'If the import fails due to missing environment variables, follow the error instructions.',\n ].join('\\n');\n}\n\nfunction extractGuideExamples(\n inputSchema: Record<string, unknown>,\n toolName: string\n): Record<string, unknown>[] {\n const rawExamples = inputSchema.examples;\n if (Array.isArray(rawExamples) && rawExamples.length > 0) {\n return rawExamples\n .filter((value): value is Record<string, unknown> => !!value && typeof value === 'object')\n .slice(0, 2);\n }\n\n if (toolName === 'mcp:import') return [];\n if (toolName === 'listAllAaiApps') return [{}];\n return [];\n}\n","/**\n * App Registry\n *\n * Manages the registry of discovered and imported apps.\n */\n\nimport type { RuntimeAppRecord } from '../types/aai-json.js';\nimport { logger } from '../utils/logger.js';\n\nexport class AppRegistry {\n private registry = new Map<string, RuntimeAppRecord>();\n\n set(appId: string, record: RuntimeAppRecord): void {\n this.registry.set(appId, record);\n }\n\n get(appId: string): RuntimeAppRecord | undefined {\n return this.registry.get(appId);\n }\n\n has(appId: string): boolean {\n return this.registry.has(appId);\n }\n\n delete(appId: string): boolean {\n return this.registry.delete(appId);\n }\n\n getAll(): RuntimeAppRecord[] {\n return Array.from(this.registry.values());\n }\n\n values(): IterableIterator<RuntimeAppRecord> {\n return this.registry.values();\n }\n\n filter(predicate: (record: RuntimeAppRecord) => boolean): RuntimeAppRecord[] {\n return this.getAll().filter(predicate);\n }\n\n getByProtocol(protocol: string): RuntimeAppRecord[] {\n return this.filter((app) => app.descriptor.access.protocol === protocol);\n }\n\n get size(): number {\n return this.registry.size;\n }\n\n async loadFromDiscovery(discoveryFn: () => Promise<RuntimeAppRecord[]>): Promise<number> {\n try {\n const discoveredApps = await discoveryFn();\n for (const app of discoveredApps) {\n this.registry.set(app.appId, app);\n }\n logger.info({ count: discoveredApps.length }, 'App registry loaded from discovery');\n return discoveredApps.length;\n } catch (err) {\n logger.error({ err }, 'Failed to load app registry from discovery');\n throw err;\n }\n }\n}\n","export type LanguageTag = string;\n\nexport type InternationalizedName = {\n default: string;\n} & Record<LanguageTag, string>;\n\nexport interface CommandConfig {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\nexport interface McpStdioConfig extends CommandConfig {\n transport: 'stdio';\n timeout?: number;\n}\n\nexport interface McpRemoteConfig {\n transport: 'streamable-http' | 'sse';\n url: string;\n timeout?: number;\n headers?: Record<string, string>;\n}\n\nexport type McpConfig = McpStdioConfig | McpRemoteConfig;\n\nexport interface SkillPathConfig {\n path: string;\n url?: never;\n}\n\nexport interface SkillUrlConfig {\n url: string;\n path?: never;\n}\n\nexport type SkillConfig = SkillPathConfig | SkillUrlConfig;\n\nexport interface AcpAgentConfig extends CommandConfig {}\n\nexport interface CliConfig extends CommandConfig {}\n\nexport interface McpAccess {\n protocol: 'mcp';\n config: McpConfig;\n}\n\nexport interface SkillAccess {\n protocol: 'skill';\n config: SkillConfig;\n}\n\nexport interface AcpAgentAccess {\n protocol: 'acp-agent';\n config: AcpAgentConfig;\n}\n\nexport interface CliAccess {\n protocol: 'cli';\n config: CliConfig;\n}\n\nexport type Access = McpAccess | SkillAccess | AcpAgentAccess | CliAccess;\n\nexport interface Exposure {\n summary: string;\n keywords?: string[];\n}\n\nexport interface CommandDiscoveryCheck {\n kind: 'command';\n command: string;\n}\n\nexport interface FileDiscoveryCheck {\n kind: 'file';\n path: string;\n}\n\nexport interface PathDiscoveryCheck {\n kind: 'path';\n path: string;\n}\n\nexport type DiscoveryCheck =\n | CommandDiscoveryCheck\n | FileDiscoveryCheck\n | PathDiscoveryCheck;\n\nexport interface DiscoveryRule {\n checks: DiscoveryCheck[];\n}\n\nexport interface AaiJson {\n schemaVersion: '2.0';\n version: string;\n app: {\n name: InternationalizedName;\n iconUrl?: string;\n };\n discovery?: DiscoveryRule;\n access: Access;\n exposure: Exposure;\n}\n\nexport interface RuntimeAppRecord {\n appId: string;\n descriptor: AaiJson;\n source: 'desktop' | 'web' | 'mcp-import' | 'skill-import' | 'acp-agent' | 'cli';\n location?: string;\n toolSchemas?: Record<string, Record<string, unknown>>;\n}\n\nexport interface DetailedCapability {\n title: string;\n body: string;\n}\n\nexport function getLocalizedName(name: InternationalizedName, locale: LanguageTag): string {\n if (name[locale]) {\n return name[locale];\n }\n\n const family = locale.split('-')[0];\n const fallback = Object.keys(name).find((key) => key !== 'default' && key.startsWith(family));\n if (fallback && name[fallback]) {\n return name[fallback];\n }\n\n return name.default;\n}\n\nexport function isMcpAccess(access: Access): access is McpAccess {\n return access.protocol === 'mcp';\n}\n\nexport function isSkillAccess(access: Access): access is SkillAccess {\n return access.protocol === 'skill';\n}\n\nexport function isAcpAgentAccess(access: Access): access is AcpAgentAccess {\n return access.protocol === 'acp-agent';\n}\n\nexport function isCliAccess(access: Access): access is CliAccess {\n return access.protocol === 'cli';\n}\n\nexport function isSkillPathConfig(config: SkillConfig): config is SkillPathConfig {\n return 'path' in config;\n}\n\nexport function isMcpStdioConfig(config: McpConfig): config is McpStdioConfig {\n return config.transport === 'stdio';\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { AaiError } from '../errors/errors.js';\nimport { isSkillPathConfig } from '../types/aai-json.js';\nimport type {\n DetailedCapability,\n SkillConfig,\n SkillExecutorConfig,\n ExecutionResult,\n} from '../types/index.js';\nimport type { AppCapabilities } from '../types/capabilities.js';\n\nimport type { Executor } from './interface.js';\n\n/**\n * Skill Executor implementation\n *\n * Implements the unified Executor interface for skill-based apps.\n */\nexport class SkillExecutor implements Executor {\n readonly protocol = 'skill';\n\n async connect(_appId: string, _config: SkillConfig & SkillExecutorConfig): Promise<void> {\n // Skills don't maintain connections\n }\n\n async disconnect(_appId: string): Promise<void> {\n // Skills don't maintain connections\n }\n\n /**\n * Load app-level capabilities for skills\n * Skills have a single \"read\" tool for reading SKILL.md\n */\n async loadAppCapabilities(\n _appId: string,\n _config: SkillConfig & SkillExecutorConfig\n ): Promise<AppCapabilities> {\n return {\n title: 'Skill',\n tools: [\n {\n name: 'read',\n description: 'Read the skill documentation (SKILL.md)',\n inputSchema: { type: 'object' as const, properties: {} },\n },\n ],\n };\n }\n\n\n async execute(\n _appId: string,\n config: SkillConfig & SkillExecutorConfig,\n operation: string,\n args: Record<string, unknown>\n ): Promise<ExecutionResult> {\n try {\n if (operation !== 'read') {\n throw new AaiError(\n 'UNKNOWN_TOOL',\n `Skill-backed apps only support tool \"read\", got \"${operation}\"`\n );\n }\n\n const data = await this.readSkill(config, args);\n return { success: true, data };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n async health(_appId: string): Promise<boolean> {\n // Skills are always \"healthy\" as they don't maintain connections\n return true;\n }\n\n // Legacy methods for backward compatibility\n\n async loadSkillDetail(config: SkillConfig & SkillExecutorConfig): Promise<DetailedCapability> {\n const content = await readSkillMarkdown(config);\n return {\n title: 'Skill Details',\n body: content,\n };\n }\n\n async executeSkill(\n config: SkillConfig & SkillExecutorConfig,\n toolName: string,\n args: Record<string, unknown>\n ): Promise<string> {\n const result = await this.execute('', config, toolName, args);\n if (!result.success) {\n throw new AaiError('EXECUTION_ERROR', result.error ?? 'Execution failed');\n }\n return result.data as string;\n }\n\n private async readSkill(\n config: SkillConfig & SkillExecutorConfig,\n args: Record<string, unknown>\n ): Promise<string> {\n const content = await readSkillMarkdown(config);\n const section = typeof args.section === 'string' ? args.section.trim() : '';\n if (!section) {\n return content;\n }\n\n const marker = new RegExp(`^#+\\\\s+${escapeRegExp(section)}\\\\s*$`, 'im');\n const match = content.match(marker);\n if (match?.index === undefined) {\n return content;\n }\n\n return content.slice(match.index);\n }\n}\n\nasync function readSkillMarkdown(config: SkillConfig & SkillExecutorConfig): Promise<string> {\n if (isSkillPathConfig(config)) {\n return readFile(join(config.path, 'SKILL.md'), 'utf-8');\n }\n\n const response = await fetch(`${config.url.replace(/\\/$/, '')}/SKILL.md`);\n if (!response.ok) {\n throw new AaiError(\n 'SERVICE_UNAVAILABLE',\n `Failed to fetch remote skill: ${config.url} (${response.status})`\n );\n }\n return response.text();\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nlet singleton: SkillExecutor | undefined;\n\nexport function getSkillExecutor(): SkillExecutor {\n if (!singleton) {\n singleton = new SkillExecutor();\n }\n return singleton;\n}\n\n// Export legacy functions for backward compatibility\nexport const legacyLoadSkillDetail = (config: SkillConfig & SkillExecutorConfig) =>\n new SkillExecutor().loadSkillDetail(config);\nexport const legacyExecuteSkill = (\n config: SkillConfig & SkillExecutorConfig,\n toolName: string,\n args: Record<string, unknown>\n) => new SkillExecutor().executeSkill(config, toolName, args);\n","/**\n * Execution Coordinator\n *\n * Handles execution routing to appropriate executors\n * and inactivity timeout management.\n */\n\nimport type { AaiJson } from '../types/aai-json.js';\nimport { logger } from '../utils/logger.js';\nimport { getAcpExecutor } from '../executors/acp.js';\nimport { getMcpExecutor } from '../executors/mcp.js';\nimport { legacyExecuteSkill as executeSkill } from '../executors/skill.js';\nimport { getSkillExecutor } from '../executors/skill.js';\nimport type { Executor } from '../executors/interface.js';\nimport type { ExecutionObserver } from '../executors/events.js';\nimport { isAcpAgentAccess, isMcpAccess, isSkillAccess } from '../types/aai-json.js';\n\nconst DOWNSTREAM_INACTIVITY_TIMEOUT_MS = 10 * 60_000;\n\nexport interface ExecutionRequest {\n appId: string;\n toolName: string;\n args: Record<string, unknown>;\n}\n\nexport class ExecutionCoordinator {\n async execute(\n appId: string,\n descriptor: AaiJson,\n toolName: string,\n args: Record<string, unknown>,\n observer?: ExecutionObserver\n ): Promise<unknown> {\n const access = descriptor.access;\n\n if (isMcpAccess(access)) {\n const executor = getMcpExecutor();\n return executor.callTool({ appId, config: access.config }, toolName, args, observer);\n }\n\n if (isSkillAccess(access)) {\n return executeSkill(access.config as any, toolName, args);\n }\n\n if (isAcpAgentAccess(access)) {\n const executor = getAcpExecutor();\n if (observer && executor.executeWithObserver) {\n return executor.executeWithObserver(appId, access.config, toolName, args, observer);\n }\n return executor.execute(appId, access.config, toolName, args);\n }\n\n throw new Error(`Unsupported protocol ${JSON.stringify(access)}`);\n }\n\n async executeWithInactivityTimeout(\n appId: string,\n descriptor: AaiJson,\n toolName: string,\n args: Record<string, unknown>,\n observer?: ExecutionObserver\n ): Promise<unknown> {\n const timeoutMs = DOWNSTREAM_INACTIVITY_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n let completed = false;\n let timer: NodeJS.Timeout | undefined;\n\n const finish = (callback: () => void) => {\n if (completed) return;\n completed = true;\n if (timer) clearTimeout(timer);\n callback();\n };\n\n const scheduleTimeout = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n const error = new Error(\n `Downstream '${appId}' timed out after ${timeoutMs}ms without any activity`\n );\n void this.cleanupTimedOutExecution(appId, descriptor).finally(() => {\n finish(() => reject(error));\n });\n }, timeoutMs);\n };\n\n const activityObserver = this.wrapExecutionObserver(observer, scheduleTimeout);\n scheduleTimeout();\n\n this.execute(appId, descriptor, toolName, args, activityObserver).then(\n (result) => finish(() => resolve(result)),\n (error) => finish(() => reject(error))\n );\n });\n }\n\n getExecutor(protocol: string): Executor {\n switch (protocol) {\n case 'mcp':\n return getMcpExecutor();\n case 'skill':\n return getSkillExecutor();\n case 'acp-agent':\n return getAcpExecutor();\n default:\n throw new Error(`Protocol '${protocol}' does not support app capabilities`);\n }\n }\n\n private wrapExecutionObserver(\n observer: ExecutionObserver | undefined,\n onActivity: () => void\n ): ExecutionObserver {\n return {\n onMessage: async (event) => {\n onActivity();\n await observer?.onMessage?.(event);\n },\n onProgress: async (event) => {\n onActivity();\n await observer?.onProgress?.(event);\n },\n onTaskStatus: async (event) => {\n onActivity();\n await observer?.onTaskStatus?.(event);\n },\n };\n }\n\n private async cleanupTimedOutExecution(appId: string, descriptor: AaiJson): Promise<void> {\n const access = descriptor.access;\n try {\n if (isMcpAccess(access)) {\n await getMcpExecutor().close(appId);\n return;\n }\n if (isAcpAgentAccess(access)) {\n await getAcpExecutor().disconnect(appId);\n }\n } catch (err) {\n logger.warn({ appId, err }, 'Failed to clean up timed out downstream execution');\n }\n }\n}\n","import { execFileSync } from \"node:child_process\";\n\nexport type SupportedLocale = \"en\" | \"zh-CN\" | \"zh-TW\";\n\n/**\n * Get the system locale on macOS\n */\nexport function getSystemLocale(): SupportedLocale {\n try {\n // On macOS, use defaults to get the locale\n const output = execFileSync(\n \"defaults\",\n [\"read\", \"-g\", \"AppleLocale\"],\n { encoding: \"utf-8\", timeout: 1000 }\n ).trim();\n\n return normalizeLocale(output);\n } catch {\n // Fallback to environment variable\n const envLocale = process.env.LANG || process.env.LC_ALL || process.env.LC_MESSAGES || \"en\";\n return normalizeLocale(envLocale);\n }\n}\n\n/**\n * Normalize locale string to supported format\n */\nfunction normalizeLocale(locale: string): SupportedLocale {\n const lower = locale.toLowerCase().replace(/[^a-z-]/g, \"\");\n\n // Chinese variants\n if (lower.startsWith(\"zh-hans\") || lower === \"zh-cn\" || lower === \"zh_cn\") {\n return \"zh-CN\";\n }\n if (lower.startsWith(\"zh-hant\") || lower === \"zh-tw\" || lower === \"zh_tw\" || lower === \"zh-hk\" || lower === \"zh_hk\") {\n return \"zh-TW\";\n }\n if (lower.startsWith(\"zh\")) {\n return \"zh-CN\"; // Default to Simplified Chinese\n }\n\n // Default to English\n return \"en\";\n}\n","import type { AaiJson } from '../types/aai-json.js';\nimport type { AppCapabilities, ToolSchema } from '../types/capabilities.js';\nimport {\n getLocalizedName,\n isSkillAccess,\n isSkillPathConfig,\n type InternationalizedName,\n} from '../types/aai-json.js';\nimport { getSystemLocale } from '../utils/locale.js';\n\n// ============================================================================\n// Templates\n// ============================================================================\n\nconst TEMPLATE_GUIDE_TOOL_SUMMARY = `{{LOCALIZED_NAME}} — {{SUMMARY}} Call this to see available tools and usage.`;\n\nconst TEMPLATE_APP_GUIDE = `# {{LOCALIZED_NAME}}\n\n- App ID: {{LOCAL_ID}}\n- Summary: {{SUMMARY}}\n\n## Tools\n\n{{TOOLS}}\n\n{{EXAMPLES_SECTION}}{{NOTES_SECTION}}`;\n\nconst TEMPLATE_MCP_APP_GUIDE = `# {{LOCALIZED_NAME}}\n\nThis is only an operation guide for tools in this app. To perform the actual operation, you must call \\`aai:exec\\`.\n\nThe \\`aai:exec\\` tool accepts three parameters: \\`app\\`, \\`tool\\`, and \\`args\\`.\nFor this app, set \\`app\\` to \"{{LOCAL_ID}}\", set \\`tool\\` to one of the tool names below, and refer to the schema of the selected tool below for \\`args\\`.\n\n## Tools\n\n{{TOOLS}}`;\n\nconst TEMPLATE_ACP_APP_GUIDE = `# {{LOCALIZED_NAME}}\n\nThis is only an operation guide for tools in this app. To perform the actual operation, you must call \\`aai:exec\\`.\n\nThe \\`aai:exec\\` tool accepts three parameters: \\`app\\`, \\`tool\\`, and \\`args\\`.\nFor this app, set \\`app\\` to \"{{LOCAL_ID}}\", set \\`tool\\` to one of the tool names below, and use each tool's example below as the reference for \\`args\\`.\n\n## Tools\n\n{{TOOLS}}{{NOTES_SECTION}}`;\n\nconst TEMPLATE_TOOL_ITEM = `### {{NAME}}\n\n{{DESCRIPTION}}\n\n{{SCHEMA}}`;\n\nconst TEMPLATE_TOOL_ITEM_NO_SCHEMA = `### {{NAME}}\n\n{{DESCRIPTION}}`;\n\n// ============================================================================\n// Public Functions\n// ============================================================================\n\nexport function generateGuideToolSummary(_appId: string, descriptor: AaiJson): string {\n const localizedName = getEnglishName(descriptor.app.name);\n const params = {\n LOCALIZED_NAME: localizedName,\n SUMMARY: normalizeGuideToolSummary(descriptor.exposure.summary),\n };\n\n switch (descriptor.access.protocol) {\n case 'mcp':\n return renderTemplate(TEMPLATE_GUIDE_TOOL_SUMMARY, params);\n case 'skill':\n return renderTemplate(TEMPLATE_GUIDE_TOOL_SUMMARY, params);\n case 'cli':\n return renderTemplate(TEMPLATE_GUIDE_TOOL_SUMMARY, params);\n case 'acp-agent':\n return renderTemplate(TEMPLATE_GUIDE_TOOL_SUMMARY, params);\n }\n}\n\n/**\n * Generate app guide using the new AppCapabilities interface\n */\nexport function generateAppGuideMarkdown(\n appId: string,\n descriptor: AaiJson,\n capabilities: AppCapabilities\n): string {\n const protocol = descriptor.access.protocol;\n if (protocol === 'mcp') {\n return generateMcpAppGuideMarkdown(appId, descriptor, capabilities);\n }\n if (protocol === 'acp-agent') {\n return generateAcpAppGuideMarkdown(appId, descriptor, capabilities);\n }\n\n const locale = getSystemLocale();\n const localizedName = getLocalizedName(descriptor.app.name, locale);\n const toolsSection = buildToolsSection(capabilities);\n const examplesSection = buildExamplesSection(protocol, capabilities);\n const notesSection = buildNotesSection(protocol, descriptor);\n\n return renderTemplate(TEMPLATE_APP_GUIDE, {\n LOCALIZED_NAME: localizedName,\n LOCAL_ID: appId,\n SUMMARY: descriptor.exposure.summary,\n TOOLS: toolsSection,\n EXAMPLES_SECTION: examplesSection\n ? `\\n## Examples\\n\\nExecute via \\`aai:exec\\` with \\`app: \"${appId}\"\\`:\\n\\n${examplesSection}\\n`\n : '',\n NOTES_SECTION: notesSection ? `\\n## Notes\\n\\n${notesSection}\\n` : '',\n });\n}\n\nfunction generateMcpAppGuideMarkdown(\n appId: string,\n descriptor: AaiJson,\n capabilities: AppCapabilities\n): string {\n const locale = getSystemLocale();\n const localizedName = getLocalizedName(descriptor.app.name, locale);\n const toolsSection = buildToolsSection(capabilities);\n\n return renderTemplate(TEMPLATE_MCP_APP_GUIDE, {\n LOCALIZED_NAME: localizedName,\n LOCAL_ID: appId,\n TOOLS: toolsSection,\n });\n}\n\nfunction generateAcpAppGuideMarkdown(\n appId: string,\n descriptor: AaiJson,\n capabilities: AppCapabilities\n): string {\n const locale = getSystemLocale();\n const localizedName = getLocalizedName(descriptor.app.name, locale);\n const toolsSection = buildAcpToolsSection(appId, capabilities);\n const notesSection = buildNotesSection('acp-agent', descriptor);\n\n return renderTemplate(TEMPLATE_ACP_APP_GUIDE, {\n LOCALIZED_NAME: localizedName,\n LOCAL_ID: appId,\n TOOLS: toolsSection,\n NOTES_SECTION: notesSection ? `\\n\\n## Notes\\n\\n${notesSection}\\n` : '',\n });\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction buildToolsSection(\n capabilities: AppCapabilities,\n options: { includeSchema?: boolean } = {}\n): string {\n if (capabilities.tools.length === 0) {\n return 'No tools available.';\n }\n\n const includeSchema = options.includeSchema ?? true;\n return capabilities.tools\n .map((tool) => {\n const desc = tool.description?.trim();\n const shortDesc = desc ? truncateDescription(desc) : 'No description provided.';\n return renderTemplate(includeSchema ? TEMPLATE_TOOL_ITEM : TEMPLATE_TOOL_ITEM_NO_SCHEMA, {\n NAME: tool.name,\n DESCRIPTION: shortDesc,\n SCHEMA: includeSchema ? formatToolSchema(tool) : '',\n });\n })\n .join('\\n');\n}\n\nfunction formatToolSchema(tool: ToolSchema): string {\n const schema: Record<string, unknown> = { inputSchema: tool.inputSchema };\n if (tool.outputSchema) {\n schema.outputSchema = tool.outputSchema;\n }\n return ['```json', JSON.stringify(schema, null, 2), '```'].join('\\n');\n}\n\nfunction truncateDescription(desc: string): string {\n const firstSentence = desc.split(/(?<=[.!?])\\s/)[0];\n return firstSentence.length <= 120 ? firstSentence : `${firstSentence.slice(0, 117)}...`;\n}\n\nfunction buildExamplesSection(protocol: string, capabilities: AppCapabilities): string {\n switch (protocol) {\n case 'mcp':\n return '';\n\n case 'acp-agent':\n return '';\n\n case 'skill':\n return buildSkillExamples(capabilities);\n\n case 'cli':\n return buildCliExamples(capabilities);\n\n default:\n return '';\n }\n}\n\nfunction buildNotesSection(protocol: string, descriptor: AaiJson): string {\n switch (protocol) {\n case 'acp-agent':\n return 'session/new returns promptCapabilities. turn/start.prompt must match those capabilities.';\n case 'skill':\n return [\n 'Execute via `aai:exec` with the app id above.',\n buildSkillDirSection(descriptor),\n ].join('\\n');\n case 'cli':\n return 'Pass args.argv as a string array and args.stdin as optional text.';\n default:\n return '';\n }\n}\n\nfunction buildSkillDirSection(descriptor: AaiJson): string {\n if (isSkillAccess(descriptor.access) && isSkillPathConfig(descriptor.access.config)) {\n return `AAI Gateway managed skill directory: \\`${descriptor.access.config.path}\\`.`;\n }\n return 'AAI Gateway managed skill directory: use the local skill path configured for this imported skill.';\n}\n\nfunction buildAcpToolsSection(appId: string, capabilities: AppCapabilities): string {\n if (capabilities.tools.length === 0) {\n return 'No tools available.';\n }\n\n return capabilities.tools\n .map((tool) => {\n const desc = tool.description?.trim();\n const shortDesc = desc ? truncateDescription(desc) : 'No description provided.';\n const example = buildAcpExample(tool.name, appId);\n\n return [\n `### ${tool.name}`,\n '',\n shortDesc,\n '',\n 'args:',\n '',\n example ? JSON.stringify(example, null, 2) : 'No example available.',\n ].join('\\n');\n })\n .join('\\n\\n');\n}\n\nfunction buildSkillExamples(capabilities: AppCapabilities): string {\n if (!capabilities.tools.some((tool) => tool.name === 'read')) {\n return '';\n }\n\n return renderExampleJson({\n tool: 'read',\n args: {},\n });\n}\n\nfunction buildCliExamples(capabilities: AppCapabilities): string {\n const primaryTool = capabilities.tools.find((tool) => tool.name === 'run')?.name ?? 'run';\n return renderExampleJson({\n tool: primaryTool,\n args: {\n argv: ['--help'],\n },\n });\n}\n\nfunction buildAcpExample(toolName: string, appId: string): Record<string, unknown> | null {\n switch (toolName) {\n case 'session/new':\n return {\n app: appId,\n tool: 'session/new',\n args: {\n cwd: '/absolute/path/to/project',\n },\n };\n case 'turn/start':\n return {\n app: appId,\n tool: 'turn/start',\n args: {\n sessionId: '<sessionId>',\n prompt: [{ type: 'text', text: 'Summarize the current project.' }],\n },\n };\n case 'turn/poll':\n return {\n app: appId,\n tool: 'turn/poll',\n args: {\n turnId: '<turnId>',\n },\n };\n case 'turn/respondPermission':\n return {\n app: appId,\n tool: 'turn/respondPermission',\n args: {\n turnId: '<turnId>',\n permissionId: '<permissionId>',\n decision: {\n type: 'select',\n optionId: '<optionId>',\n },\n },\n };\n case 'turn/cancel':\n return {\n app: appId,\n tool: 'turn/cancel',\n args: {\n turnId: '<turnId>',\n },\n };\n default:\n return null;\n }\n}\n\nfunction renderExampleJson(payload: Record<string, unknown>): string {\n return ['```json', JSON.stringify(payload, null, 2), '```'].join('\\n');\n}\n\nfunction normalizeGuideToolSummary(summary: string): string {\n return summary.trim().replace(/\\s+/g, ' ');\n}\n\nfunction getEnglishName(name: InternationalizedName): string {\n return name.en ?? name['en-US'] ?? name.default;\n}\n\n// ============================================================================\n// Simple Template Engine\n// ============================================================================\n\ninterface TemplateVars {\n [key: string]: string | number | boolean | undefined;\n}\n\n/**\n * Simple template renderer supporting {{variable}} and {{#if}}...{{/if}} blocks.\n */\nfunction renderTemplate(template: string, vars: TemplateVars): string {\n let output = template;\n\n // Handle if blocks: {{#if VAR}}...{{/if}}\n output = output.replace(/\\{\\{#if (\\w+)\\}\\}([\\s\\S]*?)\\{\\{\\/if\\}\\}/g, (_, varName, content) => {\n const value = vars[varName];\n if (value && value !== 'false' && value !== '0') {\n return content;\n }\n return '';\n });\n\n // Handle variable replacement\n output = output.replace(/\\{\\{(\\w+)\\}\\}/g, (_, varName) => {\n const value = vars[varName];\n return value !== undefined ? String(value) : '';\n });\n\n return output;\n}\n","/**\n * Guide Service\n *\n * Handles generation of guides and tool summaries.\n */\n\nimport type { AaiJson, RuntimeAppRecord } from '../types/aai-json.js';\nimport type { AppCapabilities } from '../types/capabilities.js';\nimport {\n generateAppGuideMarkdown,\n generateGuideToolSummary,\n} from '../guides/app-guide-generator.js';\n\nexport class GuideService {\n generateAppGuide(appId: string, descriptor: AaiJson, capabilities: AppCapabilities): string {\n return generateAppGuideMarkdown(appId, descriptor, capabilities);\n }\n\n generateToolSummary(appId: string, descriptor: AaiJson): string {\n return generateGuideToolSummary(appId, descriptor);\n }\n\n buildToolListForCaller(\n apps: RuntimeAppRecord[],\n gatewayToolDefinitions: Array<{\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n listInputSchema?: Record<string, unknown>;\n }>\n ): Array<{\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n }> {\n return [\n ...apps.map((app) => ({\n name: `app:${app.appId}`,\n description: this.generateToolSummary(app.appId, app.descriptor),\n inputSchema: { type: 'object', properties: {} },\n })),\n ...gatewayToolDefinitions.map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.listInputSchema ?? tool.inputSchema,\n })),\n ];\n }\n}\n","/**\n * Import Service\n *\n * Handles MCP server and skill import logic.\n */\n\nimport type { AaiJson, McpConfig, RuntimeAppRecord } from '../types/aai-json.js';\nimport { getMcpExecutor } from '../executors/mcp.js';\nimport { importMcpServer, importSkill } from './importer.js';\nimport {\n deleteAppPolicyState,\n removeAppFromAllAgents,\n saveAppPolicyState,\n} from '../storage/agent-state.js';\nimport { getSkillRegistry } from '../storage/skill-registry.js';\nimport { getManagedAppDir } from '../storage/paths.js';\nimport { rm } from 'node:fs/promises';\nimport type { CallerContext } from '../types/caller.js';\n\nexport interface ImportResult {\n appId: string;\n descriptor: AaiJson;\n managedPath: string;\n tools: Array<{ name: string; description?: string; inputSchema?: Record<string, unknown> }>;\n}\n\nexport class ImportService {\n constructor(\n private readonly appRegistry: {\n set(appId: string, record: RuntimeAppRecord): void;\n delete(appId: string): boolean;\n }\n ) {}\n\n async importMcp(\n options: {\n name?: string;\n config: McpConfig;\n summary: string;\n enableScope: 'current' | 'all';\n },\n caller: CallerContext\n ): Promise<ImportResult> {\n const result = await importMcpServer(getMcpExecutor(), {\n name: options.name,\n config: options.config,\n summary: options.summary,\n });\n\n await saveAppPolicyState(result.entry.appId, {\n defaultEnabled: options.enableScope === 'current' ? 'importer-only' : 'all',\n importerAgentId: caller.id,\n updatedAt: new Date().toISOString(),\n });\n\n this.appRegistry.set(result.entry.appId, {\n appId: result.entry.appId,\n descriptor: result.descriptor,\n source: 'mcp-import',\n location: result.entry.descriptorPath,\n });\n\n return {\n appId: result.entry.appId,\n descriptor: result.descriptor,\n managedPath: result.entry.descriptorPath,\n tools: result.tools,\n };\n }\n\n async importSkill(\n options: { path: string },\n caller: CallerContext\n ): Promise<ImportResult> {\n const result = await importSkill({ path: options.path });\n\n await saveAppPolicyState(result.appId, {\n defaultEnabled: 'importer-only',\n importerAgentId: caller.id,\n updatedAt: new Date().toISOString(),\n });\n\n this.appRegistry.set(result.appId, {\n appId: result.appId,\n descriptor: result.descriptor,\n source: 'skill-import',\n location: result.managedPath,\n });\n\n return {\n appId: result.appId,\n descriptor: result.descriptor,\n managedPath: result.managedPath,\n tools: [],\n };\n }\n\n async removeApp(appId: string): Promise<void> {\n const { getMcpRegistry } = await import('../storage/mcp-registry.js');\n const registry = getMcpRegistry();\n\n const mcpEntry = await registry.get(appId);\n if (mcpEntry) {\n await registry.delete(appId);\n } else {\n await getSkillRegistry().delete(appId);\n }\n\n await deleteAppPolicyState(appId);\n await removeAppFromAllAgents(appId);\n await rm(getManagedAppDir(appId), { recursive: true, force: true });\n }\n}\n","import type { AaiJson } from '../../types/aai-json.js';\n\nexport const appId = 'claude';\n\nexport const descriptor: AaiJson = {\n schemaVersion: '2.0',\n version: '1.0.0',\n app: {\n name: {\n default: 'Claude Code',\n en: 'Claude Code',\n 'zh-CN': 'Claude Code',\n },\n },\n discovery: {\n checks: [\n { kind: 'command', command: 'npx' },\n { kind: 'command', command: 'claude' },\n ],\n },\n access: {\n protocol: 'acp-agent',\n config: {\n command: 'npx',\n args: ['-y', '@zed-industries/claude-agent-acp'],\n },\n },\n exposure: {\n summary: 'AI assistant for code editing, analysis, and development tasks.',\n },\n};\n","import type { AaiJson } from '../../types/aai-json.js';\n\nexport const appId = 'codex';\n\nexport const descriptor: AaiJson = {\n schemaVersion: '2.0',\n version: '1.0.0',\n app: {\n name: {\n default: 'Codex',\n en: 'Codex',\n 'zh-CN': 'Codex',\n },\n },\n discovery: {\n checks: [\n { kind: 'command', command: 'npx' },\n { kind: 'command', command: 'codex' },\n ],\n },\n access: {\n protocol: 'acp-agent',\n config: {\n command: 'npx',\n args: ['-y', '@zed-industries/codex-acp'],\n },\n },\n exposure: {\n summary: 'AI assistant powered by OpenAI for code generation and editing tasks.',\n },\n};\n","import type { AaiJson } from '../../types/aai-json.js';\n\nexport const appId = 'opencode';\n\nexport const descriptor: AaiJson = {\n schemaVersion: '2.0',\n version: '1.0.0',\n app: {\n name: {\n default: 'OpenCode',\n en: 'OpenCode',\n 'zh-CN': 'OpenCode',\n },\n },\n discovery: {\n checks: [{ kind: 'command', command: 'opencode' }],\n },\n access: {\n protocol: 'acp-agent',\n config: {\n command: 'opencode',\n args: ['acp'],\n },\n },\n exposure: {\n summary: 'AI assistant for editing files, running commands, and automating development tasks.',\n },\n};\n","/**\n * Seed Pre-built Descriptors\n *\n * Writes pre-built ACP agent descriptors into the managed apps directory\n * on every startup (always overwrites to ensure latest version).\n */\n\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport type { AaiJson } from '../types/aai-json.js';\nimport { getManagedAppDir } from '../storage/paths.js';\nimport { logger } from '../utils/logger.js';\n\ninterface PrebuiltDescriptor {\n appId: string;\n descriptor: AaiJson;\n}\n\nasync function loadPrebuiltDescriptors(): Promise<PrebuiltDescriptor[]> {\n const modules = import.meta.glob('../discovery/descriptors/*-agent.ts', { eager: true });\n const descriptors: PrebuiltDescriptor[] = [];\n\n for (const [path, mod] of Object.entries(modules)) {\n const module = mod as { appId?: string; descriptor?: AaiJson };\n if (module.appId && module.descriptor) {\n descriptors.push({ appId: module.appId, descriptor: module.descriptor });\n } else {\n logger.warn({ path }, 'Pre-built descriptor module missing appId or descriptor export');\n }\n }\n\n return descriptors;\n}\n\nexport async function seedPrebuiltDescriptors(): Promise<number> {\n const descriptors = await loadPrebuiltDescriptors();\n let seeded = 0;\n\n for (const { appId, descriptor } of descriptors) {\n try {\n const appDir = getManagedAppDir(appId);\n await mkdir(appDir, { recursive: true });\n await writeFile(\n join(appDir, 'aai.json'),\n JSON.stringify(descriptor, null, 2),\n 'utf-8'\n );\n seeded++;\n logger.debug({ appId }, 'Pre-built descriptor seeded');\n } catch (err) {\n logger.error({ appId, err }, 'Failed to seed pre-built descriptor');\n }\n }\n\n logger.info({ count: seeded }, 'Pre-built descriptors seeded');\n return seeded;\n}\n","/**\n * Background Task Framework\n *\n * Provides a unified interface for background tasks that run during AAI Gateway lifetime.\n * Tasks can:\n * - Run once at startup (potentially with dependencies on other tasks)\n * - Run periodically at a specified interval\n * - Be gracefully stopped\n */\n\nimport { logger } from '../../utils/logger.js';\n\nexport interface BackgroundTask {\n readonly name: string;\n readonly dependencies?: string[];\n start(): Promise<void>;\n stop(): void;\n}\n\nexport class BackgroundTaskManager {\n private tasks = new Map<string, BackgroundTask>();\n private intervals = new Map<string, NodeJS.Timeout>();\n private started = false;\n\n register(task: BackgroundTask): void {\n if (this.tasks.has(task.name)) {\n logger.warn({ task: task.name }, 'Background task already registered, skipping');\n return;\n }\n this.tasks.set(task.name, task);\n logger.debug(\n { task: task.name, dependencies: task.dependencies },\n 'Background task registered'\n );\n }\n\n async startAll(): Promise<void> {\n if (this.started) {\n logger.warn('Background task manager already started');\n return;\n }\n this.started = true;\n\n const executionOrder = this.resolveDependencies();\n logger.info({ count: this.tasks.size, order: executionOrder }, 'Starting all background tasks');\n\n for (const name of executionOrder) {\n const task = this.tasks.get(name);\n if (!task) {\n continue;\n }\n\n try {\n await task.start();\n logger.info({ task: name }, 'Background task started');\n } catch (err) {\n logger.error({ task: name, err }, 'Background task failed to start');\n }\n }\n }\n\n private resolveDependencies(): string[] {\n const visited = new Set<string>();\n const result: string[] = [];\n\n const visit = (name: string) => {\n if (visited.has(name)) {\n return;\n }\n visited.add(name);\n\n const task = this.tasks.get(name);\n if (task?.dependencies) {\n for (const dep of task.dependencies) {\n if (this.tasks.has(dep)) {\n visit(dep);\n }\n }\n }\n\n result.push(name);\n };\n\n for (const name of this.tasks.keys()) {\n visit(name);\n }\n\n return result;\n }\n\n stopAll(): void {\n if (!this.started) {\n return;\n }\n\n logger.info({ count: this.tasks.size }, 'Stopping all background tasks');\n\n for (const [, interval] of this.intervals) {\n clearInterval(interval);\n }\n this.intervals.clear();\n\n for (const [name, task] of this.tasks) {\n try {\n task.stop();\n logger.debug({ task: name }, 'Background task stopped');\n } catch (err) {\n logger.error({ task: name, err }, 'Background task failed to stop');\n }\n }\n\n this.started = false;\n logger.info('All background tasks stopped');\n }\n\n schedulePeriodic(taskName: string, intervalMs: number, fn: () => void): void {\n const existing = this.intervals.get(taskName);\n if (existing) {\n clearInterval(existing);\n }\n\n const interval = setInterval(() => {\n try {\n fn();\n } catch (err) {\n logger.error({ task: taskName, err }, 'Background task periodic run failed');\n }\n }, intervalMs);\n\n this.intervals.set(taskName, interval);\n logger.debug({ task: taskName, intervalMs }, 'Background task scheduled for periodic run');\n }\n}\n","/**\n * ACP Pre-warm Background Task\n *\n * Pre-initializes all discovered ACP agents so the first prompt doesn't pay\n * the full initialization + session-creation penalty.\n *\n * Depends on: discovery\n */\n\nimport { logger } from '../../utils/logger.js';\nimport type { BackgroundTask } from './task-manager.js';\nimport type { AppRegistry } from '../app-registry.js';\n\nexport class AcpPrewarmBackgroundTask implements BackgroundTask {\n readonly name = 'acp-prewarm';\n readonly dependencies: string[] = [];\n\n constructor(private readonly appRegistry: AppRegistry) {}\n\n async start(): Promise<void> {\n const acpApps = this.appRegistry.getByProtocol('acp-agent');\n\n if (acpApps.length === 0) {\n logger.debug('No ACP agents to pre-warm');\n return;\n }\n\n logger.info({ count: acpApps.length }, 'Pre-warming ACP agents');\n\n for (const app of acpApps) {\n const { getAcpExecutor } = await import('../../executors/acp.js');\n const config = app.descriptor.access.config as import('../../types/index.js').AcpAgentConfig;\n void getAcpExecutor()\n .connect(app.appId, config)\n .then(() => {\n logger.info({ appId: app.appId }, 'ACP agent pre-warm completed');\n })\n .catch((err) => {\n logger.warn({ appId: app.appId, err }, 'ACP agent pre-warm failed (will retry lazily)');\n });\n }\n }\n\n stop(): void {}\n}\n","/**\n * Turn Cleanup Background Task\n *\n * Cleans up turns that were finished but not polled by clients.\n * Runs periodically to remove turns older than the retention period.\n */\n\nimport { getAcpExecutor } from '../../executors/acp.js';\nimport { logger } from '../../utils/logger.js';\nimport type { BackgroundTask } from './task-manager.js';\n\nconst TURN_RETENTION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\nconst CLEANUP_INTERVAL_MS = 60 * 60 * 1000; // 1 hour\n\nexport class TurnCleanupTask implements BackgroundTask {\n readonly name = 'turn-cleanup';\n\n async start(): Promise<void> {\n logger.info(\n {\n retentionDays: TURN_RETENTION_MS / (24 * 60 * 60 * 1000),\n intervalHours: CLEANUP_INTERVAL_MS / (60 * 60 * 1000),\n },\n 'Turn cleanup task starting'\n );\n\n // Run immediately on start\n this.run();\n\n // Then run periodically\n const executor = getAcpExecutor();\n if ('scheduleTurnCleanup' in executor && typeof executor.scheduleTurnCleanup === 'function') {\n executor.scheduleTurnCleanup(CLEANUP_INTERVAL_MS, TURN_RETENTION_MS);\n }\n }\n\n stop(): void {\n const executor = getAcpExecutor();\n if (\n 'unscheduleTurnCleanup' in executor &&\n typeof executor.unscheduleTurnCleanup === 'function'\n ) {\n executor.unscheduleTurnCleanup();\n }\n logger.info({ task: this.name }, 'Turn cleanup task stopped');\n }\n\n private run(): void {\n try {\n const executor = getAcpExecutor();\n if (\n 'cleanupFinishedTurns' in executor &&\n typeof executor.cleanupFinishedTurns === 'function'\n ) {\n const cleaned = executor.cleanupFinishedTurns(TURN_RETENTION_MS);\n if (cleaned > 0) {\n logger.info({ task: this.name, cleanedTurns: cleaned }, 'Turn cleanup completed');\n }\n }\n } catch (err) {\n logger.error({ task: this.name, err }, 'Turn cleanup run failed');\n }\n }\n}\n","/**\n * Gateway — Core Business Logic\n *\n * Handles all AAI Gateway operations: app resolution, import,\n * enable/disable, guide generation, and tool execution.\n * Protocol-agnostic — does not depend on MCP types.\n */\n\nimport type { RuntimeAppRecord } from '../types/aai-json.js';\nimport { logger } from '../utils/logger.js';\nimport { AaiError } from '../errors/errors.js';\nimport { getMcpExecutor } from '../executors/mcp.js';\nimport { loadManagedDescriptors } from '../storage/managed-registry.js';\nimport {\n disableAppForAgent,\n enableAppForAgent,\n loadAppPolicyState,\n upsertAgentState,\n} from '../storage/agent-state.js';\nimport { getDotenvPath } from '../utils/dotenv.js';\nimport { discoverMcpImport, EXPOSURE_LIMITS } from './importer.js';\nimport {\n SEARCH_DISCOVER_TOOL_NAME,\n buildSearchDiscoverResponse,\n parseSearchDiscoverArguments,\n} from './search-guidance.js';\nimport type { ParsedMcpImportArgs, ParsedSkillImportArgs } from './parsers.js';\nimport {\n summarizeMcpImportRequest,\n summarizeSkillImportRequest,\n summarizeRawImportArgs,\n summarizeExecArgs,\n summarizeExecResult,\n} from './parsers.js';\nimport type { CallerContext } from '../types/caller.js';\nimport {\n buildGatewayToolDefinitions,\n getGatewayToolDefinition,\n generateGatewayToolGuide,\n isGatewayExecutionTool,\n type GatewayToolDefinition,\n} from './tool-definitions.js';\nimport { AppRegistry } from './app-registry.js';\nimport { ExecutionCoordinator } from './execution-coordinator.js';\nimport { GuideService } from './guide-service.js';\nimport { ImportService } from './import-service.js';\nimport { seedPrebuiltDescriptors } from './seed.js';\nimport { BackgroundTaskManager } from './background/task-manager.js';\nimport { AcpPrewarmBackgroundTask } from './background/acp-prewarm-task.js';\nimport { TurnCleanupTask } from './background/turn-cleanup.js';\nimport { deriveCallerId } from '../storage/agent-state.js';\n\n// ============================================================\n// Result types (protocol-agnostic)\n// ============================================================\n\nexport interface GatewayTextResult {\n text: string;\n isError?: boolean;\n structuredContent?: Record<string, unknown>;\n}\n\nexport interface GatewayToolInfo {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n}\n\n// ============================================================\n// Gateway class\n// ============================================================\n\nexport class Gateway {\n private readonly appRegistry = new AppRegistry();\n private readonly guideService = new GuideService();\n private executionCoordinator!: ExecutionCoordinator;\n private importService!: ImportService;\n private readonly backgroundTasks = new BackgroundTaskManager();\n\n async initialize(): Promise<void> {\n this.executionCoordinator = new ExecutionCoordinator();\n this.importService = new ImportService(this.appRegistry);\n\n // Seed pre-built descriptors (always overwrite)\n await seedPrebuiltDescriptors();\n\n // Load all managed descriptors (imports + seeded)\n await this.appRegistry.loadFromDiscovery(() => loadManagedDescriptors());\n\n // Start background tasks\n this.backgroundTasks.register(new AcpPrewarmBackgroundTask(this.appRegistry));\n this.backgroundTasks.register(new TurnCleanupTask());\n await this.backgroundTasks.startAll();\n }\n\n // ============================================================\n // Caller identity\n // ============================================================\n\n createCallerContext(clientVersion: { name?: string; version?: string } | undefined): CallerContext {\n const name = clientVersion?.name?.trim() || 'Unknown Client';\n return {\n id: deriveCallerId({ callerName: name }),\n name,\n version: clientVersion?.version,\n transport: 'mcp',\n type: 'unknown',\n };\n }\n\n // ============================================================\n // Tool listing\n // ============================================================\n\n async listTools(caller: CallerContext): Promise<GatewayToolInfo[]> {\n const visibleApps = await this.listVisibleApps(caller);\n return [\n ...visibleApps.map((app) => ({\n name: `app:${app.appId}`,\n description: this.guideService.generateToolSummary(app.appId, app.descriptor),\n inputSchema: { type: 'object' as const, properties: {} },\n })),\n ...buildGatewayToolDefinitions().map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.listInputSchema ?? tool.inputSchema,\n })),\n ];\n }\n\n getGatewayToolDefinition(name: string): GatewayToolDefinition | undefined {\n return getGatewayToolDefinition(name);\n }\n\n // ============================================================\n // App guide\n // ============================================================\n\n async handleAppGuide(appId: string, caller: CallerContext): Promise<GatewayTextResult> {\n const result = await this.resolveManagedApp(appId, caller);\n if (!result) {\n throw new AaiError('UNKNOWN_APP', `App not found: ${appId}`);\n }\n if ('disabled' in result) {\n throw new AaiError(\n 'UNKNOWN_APP',\n `App \"${appId}\" is currently disabled for this agent. To enable it, call the enableApp tool with app: \"${appId}\". Please present this message to the user in their preferred language.`\n );\n }\n\n const { descriptor } = result.app;\n const access = descriptor.access;\n const executor = this.executionCoordinator.getExecutor(access.protocol);\n const capabilities = await executor.loadAppCapabilities(appId, access.config as any);\n\n return {\n text: this.guideService.generateAppGuide(appId, descriptor, capabilities),\n };\n }\n\n // ============================================================\n // Gateway tool guide (mcp:import, skill:import)\n // ============================================================\n\n handleGatewayToolGuide(toolName: string): GatewayTextResult {\n const tool = getGatewayToolDefinition(toolName);\n if (!tool) {\n throw new AaiError('UNKNOWN_TOOL', `Unknown tool: ${toolName}`);\n }\n return { text: generateGatewayToolGuide(tool) };\n }\n\n // ============================================================\n // Exec\n // ============================================================\n\n async handleExec(\n requestId: string | number,\n appIdOrUrl: string | undefined,\n toolName: string,\n args: Record<string, unknown>,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n if (!appIdOrUrl || appIdOrUrl === 'gateway') {\n if (isGatewayExecutionTool(toolName)) {\n return this.executeGatewayTool(toolName, args, caller);\n }\n throw new AaiError('INVALID_REQUEST', \"aai:exec requires 'app' for app tools\");\n }\n\n const resolved = await this.resolveApp(appIdOrUrl, caller);\n const startedAt = Date.now();\n\n logger.info(\n {\n requestId,\n app: resolved.appId,\n protocol: resolved.descriptor.access.protocol,\n tool: toolName,\n args: summarizeExecArgs(args),\n },\n 'aai:exec received'\n );\n\n try {\n const result = await this.executionCoordinator.executeWithInactivityTimeout(\n resolved.appId,\n resolved.descriptor,\n toolName,\n args\n );\n logger.info(\n {\n requestId,\n app: resolved.appId,\n protocol: resolved.descriptor.access.protocol,\n tool: toolName,\n durationMs: Date.now() - startedAt,\n result: summarizeExecResult(result),\n },\n 'aai:exec completed'\n );\n return this.toTextResult(result);\n } catch (err) {\n logger.error(\n {\n requestId,\n app: resolved.appId,\n protocol: resolved.descriptor.access.protocol,\n tool: toolName,\n durationMs: Date.now() - startedAt,\n err,\n },\n 'aai:exec failed'\n );\n throw err;\n }\n }\n\n // ============================================================\n // MCP Import\n // ============================================================\n\n async handleMcpImport(\n options: ParsedMcpImportArgs,\n rawArgs: Record<string, unknown> | undefined,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n try {\n logger.info(\n {\n tool: 'mcp:import',\n phase: options.metadata ? 'import' : 'inspect',\n request: summarizeMcpImportRequest(options),\n },\n 'MCP import request started'\n );\n\n if (!options.metadata) {\n const preview = await discoverMcpImport(getMcpExecutor(), {\n name: options.name,\n config: options.config,\n });\n\n logger.info(\n {\n tool: 'mcp:import',\n phase: 'inspect',\n appId: preview.appId,\n appName: preview.name,\n toolCount: preview.tools.length,\n },\n 'MCP import inspection completed'\n );\n\n return {\n text: [\n 'MCP inspection completed. No import record has been created yet.',\n `App name: ${preview.name}`,\n '',\n 'Available tools:',\n formatToolPreview(preview.tools),\n '',\n 'Next step:',\n '1. Summarize when this MCP should be used.',\n `2. Confirm a summary (in English, max ${EXPOSURE_LIMITS.summaryLength} chars) with the user. Communicate in the user\\'s preferred language, but the actual summary value must be English.`,\n '3. Ask the user whether this imported MCP should be enabled only for the current agent or for all agents.',\n '4. Call `mcp:import` again with the same source config plus `summary` and `enableScope`.',\n ].join('\\n'),\n };\n }\n\n const result = await this.importService.importMcp(\n {\n name: options.name,\n config: options.config,\n summary: options.metadata.summary,\n enableScope: options.metadata.enableScope,\n },\n caller\n );\n\n logger.info(\n {\n tool: 'mcp:import',\n phase: 'import',\n appId: result.appId,\n descriptorPath: result.managedPath,\n toolCount: result.tools.length,\n },\n 'MCP import completed'\n );\n\n const capabilities = {\n title: 'MCP Tools',\n tools: result.tools.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n inputSchema: t.inputSchema ?? { type: 'object' as const, properties: {} },\n })),\n };\n\n return {\n text: [\n `Imported MCP app: ${result.descriptor.app.name.default}`,\n `App ID: ${result.appId}`,\n `App tool prefix: app:${result.appId}`,\n `Descriptor: ${result.managedPath}`,\n `Summary: ${result.descriptor.exposure.summary}`,\n `Default enabled for: ${options.metadata.enableScope === 'current' ? 'importing agent only' : 'all agents'}`,\n '',\n this.guideService.generateAppGuide(result.appId, result.descriptor, capabilities),\n ].join('\\n'),\n };\n } catch (err) {\n logger.error(\n { tool: 'mcp:import', request: summarizeRawImportArgs(rawArgs), err },\n 'MCP import failed'\n );\n\n if (isMissingEnvVarsError(err)) {\n return buildMissingEnvVarsResult(err);\n }\n\n return createErrorResult('MCP import failed.', err);\n }\n }\n\n // ============================================================\n // Skill Import\n // ============================================================\n\n async handleSkillImport(\n options: ParsedSkillImportArgs,\n rawArgs: Record<string, unknown> | undefined,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n try {\n logger.info(\n {\n tool: 'skill:import',\n phase: 'import',\n request: summarizeSkillImportRequest(options),\n },\n 'Skill import request started'\n );\n\n const result = await this.importService.importSkill({ path: options.path }, caller);\n\n logger.info(\n {\n tool: 'skill:import',\n phase: 'import',\n appId: result.appId,\n managedPath: result.managedPath,\n },\n 'Skill import completed'\n );\n\n const executor = this.executionCoordinator.getExecutor(result.descriptor.access.protocol);\n let capabilities;\n try {\n capabilities = await executor.loadAppCapabilities(\n result.appId,\n result.descriptor.access.config as any\n );\n } catch {\n capabilities = {\n title: 'Skill',\n tools: [\n {\n name: 'read',\n description: 'Read the skill documentation',\n inputSchema: { type: 'object' as const, properties: {} },\n },\n ],\n };\n }\n\n return {\n text: [\n `Imported skill: ${result.descriptor.app.name.default}`,\n `App ID: ${result.appId}`,\n `App tool prefix: app:${result.appId}`,\n `Skill directory: ${result.managedPath}`,\n `Summary: ${result.descriptor.exposure.summary}`,\n 'Default enabled for: importing agent only',\n '',\n this.guideService.generateAppGuide(result.appId, result.descriptor, capabilities),\n ].join('\\n'),\n };\n } catch (err) {\n logger.error(\n { tool: 'skill:import', request: summarizeRawImportArgs(rawArgs), err },\n 'Skill import failed'\n );\n return createErrorResult('Skill import failed.', err);\n }\n }\n\n // ============================================================\n // Search / Discover\n // ============================================================\n\n handleSearchDiscover(args: Record<string, unknown> | undefined): GatewayTextResult {\n try {\n parseSearchDiscoverArguments(args);\n return { text: buildSearchDiscoverResponse() };\n } catch (err) {\n throw new AaiError('INVALID_REQUEST', err instanceof Error ? err.message : String(err));\n }\n }\n\n // ============================================================\n // List / Enable / Disable / Remove\n // ============================================================\n\n async handleListAllApps(caller: CallerContext): Promise<GatewayTextResult> {\n const apps = await this.listManageableApps(caller);\n const payload = {\n apps: apps.map(({ app, enabled }) => ({\n app: app.appId,\n name: app.descriptor.app.name.default,\n summary: app.descriptor.exposure.summary,\n source: app.source,\n enabled,\n removable: app.source === 'mcp-import' || app.source === 'skill-import',\n })),\n };\n\n return {\n text: JSON.stringify(payload, null, 2),\n structuredContent: payload,\n };\n }\n\n async handleDisableApp(\n args: Record<string, unknown> | undefined,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n const appId = typeof args?.app === 'string' ? args.app.trim() : '';\n if (!appId) {\n throw new AaiError('INVALID_REQUEST', \"disableApp requires 'app'\");\n }\n\n await this.resolveManageableApp(appId);\n await disableAppForAgent(caller.id, appId);\n\n const payload = { app: appId, disabledFor: caller.id };\n return {\n text: JSON.stringify(payload, null, 2),\n structuredContent: payload,\n };\n }\n\n async handleEnableApp(\n args: Record<string, unknown> | undefined,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n const appId = typeof args?.app === 'string' ? args.app.trim() : '';\n if (!appId) {\n throw new AaiError('INVALID_REQUEST', \"enableApp requires 'app'\");\n }\n\n await this.resolveManageableApp(appId);\n await enableAppForAgent(caller.id, appId);\n\n const payload = { app: appId, enabledFor: caller.id };\n return {\n text: JSON.stringify(payload, null, 2),\n structuredContent: payload,\n };\n }\n\n async handleRemoveApp(\n args: Record<string, unknown> | undefined,\n _caller: CallerContext\n ): Promise<GatewayTextResult> {\n const appId = typeof args?.app === 'string' ? args.app.trim() : '';\n if (!appId) {\n throw new AaiError('INVALID_REQUEST', \"removeApp requires 'app'\");\n }\n\n if (args?.confirm !== true) {\n throw new AaiError(\n 'INVALID_REQUEST',\n \"removeApp requires 'confirm: true' after the agent explains the global impact and the user explicitly confirms.\"\n );\n }\n\n const app = await this.resolveManageableApp(appId);\n if (app.source !== 'mcp-import' && app.source !== 'skill-import') {\n throw new AaiError(\n 'INVALID_REQUEST',\n `removeApp only supports AAI Gateway managed imports. '${appId}' is a '${app.source}' app.`\n );\n }\n\n await this.importService.removeApp(appId);\n\n const payload = { app: appId, removedFrom: 'all-agents' };\n return {\n text: JSON.stringify(payload, null, 2),\n structuredContent: payload,\n };\n }\n\n // ============================================================\n // Notification hook (called by server after state changes)\n // ============================================================\n\n get toolsChanged(): boolean {\n // marker for server to check; or use callback\n return false;\n }\n\n // ============================================================\n // Internal: Gateway tool routing\n // ============================================================\n\n private async executeGatewayTool(\n toolName: string,\n args: Record<string, unknown>,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n if (toolName === SEARCH_DISCOVER_TOOL_NAME) {\n return this.handleSearchDiscover(args);\n }\n if (toolName === 'listAllAaiApps') {\n return this.handleListAllApps(caller);\n }\n if (toolName === 'disableApp') {\n return this.handleDisableApp(args, caller);\n }\n if (toolName === 'enableApp') {\n return this.handleEnableApp(args, caller);\n }\n if (toolName === 'removeApp') {\n return this.handleRemoveApp(args, caller);\n }\n throw new AaiError('UNKNOWN_TOOL', `Unknown tool: ${toolName}`);\n }\n\n // ============================================================\n // Internal: App resolution\n // ============================================================\n\n private async resolveManagedApp(\n appId: string,\n caller: CallerContext\n ): Promise<{ app: RuntimeAppRecord } | { disabled: true; appId: string } | undefined> {\n const existing = this.appRegistry.get(appId);\n if (!existing) return undefined;\n\n if (await this.isAppEnabledForCaller(existing, caller)) {\n return { app: existing };\n }\n return { disabled: true, appId };\n }\n\n private async resolveManageableApp(appId: string): Promise<RuntimeAppRecord> {\n const existing = this.appRegistry.get(appId);\n if (!existing) {\n throw new AaiError('UNKNOWN_APP', `App not found: ${appId}`);\n }\n return existing;\n }\n\n private async resolveApp(appIdOrUrl: string, caller: CallerContext): Promise<RuntimeAppRecord> {\n const result = await this.resolveManagedApp(appIdOrUrl, caller);\n if (result && 'app' in result) return result.app;\n if (result && 'disabled' in result) {\n throw new AaiError(\n 'UNKNOWN_APP',\n `App \"${appIdOrUrl}\" is currently disabled for this agent. To enable it, call the enableApp tool with app: \"${appIdOrUrl}\". Please present this message to the user in their preferred language.`\n );\n }\n throw new AaiError('UNKNOWN_APP', `App not found: ${appIdOrUrl}`);\n }\n\n // ============================================================\n // Internal: Visibility\n // ============================================================\n\n private async listVisibleApps(caller: CallerContext): Promise<RuntimeAppRecord[]> {\n const apps = Array.from(this.appRegistry.values());\n const enabledApps = await Promise.all(\n apps.map(async (app) => ((await this.isAppEnabledForCaller(app, caller)) ? app : null))\n );\n return enabledApps.filter((app): app is RuntimeAppRecord => app !== null);\n }\n\n private async listManageableApps(caller: CallerContext): Promise<\n Array<{ app: RuntimeAppRecord; enabled: boolean }>\n > {\n const apps = Array.from(this.appRegistry.values());\n return Promise.all(\n apps.map(async (app) => ({\n app,\n enabled: await this.isAppEnabledForCaller(app, caller),\n }))\n );\n }\n\n private async isAppEnabledForCaller(\n app: RuntimeAppRecord,\n caller: CallerContext\n ): Promise<boolean> {\n const agentState = await upsertAgentState({\n agentId: caller.id,\n callerName: caller.name,\n agentType: caller.type,\n });\n\n const override = agentState.appOverrides[app.appId];\n if (override === 'enabled') return true;\n if (override === 'disabled') return false;\n\n const policy = await loadAppPolicyState(app.appId);\n if (!policy || policy.defaultEnabled === 'all') return true;\n\n return policy.importerAgentId === caller.id;\n }\n\n // ============================================================\n // Internal: Result formatting\n // ============================================================\n\n private toTextResult(result: unknown): GatewayTextResult {\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n return {\n text: JSON.stringify(result, null, 2),\n structuredContent: result as Record<string, unknown>,\n };\n }\n return {\n text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),\n };\n }\n}\n\n// ============================================================\n// Standalone helpers\n// ============================================================\n\nfunction formatToolPreview(tools: Array<{ name: string; description?: string }>): string {\n if (tools.length === 0) return 'No MCP tools reported.';\n return tools.map((tool) => `- ${tool.name}: ${tool.description ?? ''}`.trimEnd()).join('\\n');\n}\n\nexport function createErrorResult(summary: string, err: unknown): GatewayTextResult {\n const details: string[] = [summary];\n\n if (err instanceof AaiError) {\n details.push(`Error: ${err.message}`);\n if (err.data && Object.keys(err.data).length > 0) {\n details.push('', 'Details:', JSON.stringify(err.data, null, 2));\n }\n } else if (err instanceof Error) {\n details.push(`Error: ${err.message}`);\n } else {\n details.push(`Error: ${String(err)}`);\n }\n\n return { text: details.join('\\n'), isError: true };\n}\n\nfunction isMissingEnvVarsError(err: unknown): boolean {\n if (err instanceof AaiError) {\n const data = err.data as Record<string, unknown> | undefined;\n if (data?.code === 'MISSING_ENV_VARS') return true;\n }\n if (err instanceof Error && /Missing environment variables/i.test(err.message)) return true;\n return false;\n}\n\nfunction extractMissingVarNames(err: unknown): string[] {\n if (err instanceof AaiError) {\n const data = err.data as Record<string, unknown> | undefined;\n if (Array.isArray(data?.missingVars)) return data.missingVars as string[];\n }\n if (err instanceof Error) {\n const matches = err.message.match(/\\$\\{([^}]+)\\}/g);\n if (matches) return matches.map((m) => m.slice(2, -1));\n }\n return [];\n}\n\nfunction buildMissingEnvVarsResult(err: unknown): GatewayTextResult {\n const envFile = getDotenvPath();\n const missingVars = extractMissingVarNames(err);\n const varList = missingVars.length > 0 ? missingVars : ['<VARIABLE_NAME>'];\n\n const lines: string[] = [\n 'MCP import failed: missing environment variables.',\n '',\n '## What to do',\n '',\n `The following environment variables are required but not set: ${varList.map((v) => `\\`${v}\\``).join(', ')}`,\n '',\n '### Step 1 — Obtain the values',\n '',\n ...varList.map(\n (v) =>\n `- \\`${v}\\`: search the web for where to obtain this key (e.g. the provider\\'s developer portal or API dashboard).`\n ),\n '',\n '### Step 2 — Save to the AAI env file',\n '',\n `Open the env file for the user with a shell command:`,\n '```',\n `open ${envFile}`,\n '```',\n `Ask the user to add the values in the format:`,\n '```',\n ...varList.map((v) => `${v}=<paste_value_here>`),\n '```',\n '',\n 'Do not read or display the contents of this file — it contains sensitive secrets.',\n '',\n '### Step 3 — Retry',\n '',\n 'After the user confirms the values have been saved, call `mcp:import` again with the same parameters.',\n ];\n\n return { text: lines.join('\\n'), isError: true };\n}\n","/**\n * MCP Server\n *\n * Thin protocol layer — handles MCP request/response serialization\n * and delegates all business logic to Gateway (core/gateway.ts).\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n type CallToolResult,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport { AaiError } from '../errors/errors.js';\nimport type { CallerContext } from '../types/caller.js';\nimport { logger } from '../utils/logger.js';\nimport { AAI_GATEWAY_NAME, AAI_GATEWAY_VERSION } from '../version.js';\nimport { Gateway, type GatewayTextResult } from '../core/gateway.js';\nimport {\n parseMcpImportArguments,\n parseSkillImportArguments,\n normalizeArgumentsWithSchema,\n} from '../core/parsers.js';\n\nexport class AaiGatewayServer {\n private readonly server: Server;\n private readonly gateway = new Gateway();\n private callerContext?: CallerContext;\n\n constructor() {\n this.server = new Server(\n { name: AAI_GATEWAY_NAME, version: AAI_GATEWAY_VERSION },\n {\n capabilities: {\n tools: { listChanged: true },\n logging: {},\n },\n }\n );\n this.setupHandlers();\n }\n\n async initialize(): Promise<void> {\n await this.gateway.initialize();\n }\n\n async start(): Promise<void> {\n await this.initialize();\n const transport = new StdioServerTransport();\n await this.server.connect(transport);\n logger.info('AAI Gateway started (stdio)');\n }\n\n // ============================================================\n // MCP Protocol Handlers\n // ============================================================\n\n private setupHandlers(): void {\n this.server.oninitialized = () => {\n const clientVersion = this.server.getClientVersion();\n this.callerContext = this.gateway.createCallerContext(clientVersion);\n };\n\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n const tools = await this.gateway.listTools(this.requireCaller());\n return { tools };\n });\n\n this.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {\n const { name, arguments: rawArgs } = request.params;\n const caller = this.requireCaller();\n\n // Normalize args against tool schema if available\n const toolDef = this.gateway.getGatewayToolDefinition(name);\n const args = toolDef\n ? (normalizeArgumentsWithSchema(rawArgs, toolDef.inputSchema) as\n | Record<string, unknown>\n | undefined)\n : rawArgs;\n\n // app:<id> → guide\n if (name.startsWith('app:')) {\n return this.toCallToolResult(\n await this.gateway.handleAppGuide(name.slice(4), caller)\n );\n }\n\n // aai:exec → dispatch\n if (name === 'aai:exec') {\n const payload = args as { app?: string; tool: string; args?: Record<string, unknown> };\n return this.toCallToolResult(\n await this.gateway.handleExec(\n extra.requestId,\n payload.app,\n payload.tool,\n payload.args ?? {},\n caller\n )\n );\n }\n\n // mcp:import — empty args returns guide, otherwise execute\n if (name === 'mcp:import') {\n const rawMap = args as Record<string, unknown> | undefined;\n if (!rawMap || Object.keys(rawMap).length === 0) {\n return this.toCallToolResult(this.gateway.handleGatewayToolGuide(name));\n }\n const parsed = parseMcpImportArguments(rawMap);\n const result = await this.gateway.handleMcpImport(parsed, rawMap, caller);\n if (!result.isError) await this.notifyToolsListChanged();\n return this.toCallToolResult(result);\n }\n\n // skill:import — empty args returns guide, otherwise execute\n if (name === 'skill:import') {\n const rawMap = args as Record<string, unknown> | undefined;\n if (!rawMap || Object.keys(rawMap).length === 0) {\n return this.toCallToolResult(this.gateway.handleGatewayToolGuide(name));\n }\n const parsed = parseSkillImportArguments(rawMap);\n const result = await this.gateway.handleSkillImport(parsed, rawMap, caller);\n if (!result.isError) await this.notifyToolsListChanged();\n return this.toCallToolResult(result);\n }\n\n // Management tools routed through exec\n if (\n name === 'search:discover' ||\n name === 'listAllAaiApps' ||\n name === 'disableApp' ||\n name === 'enableApp' ||\n name === 'removeApp'\n ) {\n const toolArgs = (args as Record<string, unknown> | undefined) ?? {};\n let result: GatewayTextResult;\n\n switch (name) {\n case 'search:discover':\n result = this.gateway.handleSearchDiscover(toolArgs);\n break;\n case 'listAllAaiApps':\n result = await this.gateway.handleListAllApps(caller);\n break;\n case 'disableApp':\n result = await this.gateway.handleDisableApp(toolArgs, caller);\n await this.notifyToolsListChanged();\n break;\n case 'enableApp':\n result = await this.gateway.handleEnableApp(toolArgs, caller);\n await this.notifyToolsListChanged();\n break;\n case 'removeApp':\n result = await this.gateway.handleRemoveApp(toolArgs, caller);\n await this.notifyToolsListChanged();\n break;\n default:\n throw new AaiError('UNKNOWN_TOOL', `Unknown tool: ${name}`);\n }\n\n return this.toCallToolResult(result);\n }\n\n throw new AaiError('UNKNOWN_TOOL', `Unknown tool: ${name}`);\n });\n }\n\n // ============================================================\n // Helpers\n // ============================================================\n\n private requireCaller(): CallerContext {\n if (this.callerContext) return this.callerContext;\n return {\n id: 'unknown-client',\n name: 'Unknown Client',\n transport: 'mcp',\n type: 'unknown',\n };\n }\n\n private async notifyToolsListChanged(): Promise<void> {\n try {\n await this.server.sendToolListChanged();\n logger.debug('Sent tools/listChanged notification');\n } catch (error) {\n logger.error({ err: error }, 'Failed to send tools/listChanged notification');\n }\n }\n\n private toCallToolResult(result: GatewayTextResult): CallToolResult {\n return {\n content: [{ type: 'text', text: result.text }],\n ...(result.isError ? { isError: true } : {}),\n ...(result.structuredContent ? { structuredContent: result.structuredContent } : {}),\n };\n }\n}\n\nexport async function createGatewayServer(): Promise<AaiGatewayServer> {\n return new AaiGatewayServer();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,SAAgB,gBAAwB;AACtC,QAAO,GAAG,eAAe,CAAC;;;;;AAM5B,eAAsB,aAAoC;CACxD,MAAM,aAAa,eAAe;AAElC,KAAI;EACF,MAAM,UAAU,MAAM,SAAS,YAAY,QAAQ;EACnD,MAAM,MAA8B,EAAE;AAEtC,OAAK,MAAM,QAAQ,QAAQ,MAAM,KAAK,EAAE;GACtC,MAAM,UAAU,KAAK,MAAM;AAE3B,OAAI,CAAC,WAAW,QAAQ,WAAW,IAAI,CACrC;GAGF,MAAM,UAAU,QAAQ,QAAQ,IAAI;AACpC,OAAI,YAAY,GACd;GAGF,MAAM,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;GAC5C,IAAI,QAAQ,QAAQ,MAAM,UAAU,EAAE,CAAC,MAAM;AAG7C,OAAK,MAAM,WAAW,KAAI,IAAI,MAAM,SAAS,KAAI,IAC5C,MAAM,WAAW,IAAI,IAAI,MAAM,SAAS,IAAI,CAC/C,SAAQ,MAAM,MAAM,GAAG,GAAG;AAG5B,OAAI,IACF,KAAI,OAAO;;AAIf,SAAO;GAAE;GAAK,SAAS,EAAE;GAAE;UACpB,OAAO;AACd,MAAK,MAAgC,SAAS,SAC5C,QAAO;GAAE,KAAK,EAAE;GAAE,SAAS,EAAE;GAAE;AAEjC,QAAM;;;;;;AAOV,SAAgB,kBAAkB,KAAa,KAAqC;AAClF,QAAO,IAAI,QAAQ,mBAAmB,QAAQ,YAAY;EACxD,MAAM,QAAQ,IAAI;AAClB,MAAI,UAAU,KAAA,EACZ,OAAM,IAAI,MACR,2BAA2B,QAAQ,yCACpC;AAEH,SAAO;GACP;;;;;AAMJ,SAAgB,oBAAoB,KAAuB;CACzD,MAAM,UAAoB,EAAE;CAC5B,MAAM,QAAQ;CACd,IAAI;AACJ,SAAQ,QAAQ,MAAM,KAAK,IAAI,MAAM,KACnC,SAAQ,KAAK,MAAM,GAAG;AAExB,QAAO;;AAGT,SAAgB,mBAAmB,KAAsB;AACvD,QAAO,oBAAoB,IAAI,CAAC,SAAS;;;;;AAM3C,SAAS,iBAAiB,OAAe,KAAuC;AAE9E,QADqB,oBAAoB,MAAM,CAC3B,QAAQ,YAAY,IAAI,aAAa,KAAA,EAAU;;;;;;AAOrE,SAAgB,wBACd,QACA,KAC6C;CAC7C,MAAM,UAAoB,EAAE;CAC5B,MAAM,SAAkC,EAAE;AAE1C,MAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;EACrC,MAAM,QAAQ,OAAO;AACrB,MAAI,OAAO,UAAU,UAAU;GAC7B,MAAM,iBAAiB,iBAAiB,OAAO,IAAI;AACnD,WAAQ,KAAK,GAAG,eAAe;AAE/B,UAAO,OAAO,eAAe,SAAS,IAAI,QAAQ,kBAAkB,OAAO,IAAI;aACtE,MAAM,QAAQ,MAAM,EAAE;GAE/B,MAAM,WAAsB,EAAE;AAC9B,QAAK,MAAM,QAAQ,MACjB,KAAI,OAAO,SAAS,UAAU;IAC5B,MAAM,gBAAgB,iBAAiB,MAAM,IAAI;AACjD,YAAQ,KAAK,GAAG,cAAc;AAC9B,aAAS,KAAK,cAAc,SAAS,IAAI,OAAO,kBAAkB,MAAM,IAAI,CAAC;cACpE,OAAO,SAAS,YAAY,SAAS,MAAM;IAEpD,MAAM,EAAE,QAAQ,WAAW,SAAS,eAAe,wBACjD,MACA,IACD;AACD,YAAQ,KAAK,GAAG,WAAW;AAC3B,aAAS,KAAK,UAAU;SAExB,UAAS,KAAK,KAAK;AAGvB,UAAO,OAAO;aACL,OAAO,UAAU,YAAY,UAAU,MAAM;GAEtD,MAAM,EAAE,QAAQ,WAAW,SAAS,eAAe,wBACjD,OACA,IACD;AACD,WAAQ,KAAK,GAAG,WAAW;AAC3B,UAAO,OAAO;QAEd,QAAO,OAAO;;AAIlB,QAAO;EAAE;EAAQ;EAAS;;;;AClJ5B,IAAM,gBAAgB;;;;;;AAkBtB,IAAa,gBAAb,MAA2B;CACzB;CAEA,cAAc;AAEZ,OAAK,WAAW,IAAI,aADC,KAAK,oBAAoB,EAAE,cAAc,GAG3D,WAAW;GACV,IAAI,MAAM;GACV,OAAO,MAAM;GACb,UAAU,MAAM;GAChB,QAAQ,MAAM;GACd,cAAc,MAAM;GACpB,gBAAgB,MAAM;GACtB,YAAY,MAAM;GAClB,WAAW,MAAM;GAClB,IACA,QAAQ,IACV;;;;;CAMH,MAAM,OAAsC;AAC1C,SAAO,KAAK,SAAS,MAAM;;;;;CAM7B,MAAM,IAAI,IAAgD;AACxD,SAAO,KAAK,SAAS,IAAI,GAAG;;;;;CAM9B,MAAM,OACJ,OACA,YAC6B;EAC7B,MAAM,WAAW,MAAM,KAAK,IAAI,MAAM,MAAM;EAC5C,MAAM,uBAAM,IAAI,MAAM,EAAC,aAAa;EACpC,MAAM,SAAS,iBAAiB,MAAM,MAAM;EAC5C,MAAM,iBAAiB,KAAK,QAAQ,WAAW;AAE/C,QAAM,MAAM,QAAQ,EAAE,WAAW,MAAM,CAAC;AACxC,QAAM,UAAU,gBAAgB,KAAK,UAAU,YAAY,MAAM,EAAE,EAAE,QAAQ;EAE7E,MAAM,YAAgC;GACpC,IAAI,MAAM;GACV,GAAG;GACH;GACA,YAAY,UAAU,cAAc;GACpC,WAAW;GACZ;AAED,SAAO,KAAK,SAAS,OAAO,UAAU;;;;;CAMxC,MAAM,OAAO,IAA8B;AACzC,SAAO,KAAK,SAAS,OAAO,GAAG;;;;;CAMjC,MAAM,WAA+E;EACnF,MAAM,UAAU,MAAM,KAAK,MAAM;EACjC,MAAM,SAAoE,EAAE;AAE5E,OAAK,MAAM,SAAS,QAClB,KAAI;GACF,MAAM,MAAM,MAAM,SAAS,MAAM,gBAAgB,QAAQ;AACzD,UAAO,KAAK;IACV;IACA,YAAY,aAAa,KAAK,MAAM,IAAI,CAAC;IAC1C,CAAC;WACK,KAAK;AAKhB,SAAO;;;AAIX,IAAI,wBAA8C;AAElD,SAAgB,mBAAkC;AAChD,KAAI,CAAC,sBACH,yBAAwB,IAAI,eAAe;AAE7C,QAAO;;AAQT,eAAsB,sBAAsB,OAAmD;AAC7F,QAAO,kBAAkB,CAAC,IAAI,MAAM;;AAGtC,eAAsB,yBACpB,OACA,YAC6B;AAC7B,QAAO,kBAAkB,CAAC,OAAO,OAAO,WAAW;;;;AC1IrD,SAAgB,QAAQ,OAAuB;AAM7C,QALmB,MAChB,aAAa,CACb,QAAQ,kBAAkB,IAAI,CAC9B,QAAQ,YAAY,GAAG,IAEL;;AAGvB,SAAgB,YAAY,MAAc,WAAW,OAAe;AAElE,QAAO,GAAG,SAAS,GADN,WAAW,OAAO,CAAC,OAAO,KAAK,CAAC,OAAO,MAAM,CAAC,MAAM,GAAG,EAAE;;;;ACQxE,IAAa,gBAAgB;CAC3B,YAAY;CACZ,eAAe;CACf,WAAW;CACX,YAAY;CACZ,cAAc;CACd,WAAW;CACX,UAAU;CACV,WAAW;CACX,UAAU;CACV,cAAc;CACd,gBAAgB;CACjB;AAED,IAAa,kBAAkB,EAC7B,eAAe,KAChB;AA4DD,SAAgB,qBAAqB,OAAwC;AAC3E,8BAA6B,MAAM,SAAS,WAAW,cAAc,cAAc;AACnF,8BAA6B,MAAM,KAAK,OAAO,cAAc,UAAU;AACvE,8BAA6B,MAAM,KAAK,OAAO,cAAc,UAAU;AACvE,2BAA0B,MAAM,SAAS,WAAW,cAAc,aAAa;AAC/E,2BAA0B,MAAM,MAAM,QAAQ,cAAc,UAAU,cAAc,UAAU;AAC9F,4BACE,MAAM,KACN,OACA,cAAc,UACd,cAAc,cACd,cAAc,eACf;CAED,MAAM,UAAU,MAAM,WAAW,MAAM,QAAQ,SAAS,IAAI,MAAM,UAAU,KAAA;CAC5E,MAAM,MAAM,MAAM,OAAO,MAAM,IAAI,SAAS,IAAI,MAAM,MAAM,KAAA;AAE5D,KAAI,WAAW,IACb,OAAM,IAAI,MAAM,yDAAyD;AAG3E,KAAI,SAAS;AACX,MAAI,MAAM,UACR,OAAM,IAAI,MAAM,mDAAmD;AAGrE,SAAO;GACL,WAAW;GACX;GACA,GAAI,MAAM,YAAY,KAAA,IAAY,EAAE,SAAS,MAAM,SAAS,GAAG,EAAE;GACjE,GAAI,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,MAAM,MAAM,GAAG,EAAE;GACnE,GAAI,MAAM,OAAO,OAAO,KAAK,MAAM,IAAI,CAAC,SAAS,IAAI,EAAE,KAAK,MAAM,KAAK,GAAG,EAAE;GAC5E,GAAI,MAAM,MAAM,EAAE,KAAK,MAAM,KAAK,GAAG,EAAE;GACxC;;AAGH,KAAI,IACF,QAAO;EACL,WAAW,MAAM,aAAa;EAC9B;EACA,GAAI,MAAM,YAAY,KAAA,IAAY,EAAE,SAAS,MAAM,SAAS,GAAG,EAAE;EACjE,GAAI,MAAM,WAAW,OAAO,KAAK,MAAM,QAAQ,CAAC,SAAS,IAAI,EAAE,SAAS,MAAM,SAAS,GAAG,EAAE;EAC7F;AAGH,OAAM,IAAI,MAAM,4CAA4C;;AAG9D,SAAgB,uBAAuB,OAAuD;AAC5F,8BAA6B,MAAM,MAAM,QAAQ,cAAc,WAAW;CAE1E,MAAM,OAAO,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,MAAM,OAAO,KAAA;AAEhE,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,qCAAqC;AAGvD,QAAO,EAAE,MAAM;;AAGjB,SAAgB,sBAAsB,cAAoC;CACxE,MAAM,UAAU,aAAa,MAAM;AAEnC,KAAI,QAAQ,WAAW,EACrB,OAAM,IAAI,MAAM,2BAA2B;AAG7C,KAAI,QAAQ,SAAS,gBAAgB,cACnC,OAAM,IAAI,MACR,0CAA0C,gBAAgB,cAAc,cACzE;AAGH,QAAO,EAAE,SAAS;;AAGpB,eAAsB,kBACpB,UACA,SAC2B;CAC3B,MAAM,gBAAgB,yBAAyB,QAAQ,KAAK;CAC5D,MAAM,QAAQ,MAAM,qBAAqB,QAAQ,QAAQ,cAAc;CACvE,MAAM,QAAQ,MAAM,SAAS,UAAU;EACrC;EACA,QAAQ,QAAQ;EACjB,CAAC;AAGF,QAAO;EAAE;EAAO,MADd,iBAAkB,MAAM,iBAAiB,UAAU,QAAQ,QAAQ,MAAM;EACrD;EAAO;;AAG/B,eAAsB,gBACpB,UACA,SAC4B;CAC5B,MAAM,WAAW,4BAA4B,QAAQ;CACrD,MAAM,EAAE,gBAAgB,gBAAgB,MAAM,gCAAgC,QAAQ,OAAO;AAE7F,KAAI,YAAY,SAAS,GAAG;EAC1B,MAAM,gBAAgB,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC;AAC/C,QAAM,IAAI,MACR,oCAAoC,eAAe,CAAC,IAAI,cACrD,KAAK,MAAM,MAAM,EAAE,GAAG,CACtB,KAAK,KAAK,CAAC,GACf;;CAGH,MAAM,UAAU,MAAM,kBAAkB,UAAU;EAChD,GAAG;EACH,QAAQ;EACT,CAAC;CACF,MAAM,aAAa,2BACjB,QAAQ,MACR,QAAQ,QACR,sBAAsB,QAAQ,QAAQ,CACvC;AAWD,QAAO;EAAE,OATK,MAAM,uBAClB;GACE,OAAO,QAAQ;GACf,UAAU;GACV,QAAQ,QAAQ;GACjB,EACD,WACD;EAEe;EAAY,OAAO,QAAQ;EAAO,GAAI,SAAS,SAAS,IAAI,EAAE,UAAU,GAAG,EAAE;EAAG;;AAGlG,eAAsB,oBACpB,SAC6B;CAC7B,MAAM,SAAS,uBAAuB,QAAQ;CAC9C,MAAM,UAAU,MAAM,uBAAuB,OAAO;CACpD,MAAM,QAAQ,MAAM,uBAAuB,QAAQ,QAAQ;CAC3D,MAAM,cAAc,sBAAsB,QAAQ;AAClD,QAAO;EACL;EACA,MAAM,gBAAgB,QAAQ,QAAQ;EACtC,aAAa,YAAY;EACzB;EACD;;AAGH,eAAsB,YACpB,SACsE;CAEtE,MAAM,EAAE,KAAK,QAAQ,SAAS,iBAAiB,MAAM,YAAY;CAGjE,IAAI,eAAe;CACnB,IAAI,cAAwB,CAAC,GAAG,aAAa;AAE7C,KAAI,OAAO,KAAK,OAAO,CAAC,SAAS,GAAG;EAClC,MAAM,YAAY,QAAQ;AAC1B,MAAI,WAAW;GACb,MAAM,EAAE,QAAQ,aAAa,YAAY,wBACvC,EAAE,QAAQ,WAAW,EACrB,OACD;GACD,MAAM,oBAAoB,YAAY;AACtC,iBAAc,CAAC,GAAG,aAAa,GAAG,QAAQ;AAC1C,kBAAe;IAAE,GAAG;IAAS,MAAM;IAAmB;;;AAI1D,KAAI,YAAY,SAAS,GAAG;EAC1B,MAAM,gBAAgB,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC;AAC/C,QAAM,IAAI,MACR,oCAAoC,eAAe,CAAC,IAAI,cACrD,KAAK,MAAM,MAAM,EAAE,GAAG,CACtB,KAAK,KAAK,CAAC,GACf;;CAGH,MAAM,UAAU,MAAM,oBAAoB,aAAa;CACvD,MAAM,SAAS,uBAAuB,aAAa;CACnD,MAAM,cAAc,iBAAiB,QAAQ,MAAM;CACnD,MAAM,uBAAuB,KAAK,aAAa,QAAQ;AACvD,OAAM,MAAM,aAAa,EAAE,WAAW,MAAM,CAAC;AAE7C,OAAM,cAAc,OAAO,MAAO,qBAAqB;CAEvD,MAAM,aAAsB;EAC1B,eAAe;EACf,SAAS;EACT,KAAK,EACH,MAAM;GACJ,SAAS,QAAQ;GACjB,IAAI,QAAQ;GACb,EACF;EACD,QAAQ;GACN,UAAU;GACV,QAAQ,EACN,MAAM,sBACP;GACF;EACD,UAAU,sBAAsB,mBAAmB,QAAQ,CAAC;EAC7D;AAED,OAAM,UAAU,KAAK,aAAa,WAAW,EAAE,KAAK,UAAU,YAAY,MAAM,EAAE,EAAE,QAAQ;AAC5F,OAAM,yBACJ;EACE,OAAO,QAAQ;EACf,UAAU;EACV,QAAQ,EACN,MAAM,sBACP;EACF,EACD,WACD;AAED,QAAO;EAAE,OAAO,QAAQ;EAAO;EAAY,aAAa;EAAsB;;AAGhF,SAAS,4BAA4B,SAAqC;CACxE,MAAM,MAAM,QAAQ,OAAO,cAAc,UAAU,QAAQ,OAAO,MAAM,KAAA;CACxE,MAAM,UAAU,QAAQ,OAAO,cAAc,UAAW,QAAQ,OAAgD,UAAU,KAAA;AAC1H,KAAI,iCAAiC,IAAI,IAAI,iCAAiC,QAAQ,CACpF,QAAO,CACL,+HAA+H,eAAe,CAAC,kDAChJ;AAEH,QAAO,EAAE;;AAGX,SAAS,iCAAiC,QAA0C;AAClF,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,OAAO,QAAQ,OAAO,CAAC,MAC3B,CAAC,KAAK,WAAW,eAAe,IAAI,IAAI,CAAC,mBAAmB,MAAM,CACpE;;AAGH,SAAS,eAAe,KAAsB;CAC5C,MAAM,aAAa,IAAI,aAAa;AACpC,QACE,eAAe,mBACf,WAAW,SAAS,UAAU,IAC9B,WAAW,SAAS,SAAS,IAC7B,WAAW,SAAS,WAAW,IAC/B,WAAW,SAAS,SAAS,IAC7B,WAAW,SAAS,UAAU,IAC9B,WAAW,SAAS,YAAY;;AAIpC,eAAsB,gCACpB,QAIC;CACD,MAAM,EAAE,KAAK,QAAQ,SAAS,iBAAiB,MAAM,YAAY;CAEjE,MAAM,EAAE,QAAQ,mBAAmB,SAAS,kBAAkB,wBADd,KAAK,MAAM,KAAK,UAAU,OAAO,CAAC,EAGhF,OACD;AAGD,QAAO;EACL,gBAAgB;EAChB,aAHkB,CAAC,GAAG,cAAc,GAAG,cAAc;EAItD;;AAGH,SAAgB,sBAAsB,SAAmC;CACvE,MAAM,QAAQ,QAAQ,MAAM,2CAA2C;AACvE,KAAI,CAAC,MACH,QAAO,EAAE,MAAM,SAAS;CAG1B,MAAM,GAAG,gBAAgB,QAAQ;CACjC,MAAM,yBAAS,IAAI,KAAqB;AACxC,MAAK,MAAM,QAAQ,eAAe,MAAM,KAAK,EAAE;EAC7C,MAAM,aAAa,KAAK,MAAM,gCAAgC;AAC9D,MAAI,CAAC,WACH;EAGF,MAAM,GAAG,KAAK,SAAS;AACvB,SAAO,IAAI,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC,QAAQ,gBAAgB,GAAG,CAAC;;AAGzE,QAAO;EACL,MAAM,OAAO,IAAI,OAAO;EACxB,aAAa,OAAO,IAAI,cAAc;EACtC;EACD;;AAGH,eAAe,iBACb,UACA,QACA,OACiB;CACjB,MAAM,aAAa,MAAM,SAAS,gBAAgB;EAChD;EACA;EACD,CAAC;AACF,KAAI,YAAY,KACd,QAAO,WAAW;AAGpB,QAAO,OAAO,cAAc,UAAU,SAAS,OAAO,QAAQ,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC;;AAGvF,SAAS,2BAA2B,MAAc,QAAmB,UAAiC;AACpG,QAAO;EACL,eAAe;EACf,SAAS;EACT,KAAK,EACH,MAAM;GACJ,SAAS;GACT,IAAI;GACL,EACF;EACD,QAAQ;GACN,UAAU;GACV;GACD;EACD;EACD;;AAGH,eAAe,qBAAqB,QAAmB,MAAgC;CACrF,MAAM,YAAY,oBAAoB,QAAQ,KAAK;CACnD,MAAM,WAAW,MAAM,oBAAoB,UAAU;AACrD,KAAI,CAAC,SACH,QAAO;AAGT,KAAI,KAAK,UAAU,SAAS,OAAO,KAAK,KAAK,UAAU,OAAO,CAC5D,QAAO;CAGT,MAAM,OACJ,OAAO,cAAc,UACjB,OAAO,OAAO,QAAQ,IAAI,OAAO,QAAQ,EAAE,EAAE,KAAK,IAAI,KACtD,OAAO,OAAO,UAAU,GAAG,OAAO;AACxC,QAAO,YAAY,OAAO,GAAG,KAAK,QAAQ,SAAS,MAAM,UAAU;;AAGrE,SAAS,oBAAoB,QAAmB,MAAuB;AACrE,KAAI,KACF,QAAO,QAAQ,KAAK,IAAI;AAO1B,QAAO,QAHL,OAAO,cAAc,UACjB,sBAAsB,OAAO,SAAS,OAAO,KAAK,GAClD,uBAAuB,OAAO,IAAI,CACpB,IAAI;;AAG1B,SAAS,sBAAsB,SAAiB,MAAyB;CACvE,MAAM,aAAa,MAAM,MAAM,QAAQ,yBAAyB,IAAI,CAAC;AACrE,KAAI,WACF,QAAO,qBAAqB,WAAW;AAGzC,QAAO,qBAAqB,SAAS,QAAQ,CAAC;;AAGhD,SAAS,uBAAuB,KAAqB;CACnD,MAAM,SAAS,IAAI,IAAI,IAAI;CAC3B,MAAM,WAAW,OAAO,SAAS,QAAQ,UAAU,GAAG;CACtD,MAAM,qBAAqB,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI;CACrF,MAAM,WAAW,OAAO,SACrB,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,OAAO,QAAQ,CACf,MAAM,SAAS,SAAS,SAAS,SAAS,MAAM;AAEnD,QAAO,qBAAqB,sBAAsB,YAAY,SAAS;;AAGzE,SAAS,yBAAyB,OAAwB;AACxD,KAAI,CAAC,SAAS,MAAM,WAAW,IAAI,CACjC,QAAO;AAGT,KAAI,MAAM,WAAW,IAAI,IAAI,MAAM,WAAW,KAAK,IAAI,MAAM,WAAW,MAAM,IAAI,MAAM,SAAS,KAAK,CACpG,QAAO;AAGT,QAAO,MAAM,SAAS,IAAI,IAAI,MAAM,SAAS,IAAI,IAAI,0BAA0B,KAAK,MAAM;;AAG5F,SAAS,qBAAqB,OAAuB;CACnD,MAAM,UAAU,MAAM,MAAM;CAC5B,MAAM,eAAe,QAAQ,WAAW,IAAI,GAAG,QAAQ,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,GAAG;AAOvF,QAAO,SANa,aAAa,MAAM,IAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,cAElE,QAAQ,0BAA0B,GAAG,CACrC,QAAQ,gBAAgB,UAAU,CAClC,QAAQ,SAAS,GAAG,CAEG,IAAI;;AAGhC,SAAS,yBAAyB,MAA8C;AAC9E,8BAA6B,MAAM,QAAQ,cAAc,WAAW;CACpE,MAAM,aAAa,MAAM,MAAM;AAC/B,QAAO,cAAc,WAAW,SAAS,IAAI,aAAa,KAAA;;AAG5D,SAAS,gBAAgB,SAAiC,SAAyB;CACjF,MAAM,cAAc,sBAAsB,QAAQ;AAClD,KAAI,YAAY,KAAM,QAAO,YAAY;CAEzC,MAAM,aAAa,YAAY,KAAK,MAAM,cAAc;AACxD,KAAI,aAAa,GAAI,QAAO,WAAW,GAAG,MAAM;AAChD,KAAI,QAAQ,KAAM,QAAO,SAAS,QAAQ,KAAK;AAC/C,QAAO;;AAGT,eAAe,uBAAuB,SAAiC,SAAkC;CACvG,MAAM,YAAY,SAAS,qBAAqB,gBAAgB,SAAS,QAAQ,CAAC;AAElF,KAAI,CADa,MAAM,sBAAsB,UAAU,CAErD,QAAO;AAIT,QAAO,YADM,SAAS,QAAQ,QAAQ,oBACb,UAAU;;AAGrC,eAAe,uBAAuB,SAAkD;AACtF,KAAI,QAAQ,KACV,QAAO,SAAS,KAAK,QAAQ,MAAM,WAAW,EAAE,QAAQ;AAG1D,OAAM,IAAI,MAAM,qCAAqC;;AAGvD,eAAe,cAAc,WAAmB,WAAkC;AAEhF,QADW,MAAM,OAAO,qBACf,GAAG,WAAW,WAAW,EAAE,WAAW,MAAM,CAAC;;AAGxD,SAAS,mBAAmB,SAAqC;AAE/D,QAAO,uBADW,QAAQ,aAAa,MAAM,IAAI,sBAAsB,QAAQ,QAAQ,IAAI,OAAO,QAAQ,KAAK,wBACxE,MAAM,GAAG,gBAAgB,cAAc,CAAC,CAAC;;AAGlF,SAAS,sBAAsB,SAAyB;AAOtD,QANoB,sBAAsB,QAAQ,CACtB,KACzB,QAAQ,WAAW,GAAG,CACtB,MAAM,UAAU,CAChB,KAAK,UAAU,MAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM,CAAC,CACjD,MAAM,UAAU,MAAM,SAAS,EAAE,IAClB;;AAGpB,SAAS,6BACP,OACA,OACA,WACM;AACN,KAAI,UAAU,KAAA,EACZ;AAGF,KAAI,MAAM,SAAS,UACjB,OAAM,IAAI,MAAM,GAAG,MAAM,kCAAkC,UAAU,cAAc;;AAIvF,SAAS,0BACP,OACA,OACA,UACM;AACN,KAAI,UAAU,KAAA,EACZ;AAGF,KAAI,CAAC,OAAO,UAAU,MAAM,IAAI,SAAS,EACvC,OAAM,IAAI,MAAM,GAAG,MAAM,8CAA8C;AAGzE,KAAI,QAAQ,SACV,OAAM,IAAI,MAAM,GAAG,MAAM,kCAAkC,SAAS,GAAG;;AAI3E,SAAS,0BACP,QACA,OACA,UACA,eACM;AACN,KAAI,CAAC,OACH;AAGF,KAAI,OAAO,SAAS,SAClB,OAAM,IAAI,MAAM,GAAG,MAAM,6CAA6C,SAAS,GAAG;AAGpF,MAAK,MAAM,CAAC,OAAO,UAAU,OAAO,SAAS,CAC3C,KAAI,MAAM,SAAS,cACjB,OAAM,IAAI,MAAM,GAAG,MAAM,GAAG,MAAM,mCAAmC,cAAc,cAAc;;AAKvG,SAAS,2BACP,QACA,OACA,UACA,cACA,gBACM;AACN,KAAI,CAAC,OACH;CAGF,MAAM,UAAU,OAAO,QAAQ,OAAO;AACtC,KAAI,QAAQ,SAAS,SACnB,OAAM,IAAI,MAAM,GAAG,MAAM,gDAAgD,SAAS,GAAG;AAGvF,MAAK,MAAM,CAAC,KAAK,UAAU,SAAS;AAClC,MAAI,IAAI,SAAS,aACf,OAAM,IAAI,MACR,GAAG,MAAM,QAAQ,IAAI,MAAM,GAAG,GAAG,CAAC,uCAAuC,aAAa,cACvF;AAGH,MAAI,MAAM,SAAS,eACjB,OAAM,IAAI,MACR,GAAG,MAAM,cAAc,IAAI,MAAM,GAAG,GAAG,CAAC,yCAAyC,eAAe,cACjG;;;;;ACxkBP,IAAM,iCAAiC;;;;;;AAOvC,IAAa,cAAb,MAA6C;CAC3C,WAAoB;CACpB,0BAAkB,IAAI,KAA0B;CAGhD,6BAAqB,IAAI,KAA8B;CAEvD,MAAM,QAAQ,OAAe,QAAkC;EAC7D,MAAM,YAAY,KAAK,UAAU,EAAE,QAAQ,CAAC;EAC5C,MAAM,WAAW,KAAK,QAAQ,IAAI,MAAM;AACxC,MAAI,YAAY,SAAS,cAAc,UACrC;AAGF,MAAI,SACF,OAAM,KAAK,WAAW,MAAM;EAG9B,MAAM,SAAS,IAAI,OACjB;GAAE,MAAM;GAAkB,SAAS;GAAqB,EACxD,EAAE,cAAc,EAAE,EAAE,CACrB;EACD,MAAM,YAAY,KAAK,gBAAgB,OAAO;EAC9C,MAAM,oCAAoB,IAAI,KAAiC;AAC/D,YAAU,aAAa,YAAY;AACjC,QAAK,MAAM,YAAY,MAAM,KAAK,kBAAkB,CAClD,UAAS,QAAQ;;AAIrB,MAAI;AACF,SAAM,OAAO,QAAQ,UAAU;AAC/B,QAAK,QAAQ,IAAI,OAAO;IAAE;IAAQ;IAAW;IAAQ;IAAmB,CAAC;AACzE,UAAO,KAAK;IAAE;IAAO,QAAQ,qBAAmB,OAAO;IAAE,EAAE,6BAA6B;WACjF,KAAK;AACZ,UAAO,MAAM;IAAE;IAAO,QAAQ,qBAAmB,OAAO;IAAE;IAAK,EAAE,wBAAwB;AACzF,SAAM,IAAI,SACR,uBACA,8BAA8B,MAAM,KAAK,OAAO,IAAI,GACrD;;;CAIL,MAAM,WAAW,OAA8B;EAC7C,MAAM,WAAW,KAAK,QAAQ,IAAI,MAAM;AACxC,MAAI,CAAC,SAAU;AACf,OAAK,QAAQ,OAAO,MAAM;AAC1B,MAAI;AACF,SAAM,SAAS,OAAO,OAAO;UACvB;AAIR,OAAK,WAAW,OAAO,MAAM;;;;;CAO/B,MAAM,oBAAoB,OAAe,QAA6C;EACpF,MAAM,SAAS,MAAM,KAAK,UAAU;GAAE;GAAO;GAAQ,CAAC;AAGtD,OAAK,WAAW,IAAI,OAAO,OAAO;AAQlC,SAAO;GAAE,OAAO;GAAa,OANf,OAAO,KAAK,OAAO;IAC/B,MAAM,EAAE;IACR,aAAa,EAAE,eAAe;IAC9B,aAAa,EAAE,eAAe;KAAE,MAAM;KAAmB,YAAY,EAAE;KAAE;IAC1E,EAAE;GAEiC;;CAGtC,MAAM,QACJ,OACA,QACA,WACA,MAC0B;EAE1B,IAAI,QAAQ,KAAK,WAAW,IAAI,MAAM;AACtC,MAAI,CAAC,OAAO;AACV,SAAM,KAAK,oBAAoB,OAAO,OAAO;AAC7C,WAAQ,KAAK,WAAW,IAAI,MAAM;;EAEpC,MAAM,aAAa,OAAO,MAAM,MAAM,EAAE,SAAS,UAAU;AAC3D,MAAI,YAAY;GACd,MAAM,cAAc,WAAW,eAAe;IAAE,MAAM;IAAU,YAAY,EAAE;IAAE;GAChF,MAAM,SAAS,aAAa,MAAM,YAAY;AAC9C,OAAI,CAAC,OAAO,MAEV,QAAO;IACL,SAAS;IACT,OAHmB,eAAe,UAAU,KAAK,uBAAuB,OAAO;IAI/E,QAAQ;IACT;;AAIL,MAAI;AAMF,UAAO;IAAE,SAAS;IAAM,MALX,MAAM,KAAK,SACtB;KAAE;KAAO;KAAQ,EACjB,WACA,KACD;IAC6B;WACvB,KAAK;AACZ,UAAO;IACL,SAAS;IACT,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;IACxD;;;CAIL,MAAM,OAAO,OAAiC;AAC5C,SAAO,KAAK,QAAQ,IAAI,MAAM;;CAGhC,MAAM,UAAU,QAAuD;AACrE,MAAI;GAEF,MAAM,SAAS,OADA,MAAM,KAAK,cAAc,OAAO,EACnB,WAAW;AACvC,UAAO,KACL;IAAE,OAAO,OAAO;IAAO,QAAQ,qBAAmB,OAAO,OAAO;IAAE,WAAW,OAAO,MAAM;IAAQ,EAClG,mBACD;AACD,UAAO,OAAO;WACP,KAAK;AACZ,UAAO,MACL;IAAE,OAAO,OAAO;IAAO,QAAQ,qBAAmB,OAAO,OAAO;IAAE;IAAK,EACvE,2BACD;AACD,SAAM,IAAI,SACR,mBACA,6BAA6B,OAAO,MAAM,KAAK,OAAO,IAAI,GAC3D;;;CAIL,MAAM,cAAc,QAAiE;AAEnF,UADe,MAAM,KAAK,cAAc,OAAO,EACjC,kBAAkB;;CAGlC,MAAM,SACJ,QACA,UACA,MACA,UACkB;EAClB,MAAM,UAAU,YAA8B;GAC5C,MAAM,SAAS,MAAM,KAAK,cAAc,OAAO;GAC/C,MAAM,QAAQ,KAAK,QAAQ,IAAI,OAAO,MAAM;AAC5C,OAAI,CAAC,MACH,OAAM,IAAI,SAAS,uBAAuB,YAAY,OAAO,MAAM,oBAAoB;GAGzF,MAAM,oBAAoB,YAAqB;IAC7C,MAAM,sBAAsB,2BAA2B,QAAQ;AAC/D,QAAI,oBACG,WAAU,YAAY,EAAE,SAAS,qBAAqB,CAAC;;AAIhE,SAAM,kBAAkB,IAAI,iBAAiB;AAE7C,OAAI;IACF,MAAM,YAAY,uBAAuB,OAAO,OAAO;IACvD,MAAM,SAAU,MAAM,OAAO,SAC3B;KACE,MAAM;KACN,WAAW;KACZ,EACD,KAAA,GACA;KACE,SAAS;KACT,aAAa,aAAa;AACnB,gBAAU,aAAa;OAC1B,UAAU,SAAS;OACnB,GAAI,SAAS,UAAU,EAAE,SAAS,SAAS,SAAS,GAAG,EAAE;OAC1D,CAAC;;KAEL,CACF;AAED,UAAM,kBAAkB,OAAO,iBAAiB;AAChD,WAAO,KACL;KACE,OAAO,OAAO;KACd,MAAM;KACN,QAAQ,qBAAmB,OAAO,OAAO;KAC1C,EACD,0BACD;AACD,WAAO;YACA,KAAK;AACZ,UAAM,kBAAkB,OAAO,iBAAiB;AAChD,WAAO,MACL;KACE,OAAO,OAAO;KACd,MAAM;KACN,QAAQ,qBAAmB,OAAO,OAAO;KACzC;KACD,EACD,uBACD;AACD,UAAM;;;AAIV,MAAI;AACF,UAAO,MAAM,SAAS;WACf,KAAK;AACZ,SAAM,KAAK,MAAM,OAAO,MAAM;AAC9B,OAAI;AACF,WAAO,MAAM,SAAS;YACf,UAAU;AACjB,WAAO,MACL;KACE,OAAO,OAAO;KACd,MAAM;KACN,QAAQ,qBAAmB,OAAO,OAAO;KACzC,KAAK,YAAY;KAClB,EACD,mCACD;AACD,UAAM,IAAI,SACR,mBACA,aAAa,SAAS,gBAAgB,OAAO,MAAM,KAAK,OAAO,YAAY,IAAI,GAChF;;;;CAKP,MAAM,MAAM,OAA8B;AACxC,SAAO,KAAK,WAAW,MAAM;;CAG/B,gBAAwB,QAAmB;AACzC,UAAQ,OAAO,WAAf;GACE,KAAK,QACH,QAAO,IAAI,qBAAqB;IAC9B,SAAS,OAAO;IAChB,MAAM,OAAO;IACb,KAAK,OAAO;IACZ,KAAK,OAAO;IACZ,QAAQ;IACT,CAAC;GACJ,KAAK,kBACH,QAAO,IAAI,8BAA8B,IAAI,IAAI,OAAO,IAAI,EAAE,EAC5D,aAAa,OAAO,UAAU,EAAE,SAAS,OAAO,SAAS,GAAG,KAAA,GAC7D,CAAC;GACJ,KAAK,MACH,QAAO,IAAI,mBAAmB,IAAI,IAAI,OAAO,IAAI,EAAE,EACjD,aAAa,OAAO,UAAU,EAAE,SAAS,OAAO,SAAS,GAAG,KAAA,GAC7D,CAAC;;;CAIR,MAAc,cAAc,QAA8C;EACxE,MAAM,iBAAiB,MAAM,KAAK,cAAc,OAAO;AACvD,QAAM,KAAK,QAAQ,eAAe,OAAO,eAAe,OAAO;EAC/D,MAAM,QAAQ,KAAK,QAAQ,IAAI,OAAO,MAAM;AAC5C,MAAI,CAAC,MACH,OAAM,IAAI,SAAS,uBAAuB,YAAY,OAAO,MAAM,oBAAoB;AAEzF,SAAO,MAAM;;CAGf,MAAc,cAAc,QAA2D;EACrF,MAAM,EAAE,gBAAgB,gBAAgB,MAAM,gCAAgC,OAAO,OAAO;AAE5F,MAAI,YAAY,SAAS,GAAG;GAC1B,MAAM,gBAAgB,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC;AAC/C,SAAM,IAAI,SACR,mBACA,8CAA8C,OAAO,MAAM,KAAK,cAAc,KAAK,SAAS,MAAM,KAAK,GAAG,CAAC,KAAK,KAAK,IACrH;IACE,MAAM;IACN,aAAa;IACb,SAAS,eAAe;IACxB,cAAc,cAAc,KAAK,SAAS,GAAG,KAAK,kBAAkB;IACpE,YACE,eAAe,eAAe,CAAC;IAClC,CACF;;AAGH,SAAO;GAAE,OAAO,OAAO;GAAO,QAAQ;GAAgB;;;AAI1D,SAAS,uBAAuB,QAA2B;AACzD,QAAO,OAAO,WAAW;;AAG3B,SAAS,2BAA2B,SAAiC;AACnE,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO;AAIT,KADgB,QAAiC,WAClC,wBACb,QAAO;CAGT,MAAM,SAAU,QAAiC;AACjD,KAAI,CAAC,UAAU,OAAO,WAAW,SAC/B,QAAO;CAGT,MAAM,OAAQ,OAA8B;AAC5C,KAAI,OAAO,SAAS,YAAY,KAAK,SAAS,EAC5C,QAAO;AAGT,KAAI,SAAS,KAAA,GAAW;EACtB,MAAM,aAAa,KAAK,UAAU,KAAK;AACvC,SAAO,cAAc,eAAe,SAAS,aAAa;;AAG5D,QAAO;;AAGT,SAAS,qBAAmB,QAA4C;AACtE,SAAQ,OAAO,WAAf;EACE,KAAK,QACH,QAAO;GACL,WAAW,OAAO;GAClB,SAAS,OAAO;GAChB,YAAY,OAAO,MAAM,UAAU;GACnC,GAAI,OAAO,MAAM,EAAE,KAAK,OAAO,KAAK,GAAG,EAAE;GACzC,GAAI,OAAO,MAAM,EAAE,SAAS,OAAO,KAAK,OAAO,IAAI,EAAE,GAAG,EAAE;GAC1D,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,SAAS,GAAG,EAAE;GACtD;EACH,KAAK;EACL,KAAK,MACH,QAAO;GACL,WAAW,OAAO;GAClB,KAAK,OAAO;GACZ,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,SAAS,GAAG,EAAE;GACtD;;;AAIP,IAAI;AAEJ,SAAgB,iBAA8B;AAC5C,KAAI,CAAC,YACH,eAAY,IAAI,aAAa;AAE/B,QAAO;;;;ACnZT,IAAM,YAAY,UAAU,KAAK;AAOjC,eAAsB,+BACpB,YAC+B;CAC/B,MAAM,SAAS,WAAW,WAAW;AACrC,KAAI,CAAC,UAAU,OAAO,WAAW,EAC/B,QAAO;EAAE,WAAW;EAAM,UAAU;EAAM;CAG5C,IAAI,WAA0B;AAE9B,MAAK,MAAM,SAAS,OAClB,SAAQ,MAAM,MAAd;EACE,KAAK,WAAW;GACd,MAAM,cAAc,MAAM,mBAAmB,MAAM,QAAQ;AAC3D,OAAI,CAAC,YACH,QAAO;IAAE,WAAW;IAAO,UAAU;IAAM;AAG7C,OAAI,CAAC,SACH,YAAW;AAEb;;EAEF,KAAK,QAAQ;GACX,MAAM,WAAW,MAAM,gBAAgB,MAAM,KAAK;AAClD,OAAI,CAAC,SACH,QAAO;IAAE,WAAW;IAAO,UAAU;IAAM;AAG7C,OAAI,CAAC,SACH,YAAW;AAEb;;EAEF,KAAK,QAAQ;GACX,MAAM,eAAe,MAAM,qBAAqB,MAAM,KAAK;AAC3D,OAAI,CAAC,aACH,QAAO;IAAE,WAAW;IAAO,UAAU;IAAM;AAG7C,OAAI,CAAC,SACH,YAAW;AAEb;;;AAKN,QAAO;EAAE,WAAW;EAAM;EAAU;;AAGtC,eAAe,mBAAmB,SAAyC;AACzE,KAAI;EAEF,MAAM,EAAE,WAAW,MAAM,UADX,QAAQ,aAAa,UAAU,SAAS,YAAY,SAAS,UAClC;AACzC,SAAO,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM;SACjC;AACN,SAAO;;;AAIX,eAAe,gBAAgB,MAAsC;AACnE,KAAI;AAEF,UADiB,MAAM,KAAK,KAAK,EACjB,QAAQ,GAAG,OAAO;SAC5B;AACN,SAAO;;;AAIX,eAAe,qBAAqB,MAAsC;AACxE,KAAI;AAEF,OADiB,MAAM,KAAK,KAAK,EACpB,aAAa,EAAE;AAC1B,SAAM,OAAO,KAAK;AAClB,UAAO;;AAET,SAAO;SACD;AACN,SAAO;;;;;;;;;;;ACpEX,IAAa,kBAAb,MAA6B;;;;CAI3B,MAAM,OAAoC;AACxC,MAAI;GACF,MAAM,UAA8B,EAAE;GACtC,MAAM,OAAO,oBAAoB;GACjC,IAAI;AACJ,OAAI;AACF,cAAU,MAAM,QAAQ,MAAM,EAAE,eAAe,MAAM,CAAC;WAChD;AACN,WAAO,EAAE;;AAGX,QAAK,MAAM,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,aAAa,CACtB;AAGF,QAAI;KACF,MAAM,iBAAiB,KAAK,MAAM,MAAM,MAAM,WAAW;KACzD,MAAM,aAAa,aAAa,KAAK,MAAM,MAAM,SAAS,gBAAgB,QAAQ,CAAC,CAAC;KACpF,MAAM,eAAe,MAAM,+BAA+B,WAAW;AACrE,SAAI,CAAC,aAAa,UAChB;KAEF,MAAM,WAAW,WAAW,OAAO;KAEnC,IAAI;AACJ,aAAQ,UAAR;MACE,KAAK;AACH,gBAAS;AACT;MACF,KAAK;AACH,gBAAS;AACT;MACF,KAAK;AACH,gBAAS;AACT;MACF,KAAK;AACH,gBAAS;AACT;MACF,QACE;;AAGJ,aAAQ,KAAK;MACX,OAAO,MAAM;MACb;MACA;MACA,UAAU,aAAa,YAAY;MACpC,CAAC;YACI;;AAKV,UAAO;UACD;AACN,UAAO,EAAE;;;;;;CAOb,MAAM,IAAI,OAAiD;AAEzD,UADgB,MAAM,KAAK,MAAM,EAClB,MAAM,MAAM,EAAE,UAAU,MAAM,IAAI;;;;;;CAOnD,MAAM,OAAO,QAAkC;AAG7C,SAAO;;;;;CAMT,MAAM,IAAI,OAAiC;AAEzC,SADY,MAAM,KAAK,IAAI,MAAM,KAClB;;;;;;AAOnB,IAAI,0BAAkD;AACtD,SAAgB,qBAAsC;AACpD,KAAI,CAAC,wBACH,2BAA0B,IAAI,iBAAiB;AAEjD,QAAO;;AAIT,eAAsB,yBAAsD;AAC1E,QAAO,oBAAoB,CAAC,MAAM;;;;AC5GpC,SAAS,gBAAwB;AAC/B,QAAO,KAAK,eAAe,EAAE,SAAS;;AAGxC,SAAS,kBAAkB,SAAyB;AAClD,QAAO,KAAK,eAAe,EAAE,GAAG,QAAQ,OAAO;;AAGjD,SAAS,gBAAgB,OAAuB;AAC9C,QAAO,KAAK,eAAe,EAAE,QAAQ,GAAG,MAAM,OAAO;;AAGvD,SAAgB,eAAe,OAA2D;AACxF,KAAI,MAAM,YAAY,MAAM,SAAS,MAAM,CAAC,SAAS,EACnD,QAAO,QAAQ,MAAM,SAAS;AAEhC,KAAI,MAAM,cAAc,MAAM,WAAW,MAAM,CAAC,SAAS,EACvD,QAAO,QAAQ,MAAM,WAAW;AAElC,QAAO;;AAGT,eAAsB,eAAe,SAA6C;AAChF,KAAI;EACF,MAAM,MAAM,MAAM,SAAS,kBAAkB,QAAQ,EAAE,QAAQ;AAC/D,SAAO,KAAK,MAAM,IAAI;SAChB;AACN,SAAO;;;AAIX,eAAsB,eAAe,OAAkC;CACrE,MAAM,OAAO,kBAAkB,MAAM,QAAQ;AAC7C,OAAM,MAAM,QAAQ,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AAC/C,OAAM,UAAU,MAAM,KAAK,UAAU,OAAO,MAAM,EAAE,EAAE,QAAQ;;AAGhE,eAAsB,iBAAiB,OAIf;CACtB,MAAM,WAAW,MAAM,eAAe,MAAM,QAAQ;CACpD,MAAM,OAAmB;EACvB,SAAS,MAAM;EACf,YAAY,MAAM;EAClB,WAAW,MAAM,aAAa,UAAU;EACxC,cAAc,UAAU,gBAAgB,EAAE;EAC1C,4BAAW,IAAI,MAAM,EAAC,aAAa;EACpC;AACD,OAAM,eAAe,KAAK;AAC1B,QAAO;;AAGT,eAAsB,mBAAmB,SAAiB,OAAoC;CAC5F,MAAM,QAAS,MAAM,eAAe,QAAQ,IAAK;EAC/C;EACA,YAAY;EACZ,cAAc,EAAE;EAChB,4BAAW,IAAI,MAAM,EAAC,aAAa;EACpC;AAED,OAAM,aAAa,SAAS;AAC5B,OAAM,6BAAY,IAAI,MAAM,EAAC,aAAa;AAC1C,OAAM,eAAe,MAAM;AAC3B,QAAO;;AAGT,eAAsB,kBAAkB,SAAiB,OAAoC;CAC3F,MAAM,QAAQ,MAAM,eAAe,QAAQ;AAC3C,KAAI,CAAC,OAAO;EACV,MAAM,OAAmB;GACvB;GACA,YAAY;GACZ,cAAc,GAAG,QAAQ,WAAW;GACpC,4BAAW,IAAI,MAAM,EAAC,aAAa;GACpC;AACD,QAAM,eAAe,KAAK;AAC1B,SAAO;;AAGT,OAAM,aAAa,SAAS;AAC5B,OAAM,6BAAY,IAAI,MAAM,EAAC,aAAa;AAC1C,OAAM,eAAe,MAAM;AAC3B,QAAO;;AAGT,eAAsB,mBAAmB,OAA+C;AACtF,KAAI;EACF,MAAM,MAAM,MAAM,SAAS,gBAAgB,MAAM,EAAE,QAAQ;AAC3D,SAAO,KAAK,MAAM,IAAI;SAChB;AACN,SAAO;;;AAIX,eAAsB,mBACpB,OACA,OACe;CACf,MAAM,OAAO,gBAAgB,MAAM;AACnC,OAAM,MAAM,QAAQ,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AAC/C,OAAM,UAAU,MAAM,KAAK,UAAU,OAAO,MAAM,EAAE,EAAE,QAAQ;;AAGhE,eAAsB,qBAAqB,OAA8B;AACvE,OAAM,GAAG,gBAAgB,MAAM,EAAE,EAAE,OAAO,MAAM,CAAC;;AAGnD,eAAsB,uBAAuB,OAA8B;CACzE,IAAI,UAAoB,EAAE;AAC1B,KAAI;AACF,YAAU,MAAM,QAAQ,eAAe,CAAC;SAClC;AACN;;AAGF,MAAK,MAAM,SAAS,SAAS;AAC3B,MAAI,CAAC,MAAM,SAAS,QAAQ,CAAE;EAG9B,MAAM,QAAQ,MAAM,eADJ,MAAM,MAAM,GAAG,GAAgB,CACJ;AAC3C,MAAI,CAAC,MAAO;AAEZ,MAAI,MAAM,aAAa,QAAQ;AAC7B,UAAO,MAAM,aAAa;AAC1B,SAAM,6BAAY,IAAI,MAAM,EAAC,aAAa;AAC1C,SAAM,eAAe,MAAM;;;;;;ACnJjC,IAAa,4BAA4B;AAEzC,IAAa,4BAAqD;CAChE,MAAM;CACN,YAAY,EAAE;CACd,sBAAsB;CACvB;AAED,IAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiG9B,SAAgB,6BAA6B,MAAiD;AAC5F,KAAI,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,WAAW,EACxC;AAGF,OAAM,IAAI,MAAM,GAAG,0BAA0B,4BAA4B;;AAG3E,SAAgB,8BAAsC;AACpD,QAAO;;;;ACtFT,SAAgB,wBAAwB,MAAgE;AACtG,KAAI;EAGF,IAAI,UAAU,MAAM;EACpB,IAAI,YAAY,MAAM;AACtB,MAAI,MAAM,QAAQ,QAAQ,EAAE;GAC1B,MAAM,QAAQ,QAAQ,QAAQ,SAAyB,OAAO,SAAS,SAAS;AAChF,OAAI,MAAM,SAAS,GAAG;AACpB,cAAU,MAAM;AAChB,QAAI,MAAM,SAAS,EACjB,aAAY,CAAC,GAAG,MAAM,MAAM,EAAE,EAAE,GAAI,MAAM,QAAQ,UAAU,GAAG,YAAY,EAAE,CAAE;;;EAMrF,MAAM,MAAM,MAAM,OAAO,MAAM;EAG/B,MAAM,UAAU,MAAM;AAEtB,SAAO;GACL,MAAM,iBAAiB,MAAM,KAAK;GAClC,QAAQ,qBAAqB;IAC3B,WACE,MAAM,cAAc,qBAAqB,MAAM,cAAc,QACzD,KAAK,YACL,KAAA;IACN,KAAK,iBAAiB,MAAM,IAAI;IAChC,SAAS,iBAAiB,QAAQ;IAClC,SAAS,0BAA0B,MAAM,SAAS,UAAU;IAC5D,MAAM,sBAAsB,WAAW,OAAO;IAC9C,KAAK,uBAAuB,KAAK,MAAM;IACvC,KAAK,iBAAiB,MAAM,IAAI;IAChC,SAAS,uBAAuB,SAAS,UAAU;IACpD,CAAC;GACF,UAAU,+BAA+B,KAAK;GAC/C;UACM,KAAK;AACZ,QAAM,IAAI,SAAS,mBAAmB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;;;AAI3F,SAAgB,0BAA0B,MAAkE;AAC1G,KAAI;AAKF,SAAO,EAAE,MAJM,uBAAuB,EACpC,MAAM,iBAAiB,MAAM,KAAK,EACnC,CAAC,CAEoB,MAAO;UACtB,KAAK;AACZ,QAAM,IAAI,SAAS,mBAAmB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;;;AAI3F,SAAS,+BAA+B,MAE1B;CACZ,MAAM,aAAa,MAAM,YAAY,KAAA;CACrC,MAAM,iBAAiB,MAAM,gBAAgB,KAAA;CAC7C,MAAM,gBAAgB,OAAO,WAAW,GAAG,OAAO,eAAe;AAEjE,KAAI,kBAAkB,EAAG,QAAO,KAAA;AAEhC,KAAI,kBAAkB,EACpB,OAAM,IAAI,MACR,4HACD;CAGH,MAAM,UAAU,iBAAiB,MAAM,QAAQ;CAC/C,MAAM,cAAc,iBAAiB,MAAM,YAAY;AAEvD,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,qCAAqC;AAGvD,QAAO;EAAE,GAAG,sBAAsB,QAAQ;EAAE;EAAa;;AAG3D,SAAS,iBAAiB,OAAmC;AAC3D,KAAI,UAAU,aAAa,UAAU,MAAO,QAAO;AACnD,OAAM,IAAI,MAAM,oEAAoE;;AAOtF,SAAgB,iBAAiB,OAAoC;AACnE,QAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ,KAAA;;AAGjE,SAAgB,0BAA0B,OAAgB,OAAmC;AAC3F,KAAI,UAAU,KAAA,EAAW,QAAO,KAAA;AAChC,KAAI,OAAO,UAAU,YAAY,CAAC,OAAO,UAAU,MAAM,IAAI,SAAS,EACpE,OAAM,IAAI,MAAM,GAAG,MAAM,6CAA6C;AAExE,QAAO;;AAGT,SAAgB,sBAAsB,OAAgB,OAAqC;CACzF,MAAM,aAAa,mBAAmB,MAAM;AAC5C,KAAI,eAAe,KAAA,EAAW,QAAO,KAAA;AACrC,KAAI,CAAC,MAAM,QAAQ,WAAW,CAC5B,OAAM,IAAI,SAAS,mBAAmB,GAAG,MAAM,8BAA8B;AAE/E,KAAI,WAAW,MAAM,SAAS,OAAO,SAAS,SAAS,KAAK,KAAA,EAC1D,OAAM,IAAI,SAAS,mBAAmB,GAAG,MAAM,4BAA4B;AAE7E,QAAO;;AAGT,SAAgB,uBAAuB,OAAgB,OAAmD;CACxG,MAAM,aAAa,mBAAmB,MAAM;AAC5C,KAAI,eAAe,KAAA,EAAW,QAAO,KAAA;AACrC,KAAI,CAAC,eAAe,WAAW,CAC7B,OAAM,IAAI,SAAS,mBAAmB,GAAG,MAAM,uCAAuC;AAExF,QAAO;;AAGT,SAAS,eAAe,OAAiD;AACvE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAAE,QAAO;AACxE,QAAO,OAAO,OAAO,MAAM,CAAC,OAAO,SAAS,OAAO,SAAS,SAAS;;AAGvE,SAAS,mBAAmB,OAAyB;AACnD,KAAI,OAAO,UAAU,SAAU,QAAO;CACtC,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,QAAQ,WAAW,KAAM,CAAC,QAAQ,WAAW,IAAI,IAAI,CAAC,QAAQ,WAAW,IAAI,CAAG,QAAO;AAC3F,KAAI;AACF,SAAO,KAAK,MAAM,QAAQ;SACpB;AACN,SAAO;;;AAIX,SAAgB,6BAA6B,OAAgB,QAA0C;CACrG,MAAM,aAAa,+BAA+B,OAAO,OAAO;CAChE,MAAM,OAAO,OAAO;AAEpB,KACE,SAAS,YACT,cACA,OAAO,eAAe,YACtB,CAAC,MAAM,QAAQ,WAAW,EAC1B;EACA,MAAM,aAAa,OAAO;EAC1B,MAAM,uBAAuB,OAAO;EACpC,MAAM,SAAkC,EAAE;AAE1C,OAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,WAAsC,EAAE;GAC/E,MAAM,iBAAiB,aAAa;AACpC,OAAI,kBAAkB,OAAO,mBAAmB,YAAY,CAAC,MAAM,QAAQ,eAAe,EAAE;AAC1F,WAAO,OAAO,6BAA6B,MAAM,eAA0C;AAC3F;;AAEF,OACE,wBACA,OAAO,yBAAyB,YAChC,CAAC,MAAM,QAAQ,qBAAqB,EACpC;AACA,WAAO,OAAO,6BACZ,MACA,qBACD;AACD;;AAEF,UAAO,OAAO;;AAEhB,SAAO;;AAGT,KAAI,SAAS,WAAW,MAAM,QAAQ,WAAW,EAAE;EACjD,MAAM,aAAa,OAAO;AAC1B,MAAI,cAAc,OAAO,eAAe,YAAY,CAAC,MAAM,QAAQ,WAAW,CAC5E,QAAO,WAAW,KAAK,SACrB,6BAA6B,MAAM,WAAsC,CAC1E;;AAIL,QAAO;;AAGT,SAAS,+BAA+B,OAAgB,QAA0C;AAChG,KAAI,OAAO,UAAU,SAAU,QAAO;CACtC,MAAM,eAAe,OAAO;CAC5B,MAAM,UAAU,MAAM,MAAM;AAE5B,KAAI,iBAAiB,YAAY,QAAQ,WAAW,IAAI,CACtD,KAAI;AAAE,SAAO,KAAK,MAAM,QAAQ;SAAU;AAAE,SAAO;;AAErD,KAAI,iBAAiB,WAAW,QAAQ,WAAW,IAAI,CACrD,KAAI;AAAE,SAAO,KAAK,MAAM,QAAQ;SAAU;AAAE,SAAO;;AAErD,QAAO;;AAOT,SAAgB,kBAAkB,MAAwD;CACxF,MAAM,UAAmC,EAAE,MAAM,OAAO,KAAK,KAAK,EAAE;AAEpE,KAAI,OAAO,KAAK,cAAc,SAAU,SAAQ,YAAY,KAAK;AACjE,KAAI,OAAO,KAAK,WAAW,SAAU,SAAQ,SAAS,KAAK;AAE3D,KAAI,OAAO,KAAK,SAAS,UAAU;AACjC,UAAQ,aAAa,KAAK,KAAK;AAC/B,UAAQ,cAAc,mBAAmB,KAAK,KAAK;YAC1C,OAAO,KAAK,YAAY,UAAU;AAC3C,UAAQ,gBAAgB,KAAK,QAAQ;AACrC,UAAQ,iBAAiB,mBAAmB,KAAK,QAAQ;YAChD,MAAM,QAAQ,KAAK,OAAO,CACnC,SAAQ,eAAe,KAAK,OAAO;AAGrC,KAAI,OAAO,KAAK,QAAQ,SAAU,SAAQ,MAAM,KAAK;AACrD,QAAO;;AAGT,SAAgB,oBAAoB,QAAsD;AACxF,KAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,CAAE,QAAO,KAAA;CAC3E,MAAM,SAAS;CACf,MAAM,UAAmC,EAAE;AAE3C,KAAI,OAAO,OAAO,WAAW,SAAU,SAAQ,SAAS,OAAO;AAC/D,KAAI,OAAO,OAAO,cAAc,SAAU,SAAQ,YAAY,OAAO;AACrE,KAAI,OAAO,OAAO,SAAS,UAAW,SAAQ,OAAO,OAAO;AAC5D,KAAI,OAAO,OAAO,cAAc,UAAW,SAAQ,YAAY,OAAO;AACtE,KAAI,OAAO,OAAO,WAAW,SAAU,SAAQ,SAAS,OAAO;AAC/D,KAAI,OAAO,OAAO,UAAU,SAAU,SAAQ,QAAQ,mBAAmB,OAAO,MAAM;AACtF,KAAI,MAAM,QAAQ,OAAO,QAAQ,EAAE;AACjC,UAAQ,gBAAgB,OAAO,QAAQ;EACvC,MAAM,cAAc,yBAAyB,OAAO,QAAQ;AAC5D,MAAI,YAAa,SAAQ,cAAc;;AAGzC,QAAO,OAAO,KAAK,QAAQ,CAAC,SAAS,IAAI,UAAU,KAAA;;AAGrD,SAAgB,uBACd,MACyB;AACzB,KAAI,CAAC,KAAM,QAAO,EAAE;AACpB,QAAO;EACL,MAAM,OAAO,KAAK,KAAK;EACvB,GAAI,OAAO,KAAK,SAAS,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,EAAE;EAC5D,GAAI,OAAO,KAAK,YAAY,WAAW,EAAE,SAAS,KAAK,SAAS,GAAG,EAAE;EACrE,GAAI,MAAM,QAAQ,KAAK,KAAK,GAAG,EAAE,YAAY,KAAK,KAAK,QAAQ,GAAG,EAAE;EACpE,GAAI,OAAO,KAAK,QAAQ,WAAW,EAAE,KAAK,KAAK,KAAK,GAAG,EAAE;EACzD,GAAI,OAAO,KAAK,QAAQ,WAAW,EAAE,KAAK,KAAK,KAAK,GAAG,EAAE;EACzD,GAAI,OAAO,KAAK,cAAc,WAAW,EAAE,WAAW,KAAK,WAAW,GAAG,EAAE;EAC3E,GAAI,OAAO,KAAK,SAAS,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,EAAE;EAC5D,GAAI,OAAO,KAAK,gBAAgB,WAAW,EAAE,aAAa,KAAK,aAAa,GAAG,EAAE;EACjF,GAAI,OAAO,KAAK,YAAY,WAAW,EAAE,eAAe,KAAK,QAAQ,QAAQ,GAAG,EAAE;EAClF,GAAI,KAAK,OAAO,OAAO,KAAK,QAAQ,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAI,GACpE,EAAE,SAAS,OAAO,KAAK,KAAK,IAA+B,EAAE,GAC7D,EAAE;EACP;;AAGH,SAAgB,0BAA0B,SAAuD;AAC/F,QAAO;EACL,GAAI,QAAQ,OAAO,EAAE,MAAM,QAAQ,MAAM,GAAG,EAAE;EAC9C,QAAQ,mBAAmB,QAAQ,OAAO;EAC1C,GAAI,QAAQ,WACR;GAAE,eAAe,QAAQ,SAAS,QAAQ;GAAQ,aAAa,QAAQ,SAAS;GAAa,GAC7F,EAAE;EACP;;AAGH,SAAgB,4BAA4B,SAAyD;AACnG,QAAO,EAAE,MAAM,QAAQ,MAAM;;AAG/B,SAAS,mBAAmB,QAA4C;AACtE,SAAQ,OAAO,WAAf;EACE,KAAK,QACH,QAAO;GACL,WAAW,OAAO;GAClB,SAAS,OAAO;GAChB,YAAY,OAAO,MAAM,UAAU;GACnC,GAAI,OAAO,MAAM,EAAE,KAAK,OAAO,KAAK,GAAG,EAAE;GACzC,GAAI,OAAO,MAAM,EAAE,SAAS,OAAO,KAAK,OAAO,IAAI,EAAE,GAAG,EAAE;GAC1D,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,SAAS,GAAG,EAAE;GACtD;EACH,KAAK;EACL,KAAK,MACH,QAAO;GACL,WAAW,OAAO;GAClB,KAAK,OAAO;GACZ,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,SAAS,GAAG,EAAE;GACtD;;;AAIP,SAAS,mBAAmB,OAAe,WAAW,KAAa;AACjE,QAAO,MAAM,UAAU,WAAW,QAAQ,GAAG,MAAM,MAAM,GAAG,SAAS,CAAC;;AAGxE,SAAS,yBAAyB,SAAoB,WAAW,KAAyB;CACxF,MAAM,OAAO,QACV,QACE,SACC,CAAC,CAAC,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,KAAK,CAC7D,CACA,QAAQ,SAAS,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,SAAS,CACvE,KAAK,SAAS,KAAK,KAAe,CAClC,KAAK,GAAG;AACX,QAAO,KAAK,SAAS,IAAI,mBAAmB,MAAM,SAAS,GAAG,KAAA;;;;;;;;;;ACjUhE,SAAgB,8BAAuD;AACrE,QAAO;EACL;GACE,MAAM;GACN,aACE;GACF,aAAa;IACX,MAAM;IACN,YAAY;KACV,KAAK;MACH,MAAM;MACN,aAAa;MACd;KACD,MAAM;MACJ,MAAM;MACN,aAAa;MACd;KACD,MAAM;MACJ,MAAM;MACN,sBAAsB;MACtB,aAAa;MACd;KACF;IACD,UAAU,CAAC,OAAO;IACnB;GACF;EACD;GACE,MAAM;GACN,aAAa;GACb,aAAa;IACX,MAAM;IACN,YAAY;KACV,MAAM;MACJ,MAAM;MACN,aAAa,gEAAgE,cAAc,WAAW;MACvG;KACD,WAAW;MACT,MAAM;MACN,MAAM,CAAC,mBAAmB,MAAM;MAChC,aACE;MACH;KACD,SAAS;MACP,MAAM;MACN,aAAa,oFAAoF,cAAc,cAAc;MAC9H;KACD,MAAM;MACJ,MAAM;MACN,OAAO,EAAE,MAAM,UAAU;MACzB,aAAa,oEAAoE,cAAc,SAAS,uBAAuB,cAAc,UAAU;MACxJ;KACD,KAAK;MACH,MAAM;MACN,sBAAsB,EAAE,MAAM,UAAU;MACxC,aAAa,wEAAwE,cAAc,SAAS;MAC7G;KACD,KAAK;MACH,MAAM;MACN,aAAa,4EAA4E,cAAc,UAAU;MAClH;KACD,SAAS;MACP,MAAM;MACN,aAAa,iFAAiF,cAAc,aAAa;MAC1H;KACD,KAAK;MACH,MAAM;MACN,aAAa,kFAAkF,cAAc,UAAU;MACxH;KACD,SAAS;MACP,MAAM;MACN,sBAAsB,EAAE,MAAM,UAAU;MACxC,aACE;MACH;KACD,SAAS;MACP,MAAM;MACN,aAAa,sFAAsF,gBAAgB,cAAc;MAClI;KACD,aAAa;MACX,MAAM;MACN,MAAM,CAAC,WAAW,MAAM;MACxB,aACE;MACH;KACF;IACD,UAAU;KACR;MACE,MAAM;MACN,SAAS;MACT,MAAM,CAAC,yBAAyB;MACjC;KACD;MACE,MAAM;MACN,SAAS;MACT,MAAM,CAAC,MAAM,wBAAwB;MACrC,KAAK;OAAE,MAAM;OAAS,uBAAuB;OAAQ;MACrD,SAAS;MACV;KACD;MACE,KAAK;MACL,SAAS;MACT,aAAa;MACd;KACD;MACE,SAAS;MACT,MAAM;OAAC;OAAM;OAA2C;OAAQ;MAChE,SAAS;MACT,aAAa;MACd;KACF;IACF;GACD,iBAAiB,2BAA2B;GAC7C;EACD;GACE,MAAM;GACN,aAAa;GACb,aAAa;IACX,MAAM;IACN,YAAY,EACV,MAAM;KACJ,MAAM;KACN,aAAa,4EAA4E,cAAc,WAAW;KACnH,EACF;IACD,UAAU,CAAC,EAAE,MAAM,2BAA2B,CAAC;IAChD;GACD,iBAAiB,2BAA2B;GAC7C;EACD;GACE,MAAM;GACN,aACE;GACF,aAAa;IACX,MAAM;IACN,YAAY,EAAE;IACd,sBAAsB;IACvB;GACF;EACD;GACE,MAAM;GACN,aAAa;GACb,aAAa;IACX,MAAM;IACN,YAAY,EACV,KAAK;KACH,MAAM;KACN,aAAa;KACd,EACF;IACD,UAAU,CAAC,MAAM;IAClB;GACF;EACD;GACE,MAAM;GACN,aAAa;GACb,aAAa;IACX,MAAM;IACN,YAAY,EACV,KAAK;KACH,MAAM;KACN,aAAa;KACd,EACF;IACD,UAAU,CAAC,MAAM;IAClB;GACF;EACD;GACE,MAAM;GACN,aAAa;GACb,aAAa;IACX,MAAM;IACN,YAAY;KACV,KAAK;MACH,MAAM;MACN,aAAa;MACd;KACD,SAAS;MACP,MAAM;MACN,aACE;MACH;KACF;IACD,UAAU,CAAC,OAAO,UAAU;IAC7B;GACF;EACD;GACE,MAAM;GACN,aACE;GACF,aAAa;GACb,iBAAiB,2BAA2B;GAC7C;EACF;;AAGH,SAAS,4BAAqD;AAC5D,QAAO;EACL,MAAM;EACN,YAAY,EAAE;EACd,sBAAsB;EACvB;;AAGH,SAAgB,yBAAyB,UAAqD;AAC5F,QAAO,6BAA6B,CAAC,MAAM,SAAS,KAAK,SAAS,SAAS;;AAG7E,SAAgB,uBAAuB,UAA2B;AAChE,QACE,aAAa,gBACb,aAAa,kBACb,aAAA,qBACA,aAAa,oBACb,aAAa,gBACb,aAAa,eACb,aAAa;;AAIjB,SAAgB,yBAAyB,MAAqC;AAC5E,KAAI,KAAK,SAAS,aAChB,QAAO,uBAAuB,KAAK;CAGrC,MAAM,WAAW,qBAAqB,KAAK,aAAa,KAAK,KAAK;AAClE,QAAO;EACL,KAAK,KAAK;EACV;EACA,yCAAyC,KAAK,KAAK;EACnD;EACA;EACA,6DAA6D,KAAK,KAAK;EACvE;EACA,GAAI,SAAS,SAAS,IAClB;GACE;GACA;GACA;GACA;GACA;GACA,GAAG,SAAS,SAAS,YAAY;IAC/B;IACA,KAAK,UACH;KAAE,MAAM;KAAY,MAAM;MAAE,MAAM,KAAK;MAAM,MAAM;MAAS;KAAE,EAC9D,MACA,EACD;IACD;IACA;IACD,CAAC;GACH,GACD,EAAE;EACP,CAAC,KAAK,KAAK;;AAGd,SAAS,uBAAuB,MAAqC;CACnE,MAAM,iBAAiB;EACrB,MAAM;EACN,MAAM;GACJ,MAAM;GACN,MAAM;IACJ,SAAS;IACT,MAAM,CAAC,MAAM,iCAAiC;IAC9C,SAAS;IACT,MAAM;IACP;GACF;EACF;CAED,MAAM,kBAAkB;EACtB,MAAM;EACN,MAAM;GACJ,MAAM;GACN,MAAM;IACJ,SAAS;IACT,MAAM,CAAC,MAAM,iCAAiC;IAC9C,SAAS;IACT,MAAM;IACN,SAAS;IACT,aAAa;IACd;GACF;EACF;CAED,MAAM,UAAU,eAAe;AAE/B,QAAO;EACL,KAAK,KAAK;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,KAAK,UAAU,gBAAgB,MAAM,EAAE;EACvC;EACA;EACA;EACA;EACA,KAAK,UAAU,iBAAiB,MAAM,EAAE;EACxC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,KAAK,QAAQ;EACb;EACA;EACA,+BAA+B,QAAQ;EACvC;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAS,qBACP,aACA,UAC2B;CAC3B,MAAM,cAAc,YAAY;AAChC,KAAI,MAAM,QAAQ,YAAY,IAAI,YAAY,SAAS,EACrD,QAAO,YACJ,QAAQ,UAA4C,CAAC,CAAC,SAAS,OAAO,UAAU,SAAS,CACzF,MAAM,GAAG,EAAE;AAGhB,KAAI,aAAa,aAAc,QAAO,EAAE;AACxC,KAAI,aAAa,iBAAkB,QAAO,CAAC,EAAE,CAAC;AAC9C,QAAO,EAAE;;;;ACzXX,IAAa,cAAb,MAAyB;CACvB,2BAAmB,IAAI,KAA+B;CAEtD,IAAI,OAAe,QAAgC;AACjD,OAAK,SAAS,IAAI,OAAO,OAAO;;CAGlC,IAAI,OAA6C;AAC/C,SAAO,KAAK,SAAS,IAAI,MAAM;;CAGjC,IAAI,OAAwB;AAC1B,SAAO,KAAK,SAAS,IAAI,MAAM;;CAGjC,OAAO,OAAwB;AAC7B,SAAO,KAAK,SAAS,OAAO,MAAM;;CAGpC,SAA6B;AAC3B,SAAO,MAAM,KAAK,KAAK,SAAS,QAAQ,CAAC;;CAG3C,SAA6C;AAC3C,SAAO,KAAK,SAAS,QAAQ;;CAG/B,OAAO,WAAsE;AAC3E,SAAO,KAAK,QAAQ,CAAC,OAAO,UAAU;;CAGxC,cAAc,UAAsC;AAClD,SAAO,KAAK,QAAQ,QAAQ,IAAI,WAAW,OAAO,aAAa,SAAS;;CAG1E,IAAI,OAAe;AACjB,SAAO,KAAK,SAAS;;CAGvB,MAAM,kBAAkB,aAAiE;AACvF,MAAI;GACF,MAAM,iBAAiB,MAAM,aAAa;AAC1C,QAAK,MAAM,OAAO,eAChB,MAAK,SAAS,IAAI,IAAI,OAAO,IAAI;AAEnC,UAAO,KAAK,EAAE,OAAO,eAAe,QAAQ,EAAE,qCAAqC;AACnF,UAAO,eAAe;WACf,KAAK;AACZ,UAAO,MAAM,EAAE,KAAK,EAAE,6CAA6C;AACnE,SAAM;;;;;;AC6DZ,SAAgB,iBAAiB,MAA6B,QAA6B;AACzF,KAAI,KAAK,QACP,QAAO,KAAK;CAGd,MAAM,SAAS,OAAO,MAAM,IAAI,CAAC;CACjC,MAAM,WAAW,OAAO,KAAK,KAAK,CAAC,MAAM,QAAQ,QAAQ,aAAa,IAAI,WAAW,OAAO,CAAC;AAC7F,KAAI,YAAY,KAAK,UACnB,QAAO,KAAK;AAGd,QAAO,KAAK;;AAGd,SAAgB,YAAY,QAAqC;AAC/D,QAAO,OAAO,aAAa;;AAG7B,SAAgB,cAAc,QAAuC;AACnE,QAAO,OAAO,aAAa;;AAG7B,SAAgB,iBAAiB,QAA0C;AACzE,QAAO,OAAO,aAAa;;AAO7B,SAAgB,kBAAkB,QAAgD;AAChF,QAAO,UAAU;;;;;;;;;AClInB,IAAa,gBAAb,MAA+C;CAC7C,WAAoB;CAEpB,MAAM,QAAQ,QAAgB,SAA2D;CAIzF,MAAM,WAAW,QAA+B;;;;;CAQhD,MAAM,oBACJ,QACA,SAC0B;AAC1B,SAAO;GACL,OAAO;GACP,OAAO,CACL;IACE,MAAM;IACN,aAAa;IACb,aAAa;KAAE,MAAM;KAAmB,YAAY,EAAE;KAAE;IACzD,CACF;GACF;;CAIH,MAAM,QACJ,QACA,QACA,WACA,MAC0B;AAC1B,MAAI;AACF,OAAI,cAAc,OAChB,OAAM,IAAI,SACR,gBACA,oDAAoD,UAAU,GAC/D;AAIH,UAAO;IAAE,SAAS;IAAM,MADX,MAAM,KAAK,UAAU,QAAQ,KAAK;IACjB;WACvB,KAAK;AACZ,UAAO;IACL,SAAS;IACT,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;IACxD;;;CAIL,MAAM,OAAO,QAAkC;AAE7C,SAAO;;CAKT,MAAM,gBAAgB,QAAwE;AAE5F,SAAO;GACL,OAAO;GACP,MAHc,MAAM,kBAAkB,OAAO;GAI9C;;CAGH,MAAM,aACJ,QACA,UACA,MACiB;EACjB,MAAM,SAAS,MAAM,KAAK,QAAQ,IAAI,QAAQ,UAAU,KAAK;AAC7D,MAAI,CAAC,OAAO,QACV,OAAM,IAAI,SAAS,mBAAmB,OAAO,SAAS,mBAAmB;AAE3E,SAAO,OAAO;;CAGhB,MAAc,UACZ,QACA,MACiB;EACjB,MAAM,UAAU,MAAM,kBAAkB,OAAO;EAC/C,MAAM,UAAU,OAAO,KAAK,YAAY,WAAW,KAAK,QAAQ,MAAM,GAAG;AACzE,MAAI,CAAC,QACH,QAAO;EAGT,MAAM,SAAS,IAAI,OAAO,UAAU,aAAa,QAAQ,CAAC,QAAQ,KAAK;EACvE,MAAM,QAAQ,QAAQ,MAAM,OAAO;AACnC,MAAI,OAAO,UAAU,KAAA,EACnB,QAAO;AAGT,SAAO,QAAQ,MAAM,MAAM,MAAM;;;AAIrC,eAAe,kBAAkB,QAA4D;AAC3F,KAAI,kBAAkB,OAAO,CAC3B,QAAO,SAAS,KAAK,OAAO,MAAM,WAAW,EAAE,QAAQ;CAGzD,MAAM,WAAW,MAAM,MAAM,GAAG,OAAO,IAAI,QAAQ,OAAO,GAAG,CAAC,WAAW;AACzE,KAAI,CAAC,SAAS,GACZ,OAAM,IAAI,SACR,uBACA,iCAAiC,OAAO,IAAI,IAAI,SAAS,OAAO,GACjE;AAEH,QAAO,SAAS,MAAM;;AAGxB,SAAS,aAAa,OAAuB;AAC3C,QAAO,MAAM,QAAQ,uBAAuB,OAAO;;AAGrD,IAAI;AAEJ,SAAgB,mBAAkC;AAChD,KAAI,CAAC,UACH,aAAY,IAAI,eAAe;AAEjC,QAAO;;AAMT,IAAa,sBACX,QACA,UACA,SACG,IAAI,eAAe,CAAC,aAAa,QAAQ,UAAU,KAAK;;;AC7I7D,IAAM,mCAAmC,KAAK;AAQ9C,IAAa,uBAAb,MAAkC;CAChC,MAAM,QACJ,OACA,YACA,UACA,MACA,UACkB;EAClB,MAAM,SAAS,WAAW;AAE1B,MAAI,YAAY,OAAO,CAErB,QADiB,gBAAgB,CACjB,SAAS;GAAE;GAAO,QAAQ,OAAO;GAAQ,EAAE,UAAU,MAAM,SAAS;AAGtF,MAAI,cAAc,OAAO,CACvB,QAAO,mBAAa,OAAO,QAAe,UAAU,KAAK;AAG3D,MAAI,iBAAiB,OAAO,EAAE;GAC5B,MAAM,WAAW,gBAAgB;AACjC,OAAI,YAAY,SAAS,oBACvB,QAAO,SAAS,oBAAoB,OAAO,OAAO,QAAQ,UAAU,MAAM,SAAS;AAErF,UAAO,SAAS,QAAQ,OAAO,OAAO,QAAQ,UAAU,KAAK;;AAG/D,QAAM,IAAI,MAAM,wBAAwB,KAAK,UAAU,OAAO,GAAG;;CAGnE,MAAM,6BACJ,OACA,YACA,UACA,MACA,UACkB;EAClB,MAAM,YAAY;AAElB,SAAO,IAAI,SAAS,SAAS,WAAW;GACtC,IAAI,YAAY;GAChB,IAAI;GAEJ,MAAM,UAAU,aAAyB;AACvC,QAAI,UAAW;AACf,gBAAY;AACZ,QAAI,MAAO,cAAa,MAAM;AAC9B,cAAU;;GAGZ,MAAM,wBAAwB;AAC5B,QAAI,MAAO,cAAa,MAAM;AAC9B,YAAQ,iBAAiB;KACvB,MAAM,wBAAQ,IAAI,MAChB,eAAe,MAAM,oBAAoB,UAAU,yBACpD;AACI,UAAK,yBAAyB,OAAO,WAAW,CAAC,cAAc;AAClE,mBAAa,OAAO,MAAM,CAAC;OAC3B;OACD,UAAU;;GAGf,MAAM,mBAAmB,KAAK,sBAAsB,UAAU,gBAAgB;AAC9E,oBAAiB;AAEjB,QAAK,QAAQ,OAAO,YAAY,UAAU,MAAM,iBAAiB,CAAC,MAC/D,WAAW,aAAa,QAAQ,OAAO,CAAC,GACxC,UAAU,aAAa,OAAO,MAAM,CAAC,CACvC;IACD;;CAGJ,YAAY,UAA4B;AACtC,UAAQ,UAAR;GACE,KAAK,MACH,QAAO,gBAAgB;GACzB,KAAK,QACH,QAAO,kBAAkB;GAC3B,KAAK,YACH,QAAO,gBAAgB;GACzB,QACE,OAAM,IAAI,MAAM,aAAa,SAAS,qCAAqC;;;CAIjF,sBACE,UACA,YACmB;AACnB,SAAO;GACL,WAAW,OAAO,UAAU;AAC1B,gBAAY;AACZ,UAAM,UAAU,YAAY,MAAM;;GAEpC,YAAY,OAAO,UAAU;AAC3B,gBAAY;AACZ,UAAM,UAAU,aAAa,MAAM;;GAErC,cAAc,OAAO,UAAU;AAC7B,gBAAY;AACZ,UAAM,UAAU,eAAe,MAAM;;GAExC;;CAGH,MAAc,yBAAyB,OAAe,YAAoC;EACxF,MAAM,SAAS,WAAW;AAC1B,MAAI;AACF,OAAI,YAAY,OAAO,EAAE;AACvB,UAAM,gBAAgB,CAAC,MAAM,MAAM;AACnC;;AAEF,OAAI,iBAAiB,OAAO,CAC1B,OAAM,gBAAgB,CAAC,WAAW,MAAM;WAEnC,KAAK;AACZ,UAAO,KAAK;IAAE;IAAO;IAAK,EAAE,oDAAoD;;;;;;;;;ACtItF,SAAgB,kBAAmC;AACjD,KAAI;AAQF,SAAO,gBANQ,aACb,YACA;GAAC;GAAQ;GAAM;GAAc,EAC7B;GAAE,UAAU;GAAS,SAAS;GAAM,CACrC,CAAC,MAAM,CAEsB;SACxB;AAGN,SAAO,gBADW,QAAQ,IAAI,QAAQ,QAAQ,IAAI,UAAU,QAAQ,IAAI,eAAe,KACtD;;;;;;AAOrC,SAAS,gBAAgB,QAAiC;CACxD,MAAM,QAAQ,OAAO,aAAa,CAAC,QAAQ,YAAY,GAAG;AAG1D,KAAI,MAAM,WAAW,UAAU,IAAI,UAAU,WAAW,UAAU,QAChE,QAAO;AAET,KAAI,MAAM,WAAW,UAAU,IAAI,UAAU,WAAW,UAAU,WAAW,UAAU,WAAW,UAAU,QAC1G,QAAO;AAET,KAAI,MAAM,WAAW,KAAK,CACxB,QAAO;AAIT,QAAO;;;;AC5BT,IAAM,8BAA8B;AAEpC,IAAM,qBAAqB;;;;;;;;;;AAW3B,IAAM,yBAAyB;;;;;;;;;;AAW/B,IAAM,yBAAyB;;;;;;;;;;AAW/B,IAAM,qBAAqB;;;;;AAM3B,IAAM,+BAA+B;;;AAQrC,SAAgB,yBAAyB,QAAgB,YAA6B;CAEpF,MAAM,SAAS;EACb,gBAFoB,eAAe,WAAW,IAAI,KAAK;EAGvD,SAAS,0BAA0B,WAAW,SAAS,QAAQ;EAChE;AAED,SAAQ,WAAW,OAAO,UAA1B;EACE,KAAK,MACH,QAAO,eAAe,6BAA6B,OAAO;EAC5D,KAAK,QACH,QAAO,eAAe,6BAA6B,OAAO;EAC5D,KAAK,MACH,QAAO,eAAe,6BAA6B,OAAO;EAC5D,KAAK,YACH,QAAO,eAAe,6BAA6B,OAAO;;;;;;AAOhE,SAAgB,yBACd,OACA,YACA,cACQ;CACR,MAAM,WAAW,WAAW,OAAO;AACnC,KAAI,aAAa,MACf,QAAO,4BAA4B,OAAO,YAAY,aAAa;AAErE,KAAI,aAAa,YACf,QAAO,4BAA4B,OAAO,YAAY,aAAa;CAGrE,MAAM,SAAS,iBAAiB;CAChC,MAAM,gBAAgB,iBAAiB,WAAW,IAAI,MAAM,OAAO;CACnE,MAAM,eAAe,kBAAkB,aAAa;CACpD,MAAM,kBAAkB,qBAAqB,UAAU,aAAa;CACpE,MAAM,eAAe,kBAAkB,UAAU,WAAW;AAE5D,QAAO,eAAe,oBAAoB;EACxC,gBAAgB;EAChB,UAAU;EACV,SAAS,WAAW,SAAS;EAC7B,OAAO;EACP,kBAAkB,kBACd,0DAA0D,MAAM,UAAU,gBAAgB,MAC1F;EACJ,eAAe,eAAe,iBAAiB,aAAa,MAAM;EACnE,CAAC;;AAGJ,SAAS,4BACP,OACA,YACA,cACQ;CACR,MAAM,SAAS,iBAAiB;AAIhC,QAAO,eAAe,wBAAwB;EAC5C,gBAJoB,iBAAiB,WAAW,IAAI,MAAM,OAAO;EAKjE,UAAU;EACV,OALmB,kBAAkB,aAAa;EAMnD,CAAC;;AAGJ,SAAS,4BACP,OACA,YACA,cACQ;CACR,MAAM,SAAS,iBAAiB;CAChC,MAAM,gBAAgB,iBAAiB,WAAW,IAAI,MAAM,OAAO;CACnE,MAAM,eAAe,qBAAqB,OAAO,aAAa;CAC9D,MAAM,eAAe,kBAAkB,aAAa,WAAW;AAE/D,QAAO,eAAe,wBAAwB;EAC5C,gBAAgB;EAChB,UAAU;EACV,OAAO;EACP,eAAe,eAAe,mBAAmB,aAAa,MAAM;EACrE,CAAC;;AAOJ,SAAS,kBACP,cACA,UAAuC,EAAE,EACjC;AACR,KAAI,aAAa,MAAM,WAAW,EAChC,QAAO;CAGT,MAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAO,aAAa,MACjB,KAAK,SAAS;EACb,MAAM,OAAO,KAAK,aAAa,MAAM;EACrC,MAAM,YAAY,OAAO,oBAAoB,KAAK,GAAG;AACrD,SAAO,eAAe,gBAAgB,qBAAqB,8BAA8B;GACvF,MAAM,KAAK;GACX,aAAa;GACb,QAAQ,gBAAgB,iBAAiB,KAAK,GAAG;GAClD,CAAC;GACF,CACD,KAAK,KAAK;;AAGf,SAAS,iBAAiB,MAA0B;CAClD,MAAM,SAAkC,EAAE,aAAa,KAAK,aAAa;AACzE,KAAI,KAAK,aACP,QAAO,eAAe,KAAK;AAE7B,QAAO;EAAC;EAAW,KAAK,UAAU,QAAQ,MAAM,EAAE;EAAE;EAAM,CAAC,KAAK,KAAK;;AAGvE,SAAS,oBAAoB,MAAsB;CACjD,MAAM,gBAAgB,KAAK,MAAM,eAAe,CAAC;AACjD,QAAO,cAAc,UAAU,MAAM,gBAAgB,GAAG,cAAc,MAAM,GAAG,IAAI,CAAC;;AAGtF,SAAS,qBAAqB,UAAkB,cAAuC;AACrF,SAAQ,UAAR;EACE,KAAK,MACH,QAAO;EAET,KAAK,YACH,QAAO;EAET,KAAK,QACH,QAAO,mBAAmB,aAAa;EAEzC,KAAK,MACH,QAAO,iBAAiB,aAAa;EAEvC,QACE,QAAO;;;AAIb,SAAS,kBAAkB,UAAkB,YAA6B;AACxE,SAAQ,UAAR;EACE,KAAK,YACH,QAAO;EACT,KAAK,QACH,QAAO,CACL,iDACA,qBAAqB,WAAW,CACjC,CAAC,KAAK,KAAK;EACd,KAAK,MACH,QAAO;EACT,QACE,QAAO;;;AAIb,SAAS,qBAAqB,YAA6B;AACzD,KAAI,cAAc,WAAW,OAAO,IAAI,kBAAkB,WAAW,OAAO,OAAO,CACjF,QAAO,0CAA0C,WAAW,OAAO,OAAO,KAAK;AAEjF,QAAO;;AAGT,SAAS,qBAAqB,OAAe,cAAuC;AAClF,KAAI,aAAa,MAAM,WAAW,EAChC,QAAO;AAGT,QAAO,aAAa,MACjB,KAAK,SAAS;EACb,MAAM,OAAO,KAAK,aAAa,MAAM;EACrC,MAAM,YAAY,OAAO,oBAAoB,KAAK,GAAG;EACrD,MAAM,UAAU,gBAAgB,KAAK,MAAM,MAAM;AAEjD,SAAO;GACL,OAAO,KAAK;GACZ;GACA;GACA;GACA;GACA;GACA,UAAU,KAAK,UAAU,SAAS,MAAM,EAAE,GAAG;GAC9C,CAAC,KAAK,KAAK;GACZ,CACD,KAAK,OAAO;;AAGjB,SAAS,mBAAmB,cAAuC;AACjE,KAAI,CAAC,aAAa,MAAM,MAAM,SAAS,KAAK,SAAS,OAAO,CAC1D,QAAO;AAGT,QAAO,kBAAkB;EACvB,MAAM;EACN,MAAM,EAAE;EACT,CAAC;;AAGJ,SAAS,iBAAiB,cAAuC;AAE/D,QAAO,kBAAkB;EACvB,MAFkB,aAAa,MAAM,MAAM,SAAS,KAAK,SAAS,MAAM,EAAE,QAAQ;EAGlF,MAAM,EACJ,MAAM,CAAC,SAAS,EACjB;EACF,CAAC;;AAGJ,SAAS,gBAAgB,UAAkB,OAA+C;AACxF,SAAQ,UAAR;EACE,KAAK,cACH,QAAO;GACL,KAAK;GACL,MAAM;GACN,MAAM,EACJ,KAAK,6BACN;GACF;EACH,KAAK,aACH,QAAO;GACL,KAAK;GACL,MAAM;GACN,MAAM;IACJ,WAAW;IACX,QAAQ,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAkC,CAAC;IACnE;GACF;EACH,KAAK,YACH,QAAO;GACL,KAAK;GACL,MAAM;GACN,MAAM,EACJ,QAAQ,YACT;GACF;EACH,KAAK,yBACH,QAAO;GACL,KAAK;GACL,MAAM;GACN,MAAM;IACJ,QAAQ;IACR,cAAc;IACd,UAAU;KACR,MAAM;KACN,UAAU;KACX;IACF;GACF;EACH,KAAK,cACH,QAAO;GACL,KAAK;GACL,MAAM;GACN,MAAM,EACJ,QAAQ,YACT;GACF;EACH,QACE,QAAO;;;AAIb,SAAS,kBAAkB,SAA0C;AACnE,QAAO;EAAC;EAAW,KAAK,UAAU,SAAS,MAAM,EAAE;EAAE;EAAM,CAAC,KAAK,KAAK;;AAGxE,SAAS,0BAA0B,SAAyB;AAC1D,QAAO,QAAQ,MAAM,CAAC,QAAQ,QAAQ,IAAI;;AAG5C,SAAS,eAAe,MAAqC;AAC3D,QAAO,KAAK,MAAM,KAAK,YAAY,KAAK;;;;;AAc1C,SAAS,eAAe,UAAkB,MAA4B;CACpE,IAAI,SAAS;AAGb,UAAS,OAAO,QAAQ,6CAA6C,GAAG,SAAS,YAAY;EAC3F,MAAM,QAAQ,KAAK;AACnB,MAAI,SAAS,UAAU,WAAW,UAAU,IAC1C,QAAO;AAET,SAAO;GACP;AAGF,UAAS,OAAO,QAAQ,mBAAmB,GAAG,YAAY;EACxD,MAAM,QAAQ,KAAK;AACnB,SAAO,UAAU,KAAA,IAAY,OAAO,MAAM,GAAG;GAC7C;AAEF,QAAO;;;;ACrWT,IAAa,eAAb,MAA0B;CACxB,iBAAiB,OAAe,YAAqB,cAAuC;AAC1F,SAAO,yBAAyB,OAAO,YAAY,aAAa;;CAGlE,oBAAoB,OAAe,YAA6B;AAC9D,SAAO,yBAAyB,OAAO,WAAW;;CAGpD,uBACE,MACA,wBAUC;AACD,SAAO,CACL,GAAG,KAAK,KAAK,SAAS;GACpB,MAAM,OAAO,IAAI;GACjB,aAAa,KAAK,oBAAoB,IAAI,OAAO,IAAI,WAAW;GAChE,aAAa;IAAE,MAAM;IAAU,YAAY,EAAE;IAAE;GAChD,EAAE,EACH,GAAG,uBAAuB,KAAK,UAAU;GACvC,MAAM,KAAK;GACX,aAAa,KAAK;GAClB,aAAa,KAAK,mBAAmB,KAAK;GAC3C,EAAE,CACJ;;;;;ACpBL,IAAa,gBAAb,MAA2B;CACzB,YACE,aAIA;AAJiB,OAAA,cAAA;;CAMnB,MAAM,UACJ,SAMA,QACuB;EACvB,MAAM,SAAS,MAAM,gBAAgB,gBAAgB,EAAE;GACrD,MAAM,QAAQ;GACd,QAAQ,QAAQ;GAChB,SAAS,QAAQ;GAClB,CAAC;AAEF,QAAM,mBAAmB,OAAO,MAAM,OAAO;GAC3C,gBAAgB,QAAQ,gBAAgB,YAAY,kBAAkB;GACtE,iBAAiB,OAAO;GACxB,4BAAW,IAAI,MAAM,EAAC,aAAa;GACpC,CAAC;AAEF,OAAK,YAAY,IAAI,OAAO,MAAM,OAAO;GACvC,OAAO,OAAO,MAAM;GACpB,YAAY,OAAO;GACnB,QAAQ;GACR,UAAU,OAAO,MAAM;GACxB,CAAC;AAEF,SAAO;GACL,OAAO,OAAO,MAAM;GACpB,YAAY,OAAO;GACnB,aAAa,OAAO,MAAM;GAC1B,OAAO,OAAO;GACf;;CAGH,MAAM,YACJ,SACA,QACuB;EACvB,MAAM,SAAS,MAAM,YAAY,EAAE,MAAM,QAAQ,MAAM,CAAC;AAExD,QAAM,mBAAmB,OAAO,OAAO;GACrC,gBAAgB;GAChB,iBAAiB,OAAO;GACxB,4BAAW,IAAI,MAAM,EAAC,aAAa;GACpC,CAAC;AAEF,OAAK,YAAY,IAAI,OAAO,OAAO;GACjC,OAAO,OAAO;GACd,YAAY,OAAO;GACnB,QAAQ;GACR,UAAU,OAAO;GAClB,CAAC;AAEF,SAAO;GACL,OAAO,OAAO;GACd,YAAY,OAAO;GACnB,aAAa,OAAO;GACpB,OAAO,EAAE;GACV;;CAGH,MAAM,UAAU,OAA8B;EAC5C,MAAM,EAAE,mBAAmB,MAAM,OAAO;EACxC,MAAM,WAAW,gBAAgB;AAGjC,MADiB,MAAM,SAAS,IAAI,MAAM,CAExC,OAAM,SAAS,OAAO,MAAM;MAE5B,OAAM,kBAAkB,CAAC,OAAO,MAAM;AAGxC,QAAM,qBAAqB,MAAM;AACjC,QAAM,uBAAuB,MAAM;AACnC,QAAM,GAAG,iBAAiB,MAAM,EAAE;GAAE,WAAW;GAAM,OAAO;GAAM,CAAC;;;;;;;;;AC5GvE,IAAa,UAAQ;AAErB,IAAa,eAAsB;CACjC,eAAe;CACf,SAAS;CACT,KAAK,EACH,MAAM;EACJ,SAAS;EACT,IAAI;EACJ,SAAS;EACV,EACF;CACD,WAAW,EACT,QAAQ,CACN;EAAE,MAAM;EAAW,SAAS;EAAO,EACnC;EAAE,MAAM;EAAW,SAAS;EAAU,CACvC,EACF;CACD,QAAQ;EACN,UAAU;EACV,QAAQ;GACN,SAAS;GACT,MAAM,CAAC,MAAM,mCAAmC;GACjD;EACF;CACD,UAAU,EACR,SAAS,mEACV;CACF;;;;;;;AC5BD,IAAa,UAAQ;AAErB,IAAa,eAAsB;CACjC,eAAe;CACf,SAAS;CACT,KAAK,EACH,MAAM;EACJ,SAAS;EACT,IAAI;EACJ,SAAS;EACV,EACF;CACD,WAAW,EACT,QAAQ,CACN;EAAE,MAAM;EAAW,SAAS;EAAO,EACnC;EAAE,MAAM;EAAW,SAAS;EAAS,CACtC,EACF;CACD,QAAQ;EACN,UAAU;EACV,QAAQ;GACN,SAAS;GACT,MAAM,CAAC,MAAM,4BAA4B;GAC1C;EACF;CACD,UAAU,EACR,SAAS,yEACV;CACF;;;;;;;AC5BD,IAAa,QAAQ;AAErB,IAAa,aAAsB;CACjC,eAAe;CACf,SAAS;CACT,KAAK,EACH,MAAM;EACJ,SAAS;EACT,IAAI;EACJ,SAAS;EACV,EACF;CACD,WAAW,EACT,QAAQ,CAAC;EAAE,MAAM;EAAW,SAAS;EAAY,CAAC,EACnD;CACD,QAAQ;EACN,UAAU;EACV,QAAQ;GACN,SAAS;GACT,MAAM,CAAC,MAAM;GACd;EACF;CACD,UAAU,EACR,SAAS,uFACV;CACF;;;ACRD,eAAe,0BAAyD;CACtE,MAAM,UAAU,uBAAA,OAAA;EAAA,iDAAA;EAAA,2CAAA;EAAA,8CAAA;EAAA,CAAwE;CACxF,MAAM,cAAoC,EAAE;AAE5C,MAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,QAAQ,EAAE;EACjD,MAAM,SAAS;AACf,MAAI,OAAO,SAAS,OAAO,WACzB,aAAY,KAAK;GAAE,OAAO,OAAO;GAAO,YAAY,OAAO;GAAY,CAAC;MAExE,QAAO,KAAK,EAAE,MAAM,EAAE,iEAAiE;;AAI3F,QAAO;;AAGT,eAAsB,0BAA2C;CAC/D,MAAM,cAAc,MAAM,yBAAyB;CACnD,IAAI,SAAS;AAEb,MAAK,MAAM,EAAE,OAAO,gBAAgB,YAClC,KAAI;EACF,MAAM,SAAS,iBAAiB,MAAM;AACtC,QAAM,MAAM,QAAQ,EAAE,WAAW,MAAM,CAAC;AACxC,QAAM,UACJ,KAAK,QAAQ,WAAW,EACxB,KAAK,UAAU,YAAY,MAAM,EAAE,EACnC,QACD;AACD;AACA,SAAO,MAAM,EAAE,OAAO,EAAE,8BAA8B;UAC/C,KAAK;AACZ,SAAO,MAAM;GAAE;GAAO;GAAK,EAAE,sCAAsC;;AAIvE,QAAO,KAAK,EAAE,OAAO,QAAQ,EAAE,+BAA+B;AAC9D,QAAO;;;;;;;;;;;;;ACrCT,IAAa,wBAAb,MAAmC;CACjC,wBAAgB,IAAI,KAA6B;CACjD,4BAAoB,IAAI,KAA6B;CACrD,UAAkB;CAElB,SAAS,MAA4B;AACnC,MAAI,KAAK,MAAM,IAAI,KAAK,KAAK,EAAE;AAC7B,UAAO,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,+CAA+C;AAChF;;AAEF,OAAK,MAAM,IAAI,KAAK,MAAM,KAAK;AAC/B,SAAO,MACL;GAAE,MAAM,KAAK;GAAM,cAAc,KAAK;GAAc,EACpD,6BACD;;CAGH,MAAM,WAA0B;AAC9B,MAAI,KAAK,SAAS;AAChB,UAAO,KAAK,0CAA0C;AACtD;;AAEF,OAAK,UAAU;EAEf,MAAM,iBAAiB,KAAK,qBAAqB;AACjD,SAAO,KAAK;GAAE,OAAO,KAAK,MAAM;GAAM,OAAO;GAAgB,EAAE,gCAAgC;AAE/F,OAAK,MAAM,QAAQ,gBAAgB;GACjC,MAAM,OAAO,KAAK,MAAM,IAAI,KAAK;AACjC,OAAI,CAAC,KACH;AAGF,OAAI;AACF,UAAM,KAAK,OAAO;AAClB,WAAO,KAAK,EAAE,MAAM,MAAM,EAAE,0BAA0B;YAC/C,KAAK;AACZ,WAAO,MAAM;KAAE,MAAM;KAAM;KAAK,EAAE,kCAAkC;;;;CAK1E,sBAAwC;EACtC,MAAM,0BAAU,IAAI,KAAa;EACjC,MAAM,SAAmB,EAAE;EAE3B,MAAM,SAAS,SAAiB;AAC9B,OAAI,QAAQ,IAAI,KAAK,CACnB;AAEF,WAAQ,IAAI,KAAK;GAEjB,MAAM,OAAO,KAAK,MAAM,IAAI,KAAK;AACjC,OAAI,MAAM;SACH,MAAM,OAAO,KAAK,aACrB,KAAI,KAAK,MAAM,IAAI,IAAI,CACrB,OAAM,IAAI;;AAKhB,UAAO,KAAK,KAAK;;AAGnB,OAAK,MAAM,QAAQ,KAAK,MAAM,MAAM,CAClC,OAAM,KAAK;AAGb,SAAO;;CAGT,UAAgB;AACd,MAAI,CAAC,KAAK,QACR;AAGF,SAAO,KAAK,EAAE,OAAO,KAAK,MAAM,MAAM,EAAE,gCAAgC;AAExE,OAAK,MAAM,GAAG,aAAa,KAAK,UAC9B,eAAc,SAAS;AAEzB,OAAK,UAAU,OAAO;AAEtB,OAAK,MAAM,CAAC,MAAM,SAAS,KAAK,MAC9B,KAAI;AACF,QAAK,MAAM;AACX,UAAO,MAAM,EAAE,MAAM,MAAM,EAAE,0BAA0B;WAChD,KAAK;AACZ,UAAO,MAAM;IAAE,MAAM;IAAM;IAAK,EAAE,iCAAiC;;AAIvE,OAAK,UAAU;AACf,SAAO,KAAK,+BAA+B;;CAG7C,iBAAiB,UAAkB,YAAoB,IAAsB;EAC3E,MAAM,WAAW,KAAK,UAAU,IAAI,SAAS;AAC7C,MAAI,SACF,eAAc,SAAS;EAGzB,MAAM,WAAW,kBAAkB;AACjC,OAAI;AACF,QAAI;YACG,KAAK;AACZ,WAAO,MAAM;KAAE,MAAM;KAAU;KAAK,EAAE,sCAAsC;;KAE7E,WAAW;AAEd,OAAK,UAAU,IAAI,UAAU,SAAS;AACtC,SAAO,MAAM;GAAE,MAAM;GAAU;GAAY,EAAE,6CAA6C;;;;;;;;;;;;;ACrH9F,IAAa,2BAAb,MAAgE;CAC9D,OAAgB;CAChB,eAAkC,EAAE;CAEpC,YAAY,aAA2C;AAA1B,OAAA,cAAA;;CAE7B,MAAM,QAAuB;EAC3B,MAAM,UAAU,KAAK,YAAY,cAAc,YAAY;AAE3D,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAO,MAAM,4BAA4B;AACzC;;AAGF,SAAO,KAAK,EAAE,OAAO,QAAQ,QAAQ,EAAE,yBAAyB;AAEhE,OAAK,MAAM,OAAO,SAAS;GACzB,MAAM,EAAE,mBAAmB,MAAM,OAAO;GACxC,MAAM,SAAS,IAAI,WAAW,OAAO;AAChC,mBAAgB,CAClB,QAAQ,IAAI,OAAO,OAAO,CAC1B,WAAW;AACV,WAAO,KAAK,EAAE,OAAO,IAAI,OAAO,EAAE,+BAA+B;KACjE,CACD,OAAO,QAAQ;AACd,WAAO,KAAK;KAAE,OAAO,IAAI;KAAO;KAAK,EAAE,gDAAgD;KACvF;;;CAIR,OAAa;;;;;;;;;;AChCf,IAAM,oBAAoB,QAAc,KAAK;AAC7C,IAAM,sBAAsB,OAAU;AAEtC,IAAa,kBAAb,MAAuD;CACrD,OAAgB;CAEhB,MAAM,QAAuB;AAC3B,SAAO,KACL;GACE,eAAe,qBAAqB,OAAU,KAAK;GACnD,eAAe,uBAAuB,OAAU;GACjD,EACD,6BACD;AAGD,OAAK,KAAK;EAGV,MAAM,WAAW,gBAAgB;AACjC,MAAI,yBAAyB,YAAY,OAAO,SAAS,wBAAwB,WAC/E,UAAS,oBAAoB,qBAAqB,kBAAkB;;CAIxE,OAAa;EACX,MAAM,WAAW,gBAAgB;AACjC,MACE,2BAA2B,YAC3B,OAAO,SAAS,0BAA0B,WAE1C,UAAS,uBAAuB;AAElC,SAAO,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,4BAA4B;;CAG/D,MAAoB;AAClB,MAAI;GACF,MAAM,WAAW,gBAAgB;AACjC,OACE,0BAA0B,YAC1B,OAAO,SAAS,yBAAyB,YACzC;IACA,MAAM,UAAU,SAAS,qBAAqB,kBAAkB;AAChE,QAAI,UAAU,EACZ,QAAO,KAAK;KAAE,MAAM,KAAK;KAAM,cAAc;KAAS,EAAE,yBAAyB;;WAG9E,KAAK;AACZ,UAAO,MAAM;IAAE,MAAM,KAAK;IAAM;IAAK,EAAE,0BAA0B;;;;;;ACYvE,IAAa,UAAb,MAAqB;CACnB,cAA+B,IAAI,aAAa;CAChD,eAAgC,IAAI,cAAc;CAClD;CACA;CACA,kBAAmC,IAAI,uBAAuB;CAE9D,MAAM,aAA4B;AAChC,OAAK,uBAAuB,IAAI,sBAAsB;AACtD,OAAK,gBAAgB,IAAI,cAAc,KAAK,YAAY;AAGxD,QAAM,yBAAyB;AAG/B,QAAM,KAAK,YAAY,wBAAwB,wBAAwB,CAAC;AAGxE,OAAK,gBAAgB,SAAS,IAAI,yBAAyB,KAAK,YAAY,CAAC;AAC7E,OAAK,gBAAgB,SAAS,IAAI,iBAAiB,CAAC;AACpD,QAAM,KAAK,gBAAgB,UAAU;;CAOvC,oBAAoB,eAA+E;EACjG,MAAM,OAAO,eAAe,MAAM,MAAM,IAAI;AAC5C,SAAO;GACL,IAAI,eAAe,EAAE,YAAY,MAAM,CAAC;GACxC;GACA,SAAS,eAAe;GACxB,WAAW;GACX,MAAM;GACP;;CAOH,MAAM,UAAU,QAAmD;AAEjE,SAAO,CACL,IAFkB,MAAM,KAAK,gBAAgB,OAAO,EAErC,KAAK,SAAS;GAC3B,MAAM,OAAO,IAAI;GACjB,aAAa,KAAK,aAAa,oBAAoB,IAAI,OAAO,IAAI,WAAW;GAC7E,aAAa;IAAE,MAAM;IAAmB,YAAY,EAAE;IAAE;GACzD,EAAE,EACH,GAAG,6BAA6B,CAAC,KAAK,UAAU;GAC9C,MAAM,KAAK;GACX,aAAa,KAAK;GAClB,aAAa,KAAK,mBAAmB,KAAK;GAC3C,EAAE,CACJ;;CAGH,yBAAyB,MAAiD;AACxE,SAAO,yBAAyB,KAAK;;CAOvC,MAAM,eAAe,OAAe,QAAmD;EACrF,MAAM,SAAS,MAAM,KAAK,kBAAkB,OAAO,OAAO;AAC1D,MAAI,CAAC,OACH,OAAM,IAAI,SAAS,eAAe,kBAAkB,QAAQ;AAE9D,MAAI,cAAc,OAChB,OAAM,IAAI,SACR,eACA,QAAQ,MAAM,2FAA2F,MAAM,yEAChH;EAGH,MAAM,EAAE,eAAe,OAAO;EAC9B,MAAM,SAAS,WAAW;EAE1B,MAAM,eAAe,MADJ,KAAK,qBAAqB,YAAY,OAAO,SAAS,CACnC,oBAAoB,OAAO,OAAO,OAAc;AAEpF,SAAO,EACL,MAAM,KAAK,aAAa,iBAAiB,OAAO,YAAY,aAAa,EAC1E;;CAOH,uBAAuB,UAAqC;EAC1D,MAAM,OAAO,yBAAyB,SAAS;AAC/C,MAAI,CAAC,KACH,OAAM,IAAI,SAAS,gBAAgB,iBAAiB,WAAW;AAEjE,SAAO,EAAE,MAAM,yBAAyB,KAAK,EAAE;;CAOjD,MAAM,WACJ,WACA,YACA,UACA,MACA,QAC4B;AAC5B,MAAI,CAAC,cAAc,eAAe,WAAW;AAC3C,OAAI,uBAAuB,SAAS,CAClC,QAAO,KAAK,mBAAmB,UAAU,MAAM,OAAO;AAExD,SAAM,IAAI,SAAS,mBAAmB,wCAAwC;;EAGhF,MAAM,WAAW,MAAM,KAAK,WAAW,YAAY,OAAO;EAC1D,MAAM,YAAY,KAAK,KAAK;AAE5B,SAAO,KACL;GACE;GACA,KAAK,SAAS;GACd,UAAU,SAAS,WAAW,OAAO;GACrC,MAAM;GACN,MAAM,kBAAkB,KAAK;GAC9B,EACD,oBACD;AAED,MAAI;GACF,MAAM,SAAS,MAAM,KAAK,qBAAqB,6BAC7C,SAAS,OACT,SAAS,YACT,UACA,KACD;AACD,UAAO,KACL;IACE;IACA,KAAK,SAAS;IACd,UAAU,SAAS,WAAW,OAAO;IACrC,MAAM;IACN,YAAY,KAAK,KAAK,GAAG;IACzB,QAAQ,oBAAoB,OAAO;IACpC,EACD,qBACD;AACD,UAAO,KAAK,aAAa,OAAO;WACzB,KAAK;AACZ,UAAO,MACL;IACE;IACA,KAAK,SAAS;IACd,UAAU,SAAS,WAAW,OAAO;IACrC,MAAM;IACN,YAAY,KAAK,KAAK,GAAG;IACzB;IACD,EACD,kBACD;AACD,SAAM;;;CAQV,MAAM,gBACJ,SACA,SACA,QAC4B;AAC5B,MAAI;AACF,UAAO,KACL;IACE,MAAM;IACN,OAAO,QAAQ,WAAW,WAAW;IACrC,SAAS,0BAA0B,QAAQ;IAC5C,EACD,6BACD;AAED,OAAI,CAAC,QAAQ,UAAU;IACrB,MAAM,UAAU,MAAM,kBAAkB,gBAAgB,EAAE;KACxD,MAAM,QAAQ;KACd,QAAQ,QAAQ;KACjB,CAAC;AAEF,WAAO,KACL;KACE,MAAM;KACN,OAAO;KACP,OAAO,QAAQ;KACf,SAAS,QAAQ;KACjB,WAAW,QAAQ,MAAM;KAC1B,EACD,kCACD;AAED,WAAO,EACL,MAAM;KACJ;KACA,aAAa,QAAQ;KACrB;KACA;KACA,kBAAkB,QAAQ,MAAM;KAChC;KACA;KACA;KACA,yCAAyC,gBAAgB,cAAc;KACvE;KACA;KACD,CAAC,KAAK,KAAK,EACb;;GAGH,MAAM,SAAS,MAAM,KAAK,cAAc,UACtC;IACE,MAAM,QAAQ;IACd,QAAQ,QAAQ;IAChB,SAAS,QAAQ,SAAS;IAC1B,aAAa,QAAQ,SAAS;IAC/B,EACD,OACD;AAED,UAAO,KACL;IACE,MAAM;IACN,OAAO;IACP,OAAO,OAAO;IACd,gBAAgB,OAAO;IACvB,WAAW,OAAO,MAAM;IACzB,EACD,uBACD;GAED,MAAM,eAAe;IACnB,OAAO;IACP,OAAO,OAAO,MAAM,KAAK,OAAO;KAC9B,MAAM,EAAE;KACR,aAAa,EAAE,eAAe;KAC9B,aAAa,EAAE,eAAe;MAAE,MAAM;MAAmB,YAAY,EAAE;MAAE;KAC1E,EAAE;IACJ;AAED,UAAO,EACL,MAAM;IACJ,qBAAqB,OAAO,WAAW,IAAI,KAAK;IAChD,WAAW,OAAO;IAClB,wBAAwB,OAAO;IAC/B,eAAe,OAAO;IACtB,YAAY,OAAO,WAAW,SAAS;IACvC,wBAAwB,QAAQ,SAAS,gBAAgB,YAAY,yBAAyB;IAC9F;IACA,KAAK,aAAa,iBAAiB,OAAO,OAAO,OAAO,YAAY,aAAa;IAClF,CAAC,KAAK,KAAK,EACb;WACM,KAAK;AACZ,UAAO,MACL;IAAE,MAAM;IAAc,SAAS,uBAAuB,QAAQ;IAAE;IAAK,EACrE,oBACD;AAED,OAAI,sBAAsB,IAAI,CAC5B,QAAO,0BAA0B,IAAI;AAGvC,UAAO,kBAAkB,sBAAsB,IAAI;;;CAQvD,MAAM,kBACJ,SACA,SACA,QAC4B;AAC5B,MAAI;AACF,UAAO,KACL;IACE,MAAM;IACN,OAAO;IACP,SAAS,4BAA4B,QAAQ;IAC9C,EACD,+BACD;GAED,MAAM,SAAS,MAAM,KAAK,cAAc,YAAY,EAAE,MAAM,QAAQ,MAAM,EAAE,OAAO;AAEnF,UAAO,KACL;IACE,MAAM;IACN,OAAO;IACP,OAAO,OAAO;IACd,aAAa,OAAO;IACrB,EACD,yBACD;GAED,MAAM,WAAW,KAAK,qBAAqB,YAAY,OAAO,WAAW,OAAO,SAAS;GACzF,IAAI;AACJ,OAAI;AACF,mBAAe,MAAM,SAAS,oBAC5B,OAAO,OACP,OAAO,WAAW,OAAO,OAC1B;WACK;AACN,mBAAe;KACb,OAAO;KACP,OAAO,CACL;MACE,MAAM;MACN,aAAa;MACb,aAAa;OAAE,MAAM;OAAmB,YAAY,EAAE;OAAE;MACzD,CACF;KACF;;AAGH,UAAO,EACL,MAAM;IACJ,mBAAmB,OAAO,WAAW,IAAI,KAAK;IAC9C,WAAW,OAAO;IAClB,wBAAwB,OAAO;IAC/B,oBAAoB,OAAO;IAC3B,YAAY,OAAO,WAAW,SAAS;IACvC;IACA;IACA,KAAK,aAAa,iBAAiB,OAAO,OAAO,OAAO,YAAY,aAAa;IAClF,CAAC,KAAK,KAAK,EACb;WACM,KAAK;AACZ,UAAO,MACL;IAAE,MAAM;IAAgB,SAAS,uBAAuB,QAAQ;IAAE;IAAK,EACvE,sBACD;AACD,UAAO,kBAAkB,wBAAwB,IAAI;;;CAQzD,qBAAqB,MAA8D;AACjF,MAAI;AACF,gCAA6B,KAAK;AAClC,UAAO,EAAE,MAAM,6BAA6B,EAAE;WACvC,KAAK;AACZ,SAAM,IAAI,SAAS,mBAAmB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;;;CAQ3F,MAAM,kBAAkB,QAAmD;EAEzE,MAAM,UAAU,EACd,OAFW,MAAM,KAAK,mBAAmB,OAAO,EAErC,KAAK,EAAE,KAAK,eAAe;GACpC,KAAK,IAAI;GACT,MAAM,IAAI,WAAW,IAAI,KAAK;GAC9B,SAAS,IAAI,WAAW,SAAS;GACjC,QAAQ,IAAI;GACZ;GACA,WAAW,IAAI,WAAW,gBAAgB,IAAI,WAAW;GAC1D,EAAE,EACJ;AAED,SAAO;GACL,MAAM,KAAK,UAAU,SAAS,MAAM,EAAE;GACtC,mBAAmB;GACpB;;CAGH,MAAM,iBACJ,MACA,QAC4B;EAC5B,MAAM,QAAQ,OAAO,MAAM,QAAQ,WAAW,KAAK,IAAI,MAAM,GAAG;AAChE,MAAI,CAAC,MACH,OAAM,IAAI,SAAS,mBAAmB,4BAA4B;AAGpE,QAAM,KAAK,qBAAqB,MAAM;AACtC,QAAM,mBAAmB,OAAO,IAAI,MAAM;EAE1C,MAAM,UAAU;GAAE,KAAK;GAAO,aAAa,OAAO;GAAI;AACtD,SAAO;GACL,MAAM,KAAK,UAAU,SAAS,MAAM,EAAE;GACtC,mBAAmB;GACpB;;CAGH,MAAM,gBACJ,MACA,QAC4B;EAC5B,MAAM,QAAQ,OAAO,MAAM,QAAQ,WAAW,KAAK,IAAI,MAAM,GAAG;AAChE,MAAI,CAAC,MACH,OAAM,IAAI,SAAS,mBAAmB,2BAA2B;AAGnE,QAAM,KAAK,qBAAqB,MAAM;AACtC,QAAM,kBAAkB,OAAO,IAAI,MAAM;EAEzC,MAAM,UAAU;GAAE,KAAK;GAAO,YAAY,OAAO;GAAI;AACrD,SAAO;GACL,MAAM,KAAK,UAAU,SAAS,MAAM,EAAE;GACtC,mBAAmB;GACpB;;CAGH,MAAM,gBACJ,MACA,SAC4B;EAC5B,MAAM,QAAQ,OAAO,MAAM,QAAQ,WAAW,KAAK,IAAI,MAAM,GAAG;AAChE,MAAI,CAAC,MACH,OAAM,IAAI,SAAS,mBAAmB,2BAA2B;AAGnE,MAAI,MAAM,YAAY,KACpB,OAAM,IAAI,SACR,mBACA,kHACD;EAGH,MAAM,MAAM,MAAM,KAAK,qBAAqB,MAAM;AAClD,MAAI,IAAI,WAAW,gBAAgB,IAAI,WAAW,eAChD,OAAM,IAAI,SACR,mBACA,yDAAyD,MAAM,UAAU,IAAI,OAAO,QACrF;AAGH,QAAM,KAAK,cAAc,UAAU,MAAM;EAEzC,MAAM,UAAU;GAAE,KAAK;GAAO,aAAa;GAAc;AACzD,SAAO;GACL,MAAM,KAAK,UAAU,SAAS,MAAM,EAAE;GACtC,mBAAmB;GACpB;;CAOH,IAAI,eAAwB;AAE1B,SAAO;;CAOT,MAAc,mBACZ,UACA,MACA,QAC4B;AAC5B,MAAI,aAAA,kBACF,QAAO,KAAK,qBAAqB,KAAK;AAExC,MAAI,aAAa,iBACf,QAAO,KAAK,kBAAkB,OAAO;AAEvC,MAAI,aAAa,aACf,QAAO,KAAK,iBAAiB,MAAM,OAAO;AAE5C,MAAI,aAAa,YACf,QAAO,KAAK,gBAAgB,MAAM,OAAO;AAE3C,MAAI,aAAa,YACf,QAAO,KAAK,gBAAgB,MAAM,OAAO;AAE3C,QAAM,IAAI,SAAS,gBAAgB,iBAAiB,WAAW;;CAOjE,MAAc,kBACZ,OACA,QACoF;EACpF,MAAM,WAAW,KAAK,YAAY,IAAI,MAAM;AAC5C,MAAI,CAAC,SAAU,QAAO,KAAA;AAEtB,MAAI,MAAM,KAAK,sBAAsB,UAAU,OAAO,CACpD,QAAO,EAAE,KAAK,UAAU;AAE1B,SAAO;GAAE,UAAU;GAAM;GAAO;;CAGlC,MAAc,qBAAqB,OAA0C;EAC3E,MAAM,WAAW,KAAK,YAAY,IAAI,MAAM;AAC5C,MAAI,CAAC,SACH,OAAM,IAAI,SAAS,eAAe,kBAAkB,QAAQ;AAE9D,SAAO;;CAGT,MAAc,WAAW,YAAoB,QAAkD;EAC7F,MAAM,SAAS,MAAM,KAAK,kBAAkB,YAAY,OAAO;AAC/D,MAAI,UAAU,SAAS,OAAQ,QAAO,OAAO;AAC7C,MAAI,UAAU,cAAc,OAC1B,OAAM,IAAI,SACR,eACA,QAAQ,WAAW,2FAA2F,WAAW,yEAC1H;AAEH,QAAM,IAAI,SAAS,eAAe,kBAAkB,aAAa;;CAOnE,MAAc,gBAAgB,QAAoD;EAChF,MAAM,OAAO,MAAM,KAAK,KAAK,YAAY,QAAQ,CAAC;AAIlD,UAHoB,MAAM,QAAQ,IAChC,KAAK,IAAI,OAAO,QAAU,MAAM,KAAK,sBAAsB,KAAK,OAAO,GAAI,MAAM,KAAM,CACxF,EACkB,QAAQ,QAAiC,QAAQ,KAAK;;CAG3E,MAAc,mBAAmB,QAE/B;EACA,MAAM,OAAO,MAAM,KAAK,KAAK,YAAY,QAAQ,CAAC;AAClD,SAAO,QAAQ,IACb,KAAK,IAAI,OAAO,SAAS;GACvB;GACA,SAAS,MAAM,KAAK,sBAAsB,KAAK,OAAO;GACvD,EAAE,CACJ;;CAGH,MAAc,sBACZ,KACA,QACkB;EAOlB,MAAM,YANa,MAAM,iBAAiB;GACxC,SAAS,OAAO;GAChB,YAAY,OAAO;GACnB,WAAW,OAAO;GACnB,CAAC,EAE0B,aAAa,IAAI;AAC7C,MAAI,aAAa,UAAW,QAAO;AACnC,MAAI,aAAa,WAAY,QAAO;EAEpC,MAAM,SAAS,MAAM,mBAAmB,IAAI,MAAM;AAClD,MAAI,CAAC,UAAU,OAAO,mBAAmB,MAAO,QAAO;AAEvD,SAAO,OAAO,oBAAoB,OAAO;;CAO3C,aAAqB,QAAoC;AACvD,MAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,OAAO,CAChE,QAAO;GACL,MAAM,KAAK,UAAU,QAAQ,MAAM,EAAE;GACrC,mBAAmB;GACpB;AAEH,SAAO,EACL,MAAM,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,QAAQ,MAAM,EAAE,EAC5E;;;AAQL,SAAS,kBAAkB,OAA8D;AACvF,KAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAO,MAAM,KAAK,SAAS,KAAK,KAAK,KAAK,IAAI,KAAK,eAAe,KAAK,SAAS,CAAC,CAAC,KAAK,KAAK;;AAG9F,SAAgB,kBAAkB,SAAiB,KAAiC;CAClF,MAAM,UAAoB,CAAC,QAAQ;AAEnC,KAAI,eAAe,UAAU;AAC3B,UAAQ,KAAK,UAAU,IAAI,UAAU;AACrC,MAAI,IAAI,QAAQ,OAAO,KAAK,IAAI,KAAK,CAAC,SAAS,EAC7C,SAAQ,KAAK,IAAI,YAAY,KAAK,UAAU,IAAI,MAAM,MAAM,EAAE,CAAC;YAExD,eAAe,MACxB,SAAQ,KAAK,UAAU,IAAI,UAAU;KAErC,SAAQ,KAAK,UAAU,OAAO,IAAI,GAAG;AAGvC,QAAO;EAAE,MAAM,QAAQ,KAAK,KAAK;EAAE,SAAS;EAAM;;AAGpD,SAAS,sBAAsB,KAAuB;AACpD,KAAI,eAAe;MACJ,IAAI,MACP,SAAS,mBAAoB,QAAO;;AAEhD,KAAI,eAAe,SAAS,iCAAiC,KAAK,IAAI,QAAQ,CAAE,QAAO;AACvF,QAAO;;AAGT,SAAS,uBAAuB,KAAwB;AACtD,KAAI,eAAe,UAAU;EAC3B,MAAM,OAAO,IAAI;AACjB,MAAI,MAAM,QAAQ,MAAM,YAAY,CAAE,QAAO,KAAK;;AAEpD,KAAI,eAAe,OAAO;EACxB,MAAM,UAAU,IAAI,QAAQ,MAAM,iBAAiB;AACnD,MAAI,QAAS,QAAO,QAAQ,KAAK,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC;;AAExD,QAAO,EAAE;;AAGX,SAAS,0BAA0B,KAAiC;CAClE,MAAM,UAAU,eAAe;CAC/B,MAAM,cAAc,uBAAuB,IAAI;CAC/C,MAAM,UAAU,YAAY,SAAS,IAAI,cAAc,CAAC,kBAAkB;AAkC1E,QAAO;EAAE,MAhCe;GACtB;GACA;GACA;GACA;GACA,iEAAiE,QAAQ,KAAK,MAAM,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK;GAC1G;GACA;GACA;GACA,GAAG,QAAQ,KACR,MACC,OAAO,EAAE,2GACZ;GACD;GACA;GACA;GACA;GACA;GACA,QAAQ;GACR;GACA;GACA;GACA,GAAG,QAAQ,KAAK,MAAM,GAAG,EAAE,qBAAqB;GAChD;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAEoB,KAAK,KAAK;EAAE,SAAS;EAAM;;;;;;;;;;AC/sBlD,IAAa,mBAAb,MAA8B;CAC5B;CACA,UAA2B,IAAI,SAAS;CACxC;CAEA,cAAc;AACZ,OAAK,SAAS,IAAI,OAChB;GAAE,MAAM;GAAkB,SAAS;GAAqB,EACxD,EACE,cAAc;GACZ,OAAO,EAAE,aAAa,MAAM;GAC5B,SAAS,EAAE;GACZ,EACF,CACF;AACD,OAAK,eAAe;;CAGtB,MAAM,aAA4B;AAChC,QAAM,KAAK,QAAQ,YAAY;;CAGjC,MAAM,QAAuB;AAC3B,QAAM,KAAK,YAAY;EACvB,MAAM,YAAY,IAAI,sBAAsB;AAC5C,QAAM,KAAK,OAAO,QAAQ,UAAU;AACpC,SAAO,KAAK,8BAA8B;;CAO5C,gBAA8B;AAC5B,OAAK,OAAO,sBAAsB;GAChC,MAAM,gBAAgB,KAAK,OAAO,kBAAkB;AACpD,QAAK,gBAAgB,KAAK,QAAQ,oBAAoB,cAAc;;AAGtE,OAAK,OAAO,kBAAkB,wBAAwB,YAAY;AAEhE,UAAO,EAAE,OADK,MAAM,KAAK,QAAQ,UAAU,KAAK,eAAe,CAAC,EAChD;IAChB;AAEF,OAAK,OAAO,kBAAkB,uBAAuB,OAAO,SAAS,UAAU;GAC7E,MAAM,EAAE,MAAM,WAAW,YAAY,QAAQ;GAC7C,MAAM,SAAS,KAAK,eAAe;GAGnC,MAAM,UAAU,KAAK,QAAQ,yBAAyB,KAAK;GAC3D,MAAM,OAAO,UACR,6BAA6B,SAAS,QAAQ,YAAY,GAG3D;AAGJ,OAAI,KAAK,WAAW,OAAO,CACzB,QAAO,KAAK,iBACV,MAAM,KAAK,QAAQ,eAAe,KAAK,MAAM,EAAE,EAAE,OAAO,CACzD;AAIH,OAAI,SAAS,YAAY;IACvB,MAAM,UAAU;AAChB,WAAO,KAAK,iBACV,MAAM,KAAK,QAAQ,WACjB,MAAM,WACN,QAAQ,KACR,QAAQ,MACR,QAAQ,QAAQ,EAAE,EAClB,OACD,CACF;;AAIH,OAAI,SAAS,cAAc;IACzB,MAAM,SAAS;AACf,QAAI,CAAC,UAAU,OAAO,KAAK,OAAO,CAAC,WAAW,EAC5C,QAAO,KAAK,iBAAiB,KAAK,QAAQ,uBAAuB,KAAK,CAAC;IAEzE,MAAM,SAAS,wBAAwB,OAAO;IAC9C,MAAM,SAAS,MAAM,KAAK,QAAQ,gBAAgB,QAAQ,QAAQ,OAAO;AACzE,QAAI,CAAC,OAAO,QAAS,OAAM,KAAK,wBAAwB;AACxD,WAAO,KAAK,iBAAiB,OAAO;;AAItC,OAAI,SAAS,gBAAgB;IAC3B,MAAM,SAAS;AACf,QAAI,CAAC,UAAU,OAAO,KAAK,OAAO,CAAC,WAAW,EAC5C,QAAO,KAAK,iBAAiB,KAAK,QAAQ,uBAAuB,KAAK,CAAC;IAEzE,MAAM,SAAS,0BAA0B,OAAO;IAChD,MAAM,SAAS,MAAM,KAAK,QAAQ,kBAAkB,QAAQ,QAAQ,OAAO;AAC3E,QAAI,CAAC,OAAO,QAAS,OAAM,KAAK,wBAAwB;AACxD,WAAO,KAAK,iBAAiB,OAAO;;AAItC,OACE,SAAS,qBACT,SAAS,oBACT,SAAS,gBACT,SAAS,eACT,SAAS,aACT;IACA,MAAM,WAAY,QAAgD,EAAE;IACpE,IAAI;AAEJ,YAAQ,MAAR;KACE,KAAK;AACH,eAAS,KAAK,QAAQ,qBAAqB,SAAS;AACpD;KACF,KAAK;AACH,eAAS,MAAM,KAAK,QAAQ,kBAAkB,OAAO;AACrD;KACF,KAAK;AACH,eAAS,MAAM,KAAK,QAAQ,iBAAiB,UAAU,OAAO;AAC9D,YAAM,KAAK,wBAAwB;AACnC;KACF,KAAK;AACH,eAAS,MAAM,KAAK,QAAQ,gBAAgB,UAAU,OAAO;AAC7D,YAAM,KAAK,wBAAwB;AACnC;KACF,KAAK;AACH,eAAS,MAAM,KAAK,QAAQ,gBAAgB,UAAU,OAAO;AAC7D,YAAM,KAAK,wBAAwB;AACnC;KACF,QACE,OAAM,IAAI,SAAS,gBAAgB,iBAAiB,OAAO;;AAG/D,WAAO,KAAK,iBAAiB,OAAO;;AAGtC,SAAM,IAAI,SAAS,gBAAgB,iBAAiB,OAAO;IAC3D;;CAOJ,gBAAuC;AACrC,MAAI,KAAK,cAAe,QAAO,KAAK;AACpC,SAAO;GACL,IAAI;GACJ,MAAM;GACN,WAAW;GACX,MAAM;GACP;;CAGH,MAAc,yBAAwC;AACpD,MAAI;AACF,SAAM,KAAK,OAAO,qBAAqB;AACvC,UAAO,MAAM,sCAAsC;WAC5C,OAAO;AACd,UAAO,MAAM,EAAE,KAAK,OAAO,EAAE,gDAAgD;;;CAIjF,iBAAyB,QAA2C;AAClE,SAAO;GACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,OAAO;IAAM,CAAC;GAC9C,GAAI,OAAO,UAAU,EAAE,SAAS,MAAM,GAAG,EAAE;GAC3C,GAAI,OAAO,oBAAoB,EAAE,mBAAmB,OAAO,mBAAmB,GAAG,EAAE;GACpF;;;AAIL,eAAsB,sBAAiD;AACrE,QAAO,IAAI,kBAAkB"}
|
|
1
|
+
{"version":3,"file":"server-DmOAeOMT.js","names":[],"sources":["../src/utils/dotenv.ts","../src/storage/skill-registry.ts","../src/utils/ids.ts","../src/core/importer.ts","../src/executors/mcp.ts","../src/discovery/checks.ts","../src/storage/managed-registry.ts","../src/storage/agent-state.ts","../src/core/search-guidance.ts","../src/core/parsers.ts","../src/core/tool-definitions.ts","../src/core/app-registry.ts","../src/types/aai-json.ts","../src/executors/skill.ts","../src/core/execution-coordinator.ts","../src/utils/locale.ts","../src/guides/app-guide-generator.ts","../src/core/guide-service.ts","../src/core/import-service.ts","../src/discovery/descriptors/claude-code-agent.ts","../src/discovery/descriptors/codex-agent.ts","../src/discovery/descriptors/opencode-agent.ts","../src/core/seed.ts","../src/core/background/task-manager.ts","../src/core/background/acp-prewarm-task.ts","../src/core/background/turn-cleanup.ts","../src/core/gateway.ts","../src/mcp/server.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\n\nimport { getAaiHomeDir } from './config.js';\n\nexport interface DotenvResult {\n env: Record<string, string>;\n missing: string[];\n}\n\nexport interface SubstitutionResult<T> {\n result: T;\n missing: string[];\n}\n\nexport function getDotenvPath(): string {\n return `${getAaiHomeDir()}/.env`;\n}\n\n/**\n * Load environment variables from ~/.aai-gateway/.env file\n */\nexport async function loadDotenv(): Promise<DotenvResult> {\n const dotenvPath = getDotenvPath();\n\n try {\n const content = await readFile(dotenvPath, 'utf-8');\n const env: Record<string, string> = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n // Skip empty lines and comments\n if (!trimmed || trimmed.startsWith('#')) {\n continue;\n }\n\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) {\n continue;\n }\n\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n\n // Remove surrounding quotes if present\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n\n if (key) {\n env[key] = value;\n }\n }\n\n return { env, missing: [] };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { env: {}, missing: [] };\n }\n throw error;\n }\n}\n\n/**\n * Substitute ${VAR_NAME} placeholders in a string with values from env\n */\nexport function substituteEnvVars(str: string, env: Record<string, string>): string {\n return str.replace(/\\$\\{([^}]+)\\}/g, (_match, varName) => {\n const value = env[varName];\n if (value === undefined) {\n throw new Error(\n `Environment variable \\${${varName}} is not defined in ~/.aai-gateway/.env`\n );\n }\n return value;\n });\n}\n\n/**\n * Find all ${VAR_NAME} placeholders in a string\n */\nexport function findEnvPlaceholders(str: string): string[] {\n const matches: string[] = [];\n const regex = /\\$\\{([^}]+)\\}/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(str)) !== null) {\n matches.push(match[1]);\n }\n return matches;\n}\n\nexport function hasEnvPlaceholders(str: string): boolean {\n return findEnvPlaceholders(str).length > 0;\n}\n\n/**\n * Check if a string value has missing environment variables\n */\nfunction checkMissingVars(value: string, env: Record<string, string>): string[] {\n const placeholders = findEnvPlaceholders(value);\n return placeholders.filter((varName) => env[varName] === undefined);\n}\n\n/**\n * Substitute ${VAR_NAME} placeholders in a config object\n * Returns the substituted config and list of missing variables\n */\nexport function substituteConfigEnvVars(\n config: Record<string, unknown>,\n env: Record<string, string>\n): SubstitutionResult<Record<string, unknown>> {\n const missing: string[] = [];\n const result: Record<string, unknown> = {};\n\n for (const key of Object.keys(config)) {\n const value = config[key];\n if (typeof value === 'string') {\n const missingInValue = checkMissingVars(value, env);\n missing.push(...missingInValue);\n // Don't substitute if there are missing vars - let the caller handle the error\n result[key] = missingInValue.length > 0 ? value : substituteEnvVars(value, env);\n } else if (Array.isArray(value)) {\n // Handle arrays\n const newArray: unknown[] = [];\n for (const item of value) {\n if (typeof item === 'string') {\n const missingInItem = checkMissingVars(item, env);\n missing.push(...missingInItem);\n newArray.push(missingInItem.length > 0 ? item : substituteEnvVars(item, env));\n } else if (typeof item === 'object' && item !== null) {\n // Recursively handle nested objects in arrays\n const { result: subResult, missing: subMissing } = substituteConfigEnvVars(\n item as Record<string, unknown>,\n env\n );\n missing.push(...subMissing);\n newArray.push(subResult);\n } else {\n newArray.push(item);\n }\n }\n result[key] = newArray;\n } else if (typeof value === 'object' && value !== null) {\n // Recursively handle nested objects\n const { result: subResult, missing: subMissing } = substituteConfigEnvVars(\n value as Record<string, unknown>,\n env\n );\n missing.push(...subMissing);\n result[key] = subResult;\n } else {\n result[key] = value;\n }\n }\n\n return { result, missing };\n}\n\nexport function substituteStringRecordEnvVars(\n values: Record<string, string> | undefined,\n env: Record<string, string>\n): SubstitutionResult<Record<string, string>> {\n if (!values) {\n return { result: {}, missing: [] };\n }\n\n const missing: string[] = [];\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(values)) {\n const missingInValue = checkMissingVars(value, env);\n missing.push(...missingInValue);\n result[key] = missingInValue.length > 0 ? value : substituteEnvVars(value, env);\n }\n\n return { result, missing };\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { parseAaiJson } from '../parsers/schema.js';\nimport type { AaiJson, SkillConfig } from '../types/aai-json.js';\n\nimport { getManagedAppDir, getManagedAppsRoot } from './paths.js';\nimport { FileRegistry } from './registry.js';\n\nconst REGISTRY_FILE = 'skill-registry.json';\n\nexport interface SkillRegistryEntry {\n id: string;\n appId: string;\n protocol: 'skill';\n config: SkillConfig;\n exposureMode?: 'summary' | 'keywords';\n descriptorPath: string;\n importedAt: string;\n updatedAt: string;\n}\n\n/**\n * Skill Registry\n *\n * Manages imported skill registrations using the unified FileRegistry.\n */\nexport class SkillRegistry {\n private registry: FileRegistry<SkillRegistryEntry>;\n\n constructor() {\n const registryPath = join(getManagedAppsRoot(), REGISTRY_FILE);\n this.registry = new FileRegistry<SkillRegistryEntry>(\n registryPath,\n (entry) => ({\n id: entry.id,\n appId: entry.appId,\n protocol: entry.protocol,\n config: entry.config,\n exposureMode: entry.exposureMode,\n descriptorPath: entry.descriptorPath,\n importedAt: entry.importedAt,\n updatedAt: entry.updatedAt,\n }),\n (raw) => raw as unknown as SkillRegistryEntry\n );\n }\n\n /**\n * List all skill registry entries\n */\n async list(): Promise<SkillRegistryEntry[]> {\n return this.registry.list();\n }\n\n /**\n * Get a specific skill registry entry by ID\n */\n async get(id: string): Promise<SkillRegistryEntry | null> {\n return this.registry.get(id);\n }\n\n /**\n * Add or update a skill registry entry\n */\n async upsert(\n entry: Omit<SkillRegistryEntry, 'id' | 'descriptorPath' | 'importedAt' | 'updatedAt'>,\n descriptor: AaiJson\n ): Promise<SkillRegistryEntry> {\n const existing = await this.get(entry.appId);\n const now = new Date().toISOString();\n const appDir = getManagedAppDir(entry.appId);\n const descriptorPath = join(appDir, 'aai.json');\n\n await mkdir(appDir, { recursive: true });\n await writeFile(descriptorPath, JSON.stringify(descriptor, null, 2), 'utf-8');\n\n const nextEntry: SkillRegistryEntry = {\n id: entry.appId,\n ...entry,\n descriptorPath,\n importedAt: existing?.importedAt ?? now,\n updatedAt: now,\n };\n\n return this.registry.upsert(nextEntry);\n }\n\n /**\n * Delete a skill registry entry\n */\n async delete(id: string): Promise<boolean> {\n return this.registry.delete(id);\n }\n\n /**\n * Load imported skill apps with their descriptors\n */\n async loadApps(): Promise<Array<{ entry: SkillRegistryEntry; descriptor: AaiJson }>> {\n const entries = await this.list();\n const loaded: Array<{ entry: SkillRegistryEntry; descriptor: AaiJson }> = [];\n\n for (const entry of entries) {\n try {\n const raw = await readFile(entry.descriptorPath, 'utf-8');\n loaded.push({\n entry,\n descriptor: parseAaiJson(JSON.parse(raw)),\n });\n } catch (err) {\n // Skip entries with missing or invalid descriptors\n }\n }\n\n return loaded;\n }\n}\n\nlet skillRegistryInstance: SkillRegistry | null = null;\n\nexport function getSkillRegistry(): SkillRegistry {\n if (!skillRegistryInstance) {\n skillRegistryInstance = new SkillRegistry();\n }\n return skillRegistryInstance;\n}\n\n// Backward compatibility exports\nexport async function listSkillRegistryEntries(): Promise<SkillRegistryEntry[]> {\n return getSkillRegistry().list();\n}\n\nexport async function getSkillRegistryEntry(appId: string): Promise<SkillRegistryEntry | null> {\n return getSkillRegistry().get(appId);\n}\n\nexport async function upsertSkillRegistryEntry(\n entry: Omit<SkillRegistryEntry, 'id' | 'descriptorPath' | 'importedAt' | 'updatedAt'>,\n descriptor: AaiJson\n): Promise<SkillRegistryEntry> {\n return getSkillRegistry().upsert(entry, descriptor);\n}\n\nexport async function loadImportedSkillApps(): Promise<Array<{ entry: SkillRegistryEntry; descriptor: AaiJson }>> {\n return getSkillRegistry().loadApps();\n}\n","import { createHash } from 'node:crypto';\n\nexport function slugify(value: string): string {\n const normalized = value\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n return normalized || 'app';\n}\n\nexport function deriveAppId(seed: string, fallback = 'app'): string {\n const hash = createHash('sha1').update(seed).digest('hex').slice(0, 8);\n return `${fallback}-${hash}`;\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\n\nimport type { McpExecutor, McpListedTool } from '../executors/mcp.js';\nimport {\n getMcpRegistryEntry,\n upsertMcpRegistryEntry,\n type McpRegistryEntry,\n} from '../storage/mcp-registry.js';\nimport { getManagedAppDir } from '../storage/paths.js';\nimport { getSkillRegistryEntry, upsertSkillRegistryEntry } from '../storage/skill-registry.js';\nimport type { AaiJson, McpConfig } from '../types/aai-json.js';\nimport { deriveAppId, slugify } from '../utils/ids.js';\nimport {\n getDotenvPath,\n hasEnvPlaceholders,\n loadDotenv,\n substituteConfigEnvVars,\n} from '../utils/dotenv.js';\n\nexport const IMPORT_LIMITS = {\n nameLength: 128,\n commandLength: 256,\n urlLength: 2048,\n pathLength: 2048,\n timeoutMsMax: 2_147_483_647,\n cwdLength: 2048,\n argCount: 64,\n argLength: 1024,\n envCount: 32,\n envKeyLength: 128,\n envValueLength: 2048,\n} as const;\n\nexport const EXPOSURE_LIMITS = {\n summaryLength: 200,\n} as const;\n\nexport interface SummaryDraft {\n summary: string;\n}\n\nexport interface McpImportConfigInput {\n transport?: 'streamable-http' | 'sse';\n url?: string;\n command?: string;\n timeout?: number;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n headers?: Record<string, string>;\n}\n\nexport interface McpImportPreviewOptions {\n config: McpConfig;\n name?: string;\n}\n\nexport interface McpImportOptions extends McpImportPreviewOptions {\n summary: string;\n}\n\nexport interface McpImportPreview {\n appId: string;\n name: string;\n tools: McpListedTool[];\n}\n\nexport interface McpImportedResult {\n entry: McpRegistryEntry;\n descriptor: AaiJson;\n tools: McpListedTool[];\n warnings?: string[];\n}\n\nexport interface SkillImportSourceInput {\n path?: string;\n}\n\nexport interface SkillImportPreviewOptions extends SkillImportSourceInput {}\n\nexport interface SkillImportOptions extends SkillImportSourceInput {}\n\nexport interface SkillImportPreview {\n appId: string;\n name: string;\n description?: string;\n content: string;\n}\n\ninterface SkillFrontMatter {\n name?: string;\n description?: string;\n body: string;\n}\n\nexport function buildMcpImportConfig(input: McpImportConfigInput): McpConfig {\n validateOptionalStringLength(input.command, 'command', IMPORT_LIMITS.commandLength);\n validateOptionalStringLength(input.url, 'url', IMPORT_LIMITS.urlLength);\n validateOptionalStringLength(input.cwd, 'cwd', IMPORT_LIMITS.cwdLength);\n validateOptionalTimeoutMs(input.timeout, 'timeout', IMPORT_LIMITS.timeoutMsMax);\n validateStringArrayLength(input.args, 'args', IMPORT_LIMITS.argCount, IMPORT_LIMITS.argLength);\n validateStringRecordLength(\n input.env,\n 'env',\n IMPORT_LIMITS.envCount,\n IMPORT_LIMITS.envKeyLength,\n IMPORT_LIMITS.envValueLength\n );\n\n const command = input.command && input.command.length > 0 ? input.command : undefined;\n const url = input.url && input.url.length > 0 ? input.url : undefined;\n\n if (command && url) {\n throw new Error('MCP import accepts either command or url, but not both');\n }\n\n if (command) {\n if (input.transport) {\n throw new Error('Local stdio MCP import does not accept transport');\n }\n\n return {\n transport: 'stdio',\n command,\n ...(input.timeout !== undefined ? { timeout: input.timeout } : {}),\n ...(input.args && input.args.length > 0 ? { args: input.args } : {}),\n ...(input.env && Object.keys(input.env).length > 0 ? { env: input.env } : {}),\n ...(input.cwd ? { cwd: input.cwd } : {}),\n };\n }\n\n if (url) {\n return {\n transport: input.transport ?? 'streamable-http',\n url,\n ...(input.timeout !== undefined ? { timeout: input.timeout } : {}),\n ...(input.headers && Object.keys(input.headers).length > 0 ? { headers: input.headers } : {}),\n };\n }\n\n throw new Error('MCP import requires either command or url');\n}\n\nexport function buildSkillImportSource(input: SkillImportSourceInput): SkillImportSourceInput {\n validateOptionalStringLength(input.path, 'path', IMPORT_LIMITS.pathLength);\n\n const path = input.path && input.path.length > 0 ? input.path : undefined;\n\n if (!path) {\n throw new Error('Skill import requires a local path');\n }\n\n return { path };\n}\n\nexport function normalizeSummaryInput(summaryInput: string): SummaryDraft {\n const summary = summaryInput.trim();\n\n if (summary.length === 0) {\n throw new Error('summary cannot be empty.');\n }\n\n if (summary.length > EXPOSURE_LIMITS.summaryLength) {\n throw new Error(\n `summary is too long. Maximum length is ${EXPOSURE_LIMITS.summaryLength} characters.`\n );\n }\n\n return { summary };\n}\n\nexport async function discoverMcpImport(\n executor: McpExecutor,\n options: McpImportPreviewOptions\n): Promise<McpImportPreview> {\n const requestedName = normalizeImportedAppName(options.name);\n const appId = await deriveUniqueMcpAppId(options.config, requestedName);\n const tools = await executor.listTools({\n appId,\n config: options.config,\n });\n const name =\n requestedName ?? (await deriveImportName(executor, options.config, appId));\n return { appId, name, tools };\n}\n\nexport async function importMcpServer(\n executor: McpExecutor,\n options: McpImportOptions\n): Promise<McpImportedResult> {\n const warnings = buildSensitiveValueWarnings(options);\n const { resolvedConfig, missingVars } = await resolveImportedMcpRuntimeValues(options.config);\n\n if (missingVars.length > 0) {\n const uniqueMissing = [...new Set(missingVars)];\n throw new Error(\n `Missing environment variables in ${getDotenvPath()}: ${uniqueMissing\n .map((v) => `$\\{${v}}`)\n .join(', ')}.`\n );\n }\n\n const preview = await discoverMcpImport(executor, {\n ...options,\n config: resolvedConfig,\n });\n const descriptor = buildImportedMcpDescriptor(\n preview.name,\n options.config,\n normalizeSummaryInput(options.summary)\n );\n\n const entry = await upsertMcpRegistryEntry(\n {\n appId: preview.appId,\n protocol: 'mcp',\n config: options.config,\n },\n descriptor\n );\n\n return { entry, descriptor, tools: preview.tools, ...(warnings.length > 0 ? { warnings } : {}) };\n}\n\nexport async function discoverSkillImport(\n options: SkillImportPreviewOptions\n): Promise<SkillImportPreview> {\n const source = buildSkillImportSource(options);\n const content = await readSkillSourceContent(source);\n const appId = await deriveUniqueSkillAppId(source, content);\n const frontMatter = parseSkillFrontMatter(content);\n return {\n appId,\n name: deriveSkillName(source, content),\n description: frontMatter.description,\n content,\n };\n}\n\nexport async function importSkill(\n options: SkillImportOptions\n): Promise<{ appId: string; descriptor: AaiJson; managedPath: string }> {\n // Load environment variables from ~/.aai-gateway/.env\n const { env: dotenv, missing: missingInEnv } = await loadDotenv();\n\n // Substitute ${VAR_NAME} placeholders in path with values from .env\n let finalOptions = options;\n let missingVars: string[] = [...missingInEnv];\n\n if (Object.keys(dotenv).length > 0) {\n const pathOrUrl = options.path;\n if (pathOrUrl) {\n const { result: substituted, missing } = substituteConfigEnvVars(\n { source: pathOrUrl } as Record<string, unknown>,\n dotenv\n );\n const substitutedSource = substituted.source as string;\n missingVars = [...missingVars, ...missing];\n finalOptions = { ...options, path: substitutedSource };\n }\n }\n\n if (missingVars.length > 0) {\n const uniqueMissing = [...new Set(missingVars)];\n throw new Error(\n `Missing environment variables in ${getDotenvPath()}: ${uniqueMissing\n .map((v) => `$\\{${v}}`)\n .join(', ')}.`\n );\n }\n\n const preview = await discoverSkillImport(finalOptions);\n const source = buildSkillImportSource(finalOptions);\n const finalAppDir = getManagedAppDir(preview.appId);\n const finalManagedSkillDir = join(finalAppDir, 'skill');\n await mkdir(finalAppDir, { recursive: true });\n\n await copyDirectory(source.path!, finalManagedSkillDir);\n\n const descriptor: AaiJson = {\n schemaVersion: '2.0',\n version: '1.0.0',\n app: {\n name: {\n default: preview.name,\n en: preview.name,\n },\n },\n access: {\n protocol: 'skill',\n config: {\n path: finalManagedSkillDir,\n },\n },\n exposure: normalizeSummaryInput(deriveSkillSummary(preview)),\n };\n\n await writeFile(join(finalAppDir, 'aai.json'), JSON.stringify(descriptor, null, 2), 'utf-8');\n await upsertSkillRegistryEntry(\n {\n appId: preview.appId,\n protocol: 'skill',\n config: {\n path: finalManagedSkillDir,\n },\n },\n descriptor\n );\n\n return { appId: preview.appId, descriptor, managedPath: finalManagedSkillDir };\n}\n\nfunction buildSensitiveValueWarnings(options: McpImportOptions): string[] {\n const env = options.config.transport === 'stdio' ? options.config.env : undefined;\n const headers = options.config.transport !== 'stdio' ? (options.config as { headers?: Record<string, string> }).headers : undefined;\n if (containsPlaintextSensitiveValues(env) || containsPlaintextSensitiveValues(headers)) {\n return [\n `Sensitive values were provided directly in this chat. Next time, use \\${VAR_NAME} placeholders and store the real values in ${getDotenvPath()} instead of sending secrets in the conversation.`,\n ];\n }\n return [];\n}\n\nfunction containsPlaintextSensitiveValues(values?: Record<string, string>): boolean {\n if (!values) return false;\n return Object.entries(values).some(\n ([key, value]) => isSensitiveKey(key) && !hasEnvPlaceholders(value)\n );\n}\n\nfunction isSensitiveKey(key: string): boolean {\n const normalized = key.toLowerCase();\n return (\n normalized === 'authorization' ||\n normalized.includes('api-key') ||\n normalized.includes('apikey') ||\n normalized.endsWith('_api_key') ||\n normalized.endsWith('_token') ||\n normalized.endsWith('_secret') ||\n normalized.endsWith('_password')\n );\n}\n\nexport async function resolveImportedMcpRuntimeValues(\n config: McpConfig\n): Promise<{\n resolvedConfig: McpConfig;\n missingVars: string[];\n}> {\n const { env: dotenv, missing: missingInEnv } = await loadDotenv();\n const configAsRecord: Record<string, unknown> = JSON.parse(JSON.stringify(config));\n const { result: substitutedConfig, missing: configMissing } = substituteConfigEnvVars(\n configAsRecord,\n dotenv\n );\n\n const missingVars = [...missingInEnv, ...configMissing];\n return {\n resolvedConfig: substitutedConfig as unknown as McpConfig,\n missingVars,\n };\n}\n\nexport function parseSkillFrontMatter(content: string): SkillFrontMatter {\n const match = content.match(/^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n?([\\s\\S]*)$/);\n if (!match) {\n return { body: content };\n }\n\n const [, rawFrontMatter, body] = match;\n const fields = new Map<string, string>();\n for (const line of rawFrontMatter.split('\\n')) {\n const fieldMatch = line.match(/^([A-Za-z0-9_-]+):\\s*(.+)\\s*$/);\n if (!fieldMatch) {\n continue;\n }\n\n const [, key, value] = fieldMatch;\n fields.set(key.toLowerCase(), value.trim().replace(/^['\"]|['\"]$/g, ''));\n }\n\n return {\n name: fields.get('name'),\n description: fields.get('description'),\n body,\n };\n}\n\nasync function deriveImportName(\n executor: McpExecutor,\n config: McpConfig,\n appId: string\n): Promise<string> {\n const serverInfo = await executor.getServerInfo?.({\n appId,\n config,\n });\n if (serverInfo?.name) {\n return serverInfo.name;\n }\n\n return config.transport === 'stdio' ? basename(config.command) : new URL(config.url).hostname;\n}\n\nfunction buildImportedMcpDescriptor(name: string, config: McpConfig, exposure: SummaryDraft): AaiJson {\n return {\n schemaVersion: '2.0',\n version: '1.0.0',\n app: {\n name: {\n default: name,\n en: name,\n },\n },\n access: {\n protocol: 'mcp',\n config,\n },\n exposure,\n };\n}\n\nasync function deriveUniqueMcpAppId(config: McpConfig, name?: string): Promise<string> {\n const preferred = deriveLocalImportId(config, name);\n const existing = await getMcpRegistryEntry(preferred);\n if (!existing) {\n return preferred;\n }\n\n if (JSON.stringify(existing.config) === JSON.stringify(config)) {\n return preferred;\n }\n\n const seed =\n config.transport === 'stdio'\n ? `mcp:${config.command}:${(config.args ?? []).join(' ')}`\n : `mcp:${config.transport}:${config.url}`;\n return deriveAppId(name ? `${seed}:name:${name}` : seed, preferred);\n}\n\nfunction deriveLocalImportId(config: McpConfig, name?: string): string {\n if (name) {\n return slugify(name) || 'mcp';\n }\n\n const seed =\n config.transport === 'stdio'\n ? deriveStdioImportSlug(config.command, config.args)\n : deriveRemoteImportSlug(config.url);\n return slugify(seed) || 'mcp';\n}\n\nfunction deriveStdioImportSlug(command: string, args?: string[]): string {\n const packageArg = args?.find((arg) => isLikelyPackageReference(arg));\n if (packageArg) {\n return simplifyImportedName(packageArg);\n }\n\n return simplifyImportedName(basename(command));\n}\n\nfunction deriveRemoteImportSlug(url: string): string {\n const parsed = new URL(url);\n const hostname = parsed.hostname.replace(/^mcp\\./, '');\n const hostnameWithoutTld = hostname.split('.').filter(Boolean).slice(0, -1).join('-');\n const pathPart = parsed.pathname\n .split('/')\n .map((part) => part.trim())\n .filter(Boolean)\n .find((part) => part !== 'mcp' && part !== 'sse');\n\n return simplifyImportedName(hostnameWithoutTld || pathPart || hostname);\n}\n\nfunction isLikelyPackageReference(value: string): boolean {\n if (!value || value.startsWith('-')) {\n return false;\n }\n\n if (value.startsWith('/') || value.startsWith('./') || value.startsWith('../') || value.includes('\\\\')) {\n return false;\n }\n\n return value.includes('/') || value.includes('@') || /^[a-z0-9][a-z0-9._-]*$/i.test(value);\n}\n\nfunction simplifyImportedName(value: string): string {\n const trimmed = value.trim();\n const withoutScope = trimmed.startsWith('@') ? trimmed.split('/').slice(1).join('/') : trimmed;\n const lastSegment = withoutScope.split('/').filter(Boolean).pop() ?? withoutScope;\n const normalized = lastSegment\n .replace(/^modelcontextprotocol-/, '')\n .replace(/^mcp-server-/, 'server-')\n .replace(/^mcp-/, '');\n\n return slugify(normalized) || 'mcp';\n}\n\nfunction normalizeImportedAppName(name: string | undefined): string | undefined {\n validateOptionalStringLength(name, 'name', IMPORT_LIMITS.nameLength);\n const normalized = name?.trim();\n return normalized && normalized.length > 0 ? normalized : undefined;\n}\n\nfunction deriveSkillName(options: SkillImportSourceInput, content: string): string {\n const frontMatter = parseSkillFrontMatter(content);\n if (frontMatter.name) return frontMatter.name;\n\n const titleMatch = frontMatter.body.match(/^#\\s+(.+)$/m);\n if (titleMatch?.[1]) return titleMatch[1].trim();\n if (options.path) return basename(options.path);\n return 'Imported Skill';\n}\n\nasync function deriveUniqueSkillAppId(options: SkillImportSourceInput, content: string): Promise<string> {\n const preferred = `skill-${simplifyImportedName(deriveSkillName(options, content))}`;\n const existing = await getSkillRegistryEntry(preferred);\n if (!existing) {\n return preferred;\n }\n\n const seed = `skill:${options.path ?? 'imported-skill'}`;\n return deriveAppId(seed, preferred);\n}\n\nasync function readSkillSourceContent(options: SkillImportSourceInput): Promise<string> {\n if (options.path) {\n return readFile(join(options.path, 'SKILL.md'), 'utf-8');\n }\n\n throw new Error('Skill import requires a local path');\n}\n\nasync function copyDirectory(sourceDir: string, targetDir: string): Promise<void> {\n const fs = await import('node:fs/promises');\n await fs.cp(sourceDir, targetDir, { recursive: true });\n}\n\nfunction deriveSkillSummary(preview: SkillImportPreview): string {\n const preferred = preview.description?.trim() || extractFirstParagraph(preview.content) || `Use ${preview.name} through AAI Gateway.`;\n return normalizeSummaryInput(preferred.slice(0, EXPOSURE_LIMITS.summaryLength)).summary;\n}\n\nfunction extractFirstParagraph(content: string): string {\n const frontMatter = parseSkillFrontMatter(content);\n const cleaned = frontMatter.body\n .replace(/^# .+$/m, '')\n .split(/\\n\\s*\\n/)\n .map((block) => block.replace(/\\s+/g, ' ').trim())\n .find((block) => block.length > 0);\n return cleaned ?? '';\n}\n\nfunction validateOptionalStringLength(\n value: string | undefined,\n field: string,\n maxLength: number\n): void {\n if (value === undefined) {\n return;\n }\n\n if (value.length > maxLength) {\n throw new Error(`${field} is too long. Maximum length is ${maxLength} characters.`);\n }\n}\n\nfunction validateOptionalTimeoutMs(\n value: number | undefined,\n field: string,\n maxValue: number\n): void {\n if (value === undefined) {\n return;\n }\n\n if (!Number.isInteger(value) || value <= 0) {\n throw new Error(`${field} must be a positive integer in milliseconds.`);\n }\n\n if (value > maxValue) {\n throw new Error(`${field} is too large. Maximum value is ${maxValue}.`);\n }\n}\n\nfunction validateStringArrayLength(\n values: string[] | undefined,\n field: string,\n maxItems: number,\n maxItemLength: number\n): void {\n if (!values) {\n return;\n }\n\n if (values.length > maxItems) {\n throw new Error(`${field} has too many items. Maximum item count is ${maxItems}.`);\n }\n\n for (const [index, value] of values.entries()) {\n if (value.length > maxItemLength) {\n throw new Error(`${field}[${index}] is too long. Maximum length is ${maxItemLength} characters.`);\n }\n }\n}\n\nfunction validateStringRecordLength(\n record: Record<string, string> | undefined,\n field: string,\n maxItems: number,\n maxKeyLength: number,\n maxValueLength: number\n): void {\n if (!record) {\n return;\n }\n\n const entries = Object.entries(record);\n if (entries.length > maxItems) {\n throw new Error(`${field} has too many entries. Maximum entry count is ${maxItems}.`);\n }\n\n for (const [key, value] of entries) {\n if (key.length > maxKeyLength) {\n throw new Error(\n `${field} key '${key.slice(0, 32)}' is too long. Maximum key length is ${maxKeyLength} characters.`\n );\n }\n\n if (value.length > maxValueLength) {\n throw new Error(\n `${field} value for '${key.slice(0, 32)}' is too long. Maximum value length is ${maxValueLength} characters.`\n );\n }\n }\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\n\nimport { AaiError } from '../errors/errors.js';\nimport { getDotenvPath } from '../utils/dotenv.js';\nimport type {\n McpConfig,\n ExecutionResult,\n} from '../types/index.js';\nimport type { AppCapabilities } from '../types/capabilities.js';\nimport { logger } from '../utils/logger.js';\nimport { AAI_GATEWAY_NAME, AAI_GATEWAY_VERSION } from '../version.js';\nimport { validateArgs, formatValidationErrors } from '../utils/schema-validator.js';\nimport { resolveImportedMcpRuntimeValues } from '../core/importer.js';\n\nimport type { ExecutionObserver } from './events.js';\nimport type { Executor } from './interface.js';\n\nexport interface McpListedTool {\n name: string;\n description?: string;\n inputSchema: {\n type: 'object';\n properties?: Record<string, object>;\n required?: string[];\n [key: string]: unknown;\n };\n}\n\nexport interface McpConnectionTarget {\n appId: string;\n config: McpConfig;\n}\n\ninterface ClientState {\n client: Client;\n targetKey: string;\n config: McpConfig;\n activityListeners: Set<(message: unknown) => void>;\n}\n\ninterface McpServerInfo {\n name?: string;\n version?: string;\n [key: string]: unknown;\n}\n\nconst MCP_DEFAULT_REQUEST_TIMEOUT_MS = 60_000;\n\n/**\n * MCP Executor implementation\n *\n * Implements the unified Executor interface for MCP servers.\n */\nexport class McpExecutor implements Executor {\n readonly protocol = 'mcp';\n private clients = new Map<string, ClientState>();\n\n // Cache: appId → MCP tools (原始数据,含 inputSchema)\n private toolsCache = new Map<string, McpListedTool[]>();\n\n async connect(appId: string, config: McpConfig): Promise<void> {\n const targetKey = JSON.stringify({ config });\n const existing = this.clients.get(appId);\n if (existing && existing.targetKey === targetKey) {\n return;\n }\n\n if (existing) {\n await this.disconnect(appId);\n }\n\n const client = new Client(\n { name: AAI_GATEWAY_NAME, version: AAI_GATEWAY_VERSION },\n { capabilities: {} }\n );\n const transport = this.createTransport(config);\n const activityListeners = new Set<(message: unknown) => void>();\n transport.onmessage = (message) => {\n for (const listener of Array.from(activityListeners)) {\n listener(message);\n }\n };\n\n try {\n await client.connect(transport);\n this.clients.set(appId, { client, targetKey, config, activityListeners });\n logger.info({ appId, config: summarizeMcpConfig(config) }, 'MCP connection established');\n } catch (err) {\n logger.error({ appId, config: summarizeMcpConfig(config), err }, 'MCP connection failed');\n throw new AaiError(\n 'SERVICE_UNAVAILABLE',\n `Failed to connect MCP app '${appId}': ${String(err)}`\n );\n }\n }\n\n async disconnect(appId: string): Promise<void> {\n const existing = this.clients.get(appId);\n if (!existing) return;\n this.clients.delete(appId);\n try {\n await existing.client.close();\n } catch {\n // ignore\n }\n // Clear tools cache for this appId\n this.toolsCache.delete(appId);\n }\n\n\n /**\n * Load app-level capabilities with full tool schemas\n */\n async loadAppCapabilities(appId: string, config: McpConfig): Promise<AppCapabilities> {\n const result = await this.listTools({ appId, config });\n\n // Cache the full tools data for validation during execute\n this.toolsCache.set(appId, result);\n\n const tools = result.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n inputSchema: t.inputSchema ?? { type: 'object' as const, properties: {} },\n }));\n\n return { title: 'MCP Tools', tools };\n }\n\n async execute(\n appId: string,\n config: McpConfig,\n operation: string,\n args: Record<string, unknown>\n ): Promise<ExecutionResult> {\n // Validate against cached schema if available\n let tools = this.toolsCache.get(appId);\n if (!tools) {\n await this.loadAppCapabilities(appId, config);\n tools = this.toolsCache.get(appId);\n }\n const cachedTool = tools?.find((t) => t.name === operation);\n if (cachedTool) {\n const inputSchema = cachedTool.inputSchema ?? { type: 'object', properties: {} };\n const result = validateArgs(args, inputSchema);\n if (!result.valid) {\n const errorMessage = `参数校验失败 for '${operation}'\\n${formatValidationErrors(result)}`;\n return {\n success: false,\n error: errorMessage,\n schema: inputSchema,\n };\n }\n }\n\n try {\n const data = await this.callTool(\n { appId, config },\n operation,\n args\n );\n return { success: true, data };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n async health(appId: string): Promise<boolean> {\n return this.clients.has(appId);\n }\n\n async listTools(target: McpConnectionTarget): Promise<McpListedTool[]> {\n try {\n const client = await this.connectLegacy(target);\n const result = await client.listTools();\n logger.info(\n { appId: target.appId, config: summarizeMcpConfig(target.config), toolCount: result.tools.length },\n 'MCP tools listed'\n );\n return result.tools as McpListedTool[];\n } catch (err) {\n logger.error(\n { appId: target.appId, config: summarizeMcpConfig(target.config), err },\n 'Failed to list MCP tools'\n );\n throw new AaiError(\n 'EXECUTION_ERROR',\n `Failed to list tools for '${target.appId}': ${String(err)}`\n );\n }\n }\n\n async getServerInfo(target: McpConnectionTarget): Promise<McpServerInfo | undefined> {\n const client = await this.connectLegacy(target);\n return client.getServerVersion() as McpServerInfo | undefined;\n }\n\n async callTool(\n target: McpConnectionTarget,\n toolName: string,\n args: Record<string, unknown>,\n observer?: ExecutionObserver\n ): Promise<unknown> {\n const execute = async (): Promise<unknown> => {\n const client = await this.connectLegacy(target);\n const state = this.clients.get(target.appId);\n if (!state) {\n throw new AaiError('SERVICE_UNAVAILABLE', `MCP app '${target.appId}' is not connected`);\n }\n\n const activityListener = (message: unknown) => {\n const notificationMessage = extractNotificationMessage(message);\n if (notificationMessage) {\n void observer?.onMessage?.({ message: notificationMessage });\n }\n };\n\n state.activityListeners.add(activityListener);\n\n try {\n const timeoutMs = getMcpRequestTimeoutMs(target.config);\n const result = (await client.callTool(\n {\n name: toolName,\n arguments: args,\n },\n undefined,\n {\n timeout: timeoutMs,\n onprogress: (progress) => {\n void observer?.onProgress?.({\n progress: progress.progress,\n ...(progress.message ? { message: progress.message } : {}),\n });\n },\n }\n )) as { content?: unknown };\n\n state.activityListeners.delete(activityListener);\n logger.info(\n {\n appId: target.appId,\n tool: toolName,\n config: summarizeMcpConfig(target.config),\n },\n 'MCP tool call completed'\n );\n return result;\n } catch (err) {\n state.activityListeners.delete(activityListener);\n logger.error(\n {\n appId: target.appId,\n tool: toolName,\n config: summarizeMcpConfig(target.config),\n err,\n },\n 'MCP tool call failed'\n );\n throw err;\n }\n };\n\n try {\n return await execute();\n } catch (err) {\n await this.close(target.appId);\n try {\n return await execute();\n } catch (retryErr) {\n logger.error(\n {\n appId: target.appId,\n tool: toolName,\n config: summarizeMcpConfig(target.config),\n err: retryErr ?? err,\n },\n 'MCP tool call failed after retry'\n );\n throw new AaiError(\n 'EXECUTION_ERROR',\n `MCP tool '${toolName}' failed for '${target.appId}': ${String(retryErr ?? err)}`\n );\n }\n }\n }\n\n async close(appId: string): Promise<void> {\n return this.disconnect(appId);\n }\n\n private createTransport(config: McpConfig) {\n switch (config.transport) {\n case 'stdio':\n return new StdioClientTransport({\n command: config.command,\n args: config.args,\n env: config.env,\n cwd: config.cwd,\n stderr: 'pipe',\n });\n case 'streamable-http':\n return new StreamableHTTPClientTransport(new URL(config.url), {\n requestInit: config.headers ? { headers: config.headers } : undefined,\n });\n case 'sse':\n return new SSEClientTransport(new URL(config.url), {\n requestInit: config.headers ? { headers: config.headers } : undefined,\n });\n }\n }\n\n private async connectLegacy(target: McpConnectionTarget): Promise<Client> {\n const resolvedTarget = await this.resolveTarget(target);\n await this.connect(resolvedTarget.appId, resolvedTarget.config);\n const state = this.clients.get(target.appId);\n if (!state) {\n throw new AaiError('SERVICE_UNAVAILABLE', `MCP app '${target.appId}' is not connected`);\n }\n return state.client;\n }\n\n private async resolveTarget(target: McpConnectionTarget): Promise<McpConnectionTarget> {\n const { resolvedConfig, missingVars } = await resolveImportedMcpRuntimeValues(target.config);\n\n if (missingVars.length > 0) {\n const uniqueMissing = [...new Set(missingVars)];\n throw new AaiError(\n 'INVALID_REQUEST',\n `Missing environment variables for MCP app '${target.appId}': ${uniqueMissing.map((name) => `$\\{${name}}`).join(', ')}`,\n {\n code: 'MISSING_ENV_VARS',\n missingVars: uniqueMissing,\n envFile: getDotenvPath(),\n setupExample: uniqueMissing.map((name) => `${name}=your_value_here`),\n userAction:\n `Do not read ${getDotenvPath()}. Help the user open it and ask them to paste the values themselves.`,\n }\n );\n }\n\n return { appId: target.appId, config: resolvedConfig };\n }\n}\n\nfunction getMcpRequestTimeoutMs(config: McpConfig): number {\n return config.timeout ?? MCP_DEFAULT_REQUEST_TIMEOUT_MS;\n}\n\nfunction extractNotificationMessage(message: unknown): string | null {\n if (!message || typeof message !== 'object') {\n return null;\n }\n\n const method = (message as { method?: unknown }).method;\n if (method !== 'notifications/message') {\n return null;\n }\n\n const params = (message as { params?: unknown }).params;\n if (!params || typeof params !== 'object') {\n return null;\n }\n\n const data = (params as { data?: unknown }).data;\n if (typeof data === 'string' && data.length > 0) {\n return data;\n }\n\n if (data !== undefined) {\n const serialized = JSON.stringify(data);\n return serialized && serialized !== 'null' ? serialized : null;\n }\n\n return null;\n}\n\nfunction summarizeMcpConfig(config: McpConfig): Record<string, unknown> {\n switch (config.transport) {\n case 'stdio':\n return {\n transport: config.transport,\n command: config.command,\n argvLength: config.args?.length ?? 0,\n ...(config.cwd ? { cwd: config.cwd } : {}),\n ...(config.env ? { envKeys: Object.keys(config.env) } : {}),\n ...(config.timeout ? { timeout: config.timeout } : {}),\n };\n case 'streamable-http':\n case 'sse':\n return {\n transport: config.transport,\n url: config.url,\n ...(config.timeout ? { timeout: config.timeout } : {}),\n };\n }\n}\n\nlet singleton: McpExecutor | undefined;\n\nexport function getMcpExecutor(): McpExecutor {\n if (!singleton) {\n singleton = new McpExecutor();\n }\n return singleton;\n}\n","import { exec } from 'node:child_process';\nimport { access, stat } from 'node:fs/promises';\nimport { promisify } from 'node:util';\n\nimport type { AaiJson } from '../types/aai-json.js';\n\nconst execAsync = promisify(exec);\n\nexport interface DiscoveryCheckResult {\n available: boolean;\n location: string | null;\n}\n\nexport async function evaluateDescriptorAvailability(\n descriptor: AaiJson\n): Promise<DiscoveryCheckResult> {\n const checks = descriptor.discovery?.checks;\n if (!checks || checks.length === 0) {\n return { available: true, location: null };\n }\n\n let location: string | null = null;\n\n for (const check of checks) {\n switch (check.kind) {\n case 'command': {\n const commandPath = await resolveCommandPath(check.command);\n if (!commandPath) {\n return { available: false, location: null };\n }\n\n if (!location) {\n location = commandPath;\n }\n break;\n }\n case 'file': {\n const filePath = await resolveFilePath(check.path);\n if (!filePath) {\n return { available: false, location: null };\n }\n\n if (!location) {\n location = filePath;\n }\n break;\n }\n case 'path': {\n const pathLocation = await resolveDirectoryPath(check.path);\n if (!pathLocation) {\n return { available: false, location: null };\n }\n\n if (!location) {\n location = pathLocation;\n }\n break;\n }\n }\n }\n\n return { available: true, location };\n}\n\nasync function resolveCommandPath(command: string): Promise<string | null> {\n try {\n const query = process.platform === 'win32' ? `where ${command}` : `which ${command}`;\n const { stdout } = await execAsync(query);\n return stdout.trim().split('\\n')[0] || null;\n } catch {\n return null;\n }\n}\n\nasync function resolveFilePath(path: string): Promise<string | null> {\n try {\n const fileStat = await stat(path);\n return fileStat.isFile() ? path : null;\n } catch {\n return null;\n }\n}\n\nasync function resolveDirectoryPath(path: string): Promise<string | null> {\n try {\n const pathStat = await stat(path);\n if (pathStat.isDirectory()) {\n await access(path);\n return path;\n }\n return null;\n } catch {\n return null;\n }\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { evaluateDescriptorAvailability } from '../discovery/checks.js';\nimport { parseAaiJson } from '../parsers/schema.js';\nimport type { RuntimeAppRecord } from '../types/aai-json.js';\n\nimport { getManagedAppsRoot } from './paths.js';\n\nexport interface ManagedEntry {\n id: string;\n appId: string;\n protocol: 'mcp' | 'skill' | 'cli' | 'acp-agent';\n descriptorPath: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Managed Registry\n *\n * Manages gateway-managed app descriptors (imported MCP servers, skills, CLI apps, etc.).\n * This registry is based on the file system structure rather than a separate registry file.\n */\nexport class ManagedRegistry {\n /**\n * Scan the managed apps directory and return all valid app records\n */\n async scan(): Promise<RuntimeAppRecord[]> {\n try {\n const records: RuntimeAppRecord[] = [];\n const root = getManagedAppsRoot();\n let entries;\n try {\n entries = await readdir(root, { withFileTypes: true });\n } catch {\n return [];\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue;\n }\n\n try {\n const descriptorPath = join(root, entry.name, 'aai.json');\n const descriptor = parseAaiJson(JSON.parse(await readFile(descriptorPath, 'utf-8')));\n const availability = await evaluateDescriptorAvailability(descriptor);\n if (!availability.available) {\n continue;\n }\n const protocol = descriptor.access.protocol;\n\n let source: RuntimeAppRecord['source'];\n switch (protocol) {\n case 'mcp':\n source = 'mcp-import';\n break;\n case 'skill':\n source = 'skill-import';\n break;\n case 'acp-agent':\n source = 'acp-agent';\n break;\n case 'cli':\n source = 'cli';\n break;\n default:\n continue;\n }\n\n records.push({\n appId: entry.name,\n descriptor,\n source,\n location: availability.location ?? descriptorPath,\n });\n } catch {\n // Skip non-app directories or invalid descriptors\n }\n }\n\n return records;\n } catch {\n return [];\n }\n }\n\n /**\n * Get a specific managed app by appId\n */\n async get(appId: string): Promise<RuntimeAppRecord | null> {\n const records = await this.scan();\n return records.find((r) => r.appId === appId) ?? null;\n }\n\n /**\n * Delete a managed app by appId\n * @deprecated This method is not implemented yet. Use the specific registries (McpRegistry, SkillRegistry) for deletion.\n */\n async delete(_appId: string): Promise<boolean> {\n // This would need to interact with the specific registries\n // For now, we'll return false to indicate it's not implemented\n return false;\n }\n\n /**\n * Check if a managed app exists\n */\n async has(appId: string): Promise<boolean> {\n const app = await this.get(appId);\n return app !== null;\n }\n}\n\n/**\n * Create a singleton Managed registry instance\n */\nlet managedRegistryInstance: ManagedRegistry | null = null;\nexport function getManagedRegistry(): ManagedRegistry {\n if (!managedRegistryInstance) {\n managedRegistryInstance = new ManagedRegistry();\n }\n return managedRegistryInstance;\n}\n\n// Backward compatibility exports\nexport async function loadManagedDescriptors(): Promise<RuntimeAppRecord[]> {\n return getManagedRegistry().scan();\n}\n","import { mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nimport { getAaiHomeDir } from '../utils/config.js';\nimport { slugify } from '../utils/ids.js';\n\nexport interface AgentState {\n agentId: string;\n agentType?: string;\n callerName: string;\n appOverrides: Record<string, 'enabled' | 'disabled'>;\n updatedAt: string;\n}\n\nexport interface AppPolicyState {\n defaultEnabled: 'all' | 'importer-only';\n importerAgentId?: string;\n updatedAt: string;\n}\n\nfunction getAgentsRoot(): string {\n return join(getAaiHomeDir(), 'agents');\n}\n\nfunction getAgentStatePath(agentId: string): string {\n return join(getAgentsRoot(), `${agentId}.json`);\n}\n\nfunction getAppStatePath(appId: string): string {\n return join(getAaiHomeDir(), 'apps', `${appId}.json`);\n}\n\nexport function deriveCallerId(input: { callerId?: string; callerName?: string }): string {\n if (input.callerId && input.callerId.trim().length > 0) {\n return slugify(input.callerId);\n }\n if (input.callerName && input.callerName.trim().length > 0) {\n return slugify(input.callerName);\n }\n return 'unknown-client';\n}\n\nexport async function loadAgentState(agentId: string): Promise<AgentState | null> {\n try {\n const raw = await readFile(getAgentStatePath(agentId), 'utf-8');\n return JSON.parse(raw) as AgentState;\n } catch {\n return null;\n }\n}\n\nexport async function saveAgentState(state: AgentState): Promise<void> {\n const path = getAgentStatePath(state.agentId);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(state, null, 2), 'utf-8');\n}\n\nexport async function upsertAgentState(input: {\n agentId: string;\n callerName: string;\n agentType?: string;\n}): Promise<AgentState> {\n const existing = await loadAgentState(input.agentId);\n const next: AgentState = {\n agentId: input.agentId,\n callerName: input.callerName,\n agentType: input.agentType ?? existing?.agentType,\n appOverrides: existing?.appOverrides ?? {},\n updatedAt: new Date().toISOString(),\n };\n await saveAgentState(next);\n return next;\n}\n\nexport async function disableAppForAgent(agentId: string, appId: string): Promise<AgentState> {\n const state = (await loadAgentState(agentId)) ?? {\n agentId,\n callerName: agentId,\n appOverrides: {},\n updatedAt: new Date().toISOString(),\n };\n\n state.appOverrides[appId] = 'disabled';\n state.updatedAt = new Date().toISOString();\n await saveAgentState(state);\n return state;\n}\n\nexport async function enableAppForAgent(agentId: string, appId: string): Promise<AgentState> {\n const state = await loadAgentState(agentId);\n if (!state) {\n const next: AgentState = {\n agentId,\n callerName: agentId,\n appOverrides: { [appId]: 'enabled' },\n updatedAt: new Date().toISOString(),\n };\n await saveAgentState(next);\n return next;\n }\n\n state.appOverrides[appId] = 'enabled';\n state.updatedAt = new Date().toISOString();\n await saveAgentState(state);\n return state;\n}\n\nexport async function loadAppPolicyState(appId: string): Promise<AppPolicyState | null> {\n try {\n const raw = await readFile(getAppStatePath(appId), 'utf-8');\n return JSON.parse(raw) as AppPolicyState;\n } catch {\n return null;\n }\n}\n\nexport async function saveAppPolicyState(\n appId: string,\n state: AppPolicyState\n): Promise<void> {\n const path = getAppStatePath(appId);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(state, null, 2), 'utf-8');\n}\n\nexport async function deleteAppPolicyState(appId: string): Promise<void> {\n await rm(getAppStatePath(appId), { force: true });\n}\n\nexport async function removeAppFromAllAgents(appId: string): Promise<void> {\n let entries: string[] = [];\n try {\n entries = await readdir(getAgentsRoot());\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (!entry.endsWith('.json')) continue;\n\n const agentId = entry.slice(0, -'.json'.length);\n const state = await loadAgentState(agentId);\n if (!state) continue;\n\n if (state.appOverrides[appId]) {\n delete state.appOverrides[appId];\n state.updatedAt = new Date().toISOString();\n await saveAgentState(state);\n }\n }\n}\n","export const SEARCH_DISCOVER_TOOL_NAME = 'search:discover';\n\nexport const searchDiscoverInputSchema: Record<string, unknown> = {\n type: 'object',\n properties: {},\n additionalProperties: false,\n};\n\nconst SEARCH_DISCOVER_GUIDE = `# MCP & Skill Search Guide\n\nUse this guide when you need to find new MCP servers or skills for the user.\n\n## Where to Search\n\n### MCP Sources\n- Official MCP Registry: https://github.com/modelcontextprotocol/registry\n- Official MCP Servers: https://github.com/modelcontextprotocol/servers\n- GitHub search: repositories, README files, release pages, and installation docs\n\n### Skill Sources\n- OpenAI Skills: https://github.com/openai/skills\n- Anthropic Skills: https://github.com/anthropics/skills\n- OpenClaw Skills: https://github.com/openclaw/skills\n- GitHub search: repositories and real skill directory paths\n- Community skill lists and registries\n\n## What to Collect\n\n### Collect for user-facing comparison\nFor each candidate, collect:\n- Type: MCP or Skill\n- Name\n- Source\n- Trust: official / community / experimental\n- Score: use the rating from the source when available, such as GitHub stars or a platform rating; omit it when no rating is available\n- What it does: one short plain-language summary\n\n### Collect for installation handoff only\nDo not show these details in the main comparison table unless the user asks.\n\nFor MCP candidates, also collect:\n- Install method:\n - local stdio: command + args\n - remote: transport + url\n- Whether headers are required\n- Whether env variables are required\n- The source page that shows the install configuration\n\nFor Skill candidates, also collect:\n- Download source URL\n- The real skill directory path\n- Whether the whole skill directory must be downloaded\n- The source page that shows the download path or repository path\n\n## How to Evaluate Candidates\n\nWhen comparing candidates, consider:\n- Relevance to the user's task\n- Whether the source is official or community-maintained\n- Maintenance quality: recent activity, clear README, usable install docs\n- Source-provided popularity or rating signals when available\n- Safety and clarity of installation requirements\n\n## How to Present Results to the User\n\nAfter searching, show the user a short comparison table.\n\nRecommended columns:\n- Type\n- Name\n- Source\n- Trust\n- Score\n- What it does\n\nKeep the table short and readable.\nDo not put raw install config, headers, env variables, or download payloads into the main user-facing table.\n\n## User Confirmation\n\nAfter showing the comparison table:\n1. Ask the user which MCP or skill they want to install.\n2. Wait for explicit user confirmation.\n3. Only then continue with import.\n\n## Import Next Step\n\nAfter the user confirms a candidate:\n\n- If the user chose an MCP server:\n - Use \\`mcp:import\\`\n\n- If the user chose a skill:\n - First make sure the whole skill directory is available locally\n - Then use \\`skill:import\\`\n\n## Important Notes\n\n- \\`search:discover\\` only provides search guidance.\n- You must perform the actual web search yourself.\n- You must prepare the comparison table yourself.\n- You must ask for user confirmation yourself.\n- You must call the appropriate AAI import tool yourself after confirmation.\n`;\n\nexport function parseSearchDiscoverArguments(args: Record<string, unknown> | undefined): void {\n if (!args || Object.keys(args).length === 0) {\n return;\n }\n\n throw new Error(`${SEARCH_DISCOVER_TOOL_NAME} does not accept arguments`);\n}\n\nexport function buildSearchDiscoverResponse(): string {\n return SEARCH_DISCOVER_GUIDE;\n}\n","/**\n * MCP Argument Parsers\n *\n * Handles parsing and validation of MCP tool call arguments.\n * These are MCP-protocol-specific input normalization functions.\n */\n\nimport type { McpConfig } from '../types/aai-json.js';\nimport { AaiError } from '../errors/errors.js';\nimport {\n buildMcpImportConfig,\n buildSkillImportSource,\n normalizeSummaryInput,\n} from './importer.js';\n\nexport interface ParsedMcpImportArgs {\n name?: string;\n config: McpConfig;\n metadata?: {\n summary: string;\n enableScope: 'current' | 'all';\n };\n}\n\nexport interface ParsedSkillImportArgs {\n path: string;\n}\n\nexport function parseMcpImportArguments(args: Record<string, unknown> | undefined): ParsedMcpImportArgs {\n try {\n // Normalize: when command is an array (common in standard MCP JSON configs),\n // split into command (first element) + args (remaining elements).\n let command = args?.command;\n let argsArray = args?.args;\n if (Array.isArray(command)) {\n const parts = command.filter((item): item is string => typeof item === 'string');\n if (parts.length > 0) {\n command = parts[0];\n if (parts.length > 1) {\n argsArray = [...parts.slice(1), ...(Array.isArray(argsArray) ? argsArray : [])];\n }\n }\n }\n\n // Normalize: accept \"environment\" as an alias for \"env\".\n const env = args?.env ?? args?.environment;\n\n // Normalize: accept \"headers\" for remote MCP imports.\n const headers = args?.headers;\n\n return {\n name: asOptionalString(args?.name),\n config: buildMcpImportConfig({\n transport:\n args?.transport === 'streamable-http' || args?.transport === 'sse'\n ? args.transport\n : undefined,\n url: asOptionalString(args?.url),\n command: asOptionalString(command),\n timeout: asOptionalPositiveInteger(args?.timeout, 'timeout'),\n args: asOptionalStringArray(argsArray, 'args'),\n env: asOptionalStringRecord(env, 'env'),\n cwd: asOptionalString(args?.cwd),\n headers: asOptionalStringRecord(headers, 'headers'),\n }),\n metadata: parseOptionalMcpImportMetadata(args),\n };\n } catch (err) {\n throw new AaiError('INVALID_REQUEST', err instanceof Error ? err.message : String(err));\n }\n}\n\nexport function parseSkillImportArguments(args: Record<string, unknown> | undefined): ParsedSkillImportArgs {\n try {\n const source = buildSkillImportSource({\n path: asOptionalString(args?.path),\n });\n\n return { path: source.path! };\n } catch (err) {\n throw new AaiError('INVALID_REQUEST', err instanceof Error ? err.message : String(err));\n }\n}\n\nfunction parseOptionalMcpImportMetadata(args: Record<string, unknown> | undefined):\n | { summary: string; enableScope: 'current' | 'all' }\n | undefined {\n const hasSummary = args?.summary !== undefined;\n const hasEnableScope = args?.enableScope !== undefined;\n const providedCount = Number(hasSummary) + Number(hasEnableScope);\n\n if (providedCount === 0) return undefined;\n\n if (providedCount !== 2) {\n throw new Error(\n \"MCP import requires 'summary' and 'enableScope' together. Omit both for inspection, or provide both for the final import.\"\n );\n }\n\n const summary = asOptionalString(args?.summary);\n const enableScope = parseEnableScope(args?.enableScope);\n\n if (!summary) {\n throw new Error(\"Import received an empty 'summary'\");\n }\n\n return { ...normalizeSummaryInput(summary), enableScope };\n}\n\nfunction parseEnableScope(value: unknown): 'current' | 'all' {\n if (value === 'current' || value === 'all') return value;\n throw new Error(\"MCP import requires 'enableScope' to be either 'current' or 'all'\");\n}\n\n// ============================================================\n// Primitive type helpers\n// ============================================================\n\nexport function asOptionalString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nexport function asOptionalPositiveInteger(value: unknown, field: string): number | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'number' || !Number.isInteger(value) || value <= 0) {\n throw new Error(`${field} must be a positive integer in milliseconds`);\n }\n return value;\n}\n\nexport function asOptionalStringArray(value: unknown, field: string): string[] | undefined {\n const normalized = tryParseJsonString(value);\n if (normalized === undefined) return undefined;\n if (!Array.isArray(normalized)) {\n throw new AaiError('INVALID_REQUEST', `${field} must be an array of strings`);\n }\n if (normalized.find((item) => typeof item !== 'string') !== undefined) {\n throw new AaiError('INVALID_REQUEST', `${field} must contain only strings`);\n }\n return normalized as string[];\n}\n\nexport function asOptionalStringRecord(value: unknown, field: string): Record<string, string> | undefined {\n const normalized = tryParseJsonString(value);\n if (normalized === undefined) return undefined;\n if (!isStringRecord(normalized)) {\n throw new AaiError('INVALID_REQUEST', `${field} must be an object with string values`);\n }\n return normalized;\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false;\n return Object.values(value).every((item) => typeof item === 'string');\n}\n\nfunction tryParseJsonString(value: unknown): unknown {\n if (typeof value !== 'string') return value;\n const trimmed = value.trim();\n if (trimmed.length === 0 || (!trimmed.startsWith('[') && !trimmed.startsWith('{'))) return value;\n try {\n return JSON.parse(trimmed);\n } catch {\n return value;\n }\n}\n\nexport function normalizeArgumentsWithSchema(value: unknown, schema: Record<string, unknown>): unknown {\n const normalized = parseJsonStringForExpectedType(value, schema);\n const type = schema.type as string | undefined;\n\n if (\n type === 'object' &&\n normalized &&\n typeof normalized === 'object' &&\n !Array.isArray(normalized)\n ) {\n const properties = schema.properties as Record<string, unknown> | undefined;\n const additionalProperties = schema.additionalProperties;\n const result: Record<string, unknown> = {};\n\n for (const [key, item] of Object.entries(normalized as Record<string, unknown>)) {\n const propertySchema = properties?.[key];\n if (propertySchema && typeof propertySchema === 'object' && !Array.isArray(propertySchema)) {\n result[key] = normalizeArgumentsWithSchema(item, propertySchema as Record<string, unknown>);\n continue;\n }\n if (\n additionalProperties &&\n typeof additionalProperties === 'object' &&\n !Array.isArray(additionalProperties)\n ) {\n result[key] = normalizeArgumentsWithSchema(\n item,\n additionalProperties as Record<string, unknown>\n );\n continue;\n }\n result[key] = item;\n }\n return result;\n }\n\n if (type === 'array' && Array.isArray(normalized)) {\n const itemSchema = schema.items;\n if (itemSchema && typeof itemSchema === 'object' && !Array.isArray(itemSchema)) {\n return normalized.map((item) =>\n normalizeArgumentsWithSchema(item, itemSchema as Record<string, unknown>)\n );\n }\n }\n\n return normalized;\n}\n\nfunction parseJsonStringForExpectedType(value: unknown, schema: Record<string, unknown>): unknown {\n if (typeof value !== 'string') return value;\n const expectedType = schema.type as string | undefined;\n const trimmed = value.trim();\n\n if (expectedType === 'object' && trimmed.startsWith('{')) {\n try { return JSON.parse(trimmed); } catch { return value; }\n }\n if (expectedType === 'array' && trimmed.startsWith('[')) {\n try { return JSON.parse(trimmed); } catch { return value; }\n }\n return value;\n}\n\n// ============================================================\n// Log summarization helpers\n// ============================================================\n\nexport function summarizeExecArgs(args: Record<string, unknown>): Record<string, unknown> {\n const summary: Record<string, unknown> = { keys: Object.keys(args) };\n\n if (typeof args.sessionId === 'string') summary.sessionId = args.sessionId;\n if (typeof args.turnId === 'string') summary.turnId = args.turnId;\n\n if (typeof args.text === 'string') {\n summary.textLength = args.text.length;\n summary.textPreview = truncateLogPreview(args.text);\n } else if (typeof args.message === 'string') {\n summary.messageLength = args.message.length;\n summary.messagePreview = truncateLogPreview(args.message);\n } else if (Array.isArray(args.prompt)) {\n summary.promptBlocks = args.prompt.length;\n }\n\n if (typeof args.cwd === 'string') summary.cwd = args.cwd;\n return summary;\n}\n\nexport function summarizeExecResult(result: unknown): Record<string, unknown> | undefined {\n if (!result || typeof result !== 'object' || Array.isArray(result)) return undefined;\n const record = result as Record<string, unknown>;\n const summary: Record<string, unknown> = {};\n\n if (typeof record.turnId === 'string') summary.turnId = record.turnId;\n if (typeof record.sessionId === 'string') summary.sessionId = record.sessionId;\n if (typeof record.done === 'boolean') summary.done = record.done;\n if (typeof record.cancelled === 'boolean') summary.cancelled = record.cancelled;\n if (typeof record.status === 'string') summary.status = record.status;\n if (typeof record.error === 'string') summary.error = truncateLogPreview(record.error);\n if (Array.isArray(record.content)) {\n summary.contentBlocks = record.content.length;\n const textPreview = previewStructuredContent(record.content);\n if (textPreview) summary.textPreview = textPreview;\n }\n\n return Object.keys(summary).length > 0 ? summary : undefined;\n}\n\nexport function summarizeRawImportArgs(\n args: Record<string, unknown> | undefined\n): Record<string, unknown> {\n if (!args) return {};\n return {\n keys: Object.keys(args),\n ...(typeof args.name === 'string' ? { name: args.name } : {}),\n ...(typeof args.command === 'string' ? { command: args.command } : {}),\n ...(Array.isArray(args.args) ? { argvLength: args.args.length } : {}),\n ...(typeof args.cwd === 'string' ? { cwd: args.cwd } : {}),\n ...(typeof args.url === 'string' ? { url: args.url } : {}),\n ...(typeof args.transport === 'string' ? { transport: args.transport } : {}),\n ...(typeof args.path === 'string' ? { path: args.path } : {}),\n ...(typeof args.enableScope === 'string' ? { enableScope: args.enableScope } : {}),\n ...(typeof args.summary === 'string' ? { summaryLength: args.summary.length } : {}),\n ...(args.env && typeof args.env === 'object' && !Array.isArray(args.env)\n ? { envKeys: Object.keys(args.env as Record<string, unknown>) }\n : {}),\n };\n}\n\nexport function summarizeMcpImportRequest(options: ParsedMcpImportArgs): Record<string, unknown> {\n return {\n ...(options.name ? { name: options.name } : {}),\n config: summarizeMcpConfig(options.config),\n ...(options.metadata\n ? { summaryLength: options.metadata.summary.length, enableScope: options.metadata.enableScope }\n : {}),\n };\n}\n\nexport function summarizeSkillImportRequest(options: ParsedSkillImportArgs): Record<string, unknown> {\n return { path: options.path };\n}\n\nfunction summarizeMcpConfig(config: McpConfig): Record<string, unknown> {\n switch (config.transport) {\n case 'stdio':\n return {\n transport: config.transport,\n command: config.command,\n argvLength: config.args?.length ?? 0,\n ...(config.cwd ? { cwd: config.cwd } : {}),\n ...(config.env ? { envKeys: Object.keys(config.env) } : {}),\n ...(config.timeout ? { timeout: config.timeout } : {}),\n };\n case 'streamable-http':\n case 'sse':\n return {\n transport: config.transport,\n url: config.url,\n ...(config.timeout ? { timeout: config.timeout } : {}),\n };\n }\n}\n\nfunction truncateLogPreview(value: string, maxChars = 160): string {\n return value.length <= maxChars ? value : `${value.slice(0, maxChars)}...`;\n}\n\nfunction previewStructuredContent(content: unknown[], maxChars = 160): string | undefined {\n const text = content\n .filter(\n (item): item is { type?: unknown; text?: unknown } =>\n !!item && typeof item === 'object' && !Array.isArray(item)\n )\n .filter((item) => item.type === 'text' && typeof item.text === 'string')\n .map((item) => item.text as string)\n .join('');\n return text.length > 0 ? truncateLogPreview(text, maxChars) : undefined;\n}\n","/**\n * Gateway Tool Definitions\n *\n * Defines the MCP tool schemas exposed by AAI Gateway.\n * Separated from protocol handling for clarity.\n */\n\nimport { EXPOSURE_LIMITS, IMPORT_LIMITS } from './importer.js';\nimport {\n SEARCH_DISCOVER_TOOL_NAME,\n searchDiscoverInputSchema,\n} from './search-guidance.js';\nimport { getDotenvPath } from '../utils/dotenv.js';\n\nexport interface GatewayToolDefinition {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n listInputSchema?: Record<string, unknown>;\n}\n\nexport function buildGatewayToolDefinitions(): GatewayToolDefinition[] {\n return [\n {\n name: 'aai:exec',\n description:\n 'Execute a tool. Read the guide first (e.g. app:*, mcp:import) — it contains the full schema.',\n inputSchema: {\n type: 'object',\n properties: {\n app: {\n type: 'string',\n description: 'Required for app tools, omit or use \"gateway\" for gateway tools.',\n },\n tool: {\n type: 'string',\n description: 'Tool name within the app, not prefixed with app id.',\n },\n args: {\n type: 'object',\n additionalProperties: true,\n description: 'Arguments for the selected tool.',\n },\n },\n required: ['tool'],\n },\n },\n {\n name: 'mcp:import',\n description: 'Call this to import an MCP server. Returns the import workflow and parameters.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: `Optional. Display name for the imported app. Maximum length: ${IMPORT_LIMITS.nameLength} characters.`,\n },\n transport: {\n type: 'string',\n enum: ['streamable-http', 'sse'],\n description:\n 'Optional. Only used with url for remote MCP imports. Defaults to \"streamable-http\".',\n },\n command: {\n type: 'string',\n description: `Use this for a local stdio MCP import. The executable to launch. Maximum length: ${IMPORT_LIMITS.commandLength} characters.`,\n },\n args: {\n type: 'array',\n items: { type: 'string' },\n description: `Optional for local stdio MCP imports. Command arguments. Maximum ${IMPORT_LIMITS.argCount} items, each at most ${IMPORT_LIMITS.argLength} characters.`,\n },\n env: {\n type: 'object',\n additionalProperties: { type: 'string' },\n description: `Optional for local stdio MCP imports. Environment variables. Maximum ${IMPORT_LIMITS.envCount} entries.`,\n },\n cwd: {\n type: 'string',\n description: `Optional for local stdio MCP imports. Working directory. Maximum length: ${IMPORT_LIMITS.cwdLength} characters.`,\n },\n timeout: {\n type: 'integer',\n description: `Optional. MCP tool execution timeout in milliseconds. Default 60000. Maximum: ${IMPORT_LIMITS.timeoutMsMax}.`,\n },\n url: {\n type: 'string',\n description: `Use this for a remote MCP import. The remote MCP endpoint URL. Maximum length: ${IMPORT_LIMITS.urlLength} characters.`,\n },\n headers: {\n type: 'object',\n additionalProperties: { type: 'string' },\n description:\n 'Optional for remote MCP imports. HTTP headers (e.g. Authorization). Use ${VAR_NAME} placeholders for sensitive values.',\n },\n summary: {\n type: 'string',\n description: `Optional on first call, required on second. Short English summary. Maximum length: ${EXPOSURE_LIMITS.summaryLength} characters.`,\n },\n enableScope: {\n type: 'string',\n enum: ['current', 'all'],\n description:\n 'Optional on first call, required on second. \"current\" for current agent only, \"all\" for all agents.',\n },\n },\n examples: [\n {\n name: 'Playwright',\n command: 'npx',\n args: ['@playwright/mcp@latest'],\n },\n {\n name: 'open-websearch',\n command: 'npx',\n args: ['-y', 'open-websearch@latest'],\n env: { MODE: 'stdio', DEFAULT_SEARCH_ENGINE: 'bing' },\n timeout: 30000,\n },\n {\n url: 'https://example.com/mcp',\n summary: 'Use this MCP for Linear issue and project operations.',\n enableScope: 'all',\n },\n {\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '/repo'],\n summary: 'Use this MCP for local filesystem operations.',\n enableScope: 'current',\n },\n ],\n },\n listInputSchema: buildGuideOnlyInputSchema(),\n },\n {\n name: 'skill:import',\n description: 'Call this to import a skill. Returns the import workflow and parameters.',\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: `Required. Path to a local directory containing SKILL.md. Maximum length: ${IMPORT_LIMITS.pathLength} characters.`,\n },\n },\n examples: [{ path: '/absolute/path/to/skill' }],\n },\n listInputSchema: buildGuideOnlyInputSchema(),\n },\n {\n name: 'listAllAaiApps',\n description:\n 'List all apps available to the current agent, excluding AAI Gateway built-in management tools.',\n inputSchema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n },\n {\n name: 'disableApp',\n description: 'Disable one app for the current agent only.',\n inputSchema: {\n type: 'object',\n properties: {\n app: {\n type: 'string',\n description: 'Required. The app id to disable for the current agent.',\n },\n },\n required: ['app'],\n },\n },\n {\n name: 'enableApp',\n description: 'Re-enable one app for the current agent only.',\n inputSchema: {\n type: 'object',\n properties: {\n app: {\n type: 'string',\n description: 'Required. The app id to re-enable for the current agent.',\n },\n },\n required: ['app'],\n },\n },\n {\n name: 'removeApp',\n description: 'Remove one AAI Gateway managed import from all agents.',\n inputSchema: {\n type: 'object',\n properties: {\n app: {\n type: 'string',\n description: 'Required. The imported app id to remove globally.',\n },\n confirm: {\n type: 'boolean',\n description:\n 'Required. Must be true only after the agent explains the global impact and the user explicitly confirms.',\n },\n },\n required: ['app', 'confirm'],\n },\n },\n {\n name: SEARCH_DISCOVER_TOOL_NAME,\n description:\n 'Call this to search for MCP servers or skills. Returns search instructions.',\n inputSchema: searchDiscoverInputSchema,\n listInputSchema: buildGuideOnlyInputSchema(),\n },\n ];\n}\n\nfunction buildGuideOnlyInputSchema(): Record<string, unknown> {\n return {\n type: 'object',\n properties: {},\n additionalProperties: false,\n };\n}\n\nexport function getGatewayToolDefinition(toolName: string): GatewayToolDefinition | undefined {\n return buildGatewayToolDefinitions().find((tool) => tool.name === toolName);\n}\n\nexport function isGatewayExecutionTool(toolName: string): boolean {\n return (\n toolName === 'mcp:import' ||\n toolName === 'skill:import' ||\n toolName === SEARCH_DISCOVER_TOOL_NAME ||\n toolName === 'listAllAaiApps' ||\n toolName === 'disableApp' ||\n toolName === 'enableApp' ||\n toolName === 'removeApp'\n );\n}\n\nexport function generateGatewayToolGuide(tool: GatewayToolDefinition): string {\n if (tool.name === 'mcp:import') {\n return generateMcpImportGuide(tool);\n }\n\n const examples = extractGuideExamples(tool.inputSchema, tool.name);\n return [\n `# ${tool.name}`,\n '',\n `This is only an operation guide for \\`${tool.name}\\`. To perform the actual operation, you must call \\`aai:exec\\`.`,\n '',\n 'The `aai:exec` tool accepts three parameters: `app`, `tool`, and `args`.',\n `For this operation, leave \\`app\\` empty, set \\`tool\\` to \"${tool.name}\", and refer to the examples below for \\`args\\`.`,\n '',\n ...(examples.length > 0\n ? [\n '',\n '## Examples',\n '',\n 'The examples below are complete `aai:exec` calls.',\n '',\n ...examples.flatMap((example) => [\n '```json',\n JSON.stringify(\n { tool: 'aai:exec', args: { tool: tool.name, args: example } },\n null,\n 2\n ),\n '```',\n '',\n ]),\n ]\n : []),\n ].join('\\n');\n}\n\nfunction generateMcpImportGuide(tool: GatewayToolDefinition): string {\n const inspectExample = {\n tool: 'aai:exec',\n args: {\n tool: 'mcp:import',\n args: {\n command: 'npx',\n args: ['-y', '@brave/brave-search-mcp-server'],\n timeout: 60000,\n name: 'brave-search',\n },\n },\n };\n\n const finalizeExample = {\n tool: 'aai:exec',\n args: {\n tool: 'mcp:import',\n args: {\n command: 'npx',\n args: ['-y', '@brave/brave-search-mcp-server'],\n timeout: 60000,\n name: 'brave-search',\n summary: 'Use this MCP for Brave web search.',\n enableScope: 'all',\n },\n },\n };\n\n const envFile = getDotenvPath();\n\n return [\n `# ${tool.name}`,\n '',\n 'This is only an operation guide for `mcp:import`. To perform the actual operation, you must call `aai:exec`.',\n '',\n 'The `aai:exec` tool accepts three parameters: `app`, `tool`, and `args`.',\n 'For this operation, leave `app` empty, set `tool` to `\"mcp:import\"`, and refer to the examples below for `args`.',\n '',\n '## Examples',\n '',\n 'Phase 1 — inspect:',\n '```json',\n JSON.stringify(inspectExample, null, 2),\n '```',\n '',\n 'Phase 2 — finalize import:',\n '```json',\n JSON.stringify(finalizeExample, null, 2),\n '```',\n '',\n '## Parameters',\n '',\n '### Local stdio MCP',\n '',\n '| Parameter | Type | Required | Description |',\n '|-----------|------|----------|-------------|',\n '| `command` | string | yes | The executable only, e.g. `\"npx\"`, `\"uvx\"`, `\"node\"` |',\n '| `args` | string[] | no | Arguments after the executable |',\n '| `env` | object | no | Environment variables as `{ \"KEY\": \"value\" }` pairs |',\n '| `timeout` | integer | no | Tool execution timeout in ms (default 60000) |',\n '| `cwd` | string | no | Working directory for the process |',\n '| `name` | string | no | Display name for the imported app |',\n '| `summary` | string | phase 2 | Short English description of when to use this MCP |',\n '| `enableScope` | `\"current\"` \\\\| `\"all\"` | phase 2 | Enable for current agent or all agents |',\n '',\n 'When converting from a standard MCP JSON config where `command` is an array:',\n '`[\"npx\", \"-y\", \"pkg\"]` → `command: \"npx\"`, `args: [\"-y\", \"pkg\"]`',\n '',\n '### Remote MCP',\n '',\n '| Parameter | Type | Required | Description |',\n '|-----------|------|----------|-------------|',\n '| `url` | string | yes | Remote MCP endpoint URL |',\n '| `transport` | string | no | `\"streamable-http\"` (default) or `\"sse\"` |',\n '| `headers` | object | no | HTTP headers (e.g. `{ \"Authorization\": \"${API_KEY}\" }`). Use `${VAR_NAME}` for secrets. |',\n '| `timeout` | integer | no | Tool execution timeout in ms (default 60000) |',\n '| `name` | string | no | Display name for the imported app |',\n '| `summary` | string | phase 2 | Short English description of when to use this MCP |',\n '| `enableScope` | `\"current\"` \\\\| `\"all\"` | phase 2 | Enable for current agent or all agents |',\n '',\n '## Notes',\n '',\n 'Phase 1 omits `summary` and `enableScope`.',\n 'Phase 2 repeats the same source config and adds `summary` and `enableScope`.',\n '',\n '## Environment variables & API keys',\n '',\n `\\`${envFile}\\` is a sensitive secrets file.`,\n 'Do not read, summarize, or repeat its contents.',\n 'Never ask the user to send API keys, tokens, or any other secret values in chat.',\n `Store sensitive values in \\`${envFile}\\` and reference them with \\${VAR_NAME} placeholders.`,\n '',\n 'If the import fails due to missing environment variables, follow the error instructions.',\n ].join('\\n');\n}\n\nfunction extractGuideExamples(\n inputSchema: Record<string, unknown>,\n toolName: string\n): Record<string, unknown>[] {\n const rawExamples = inputSchema.examples;\n if (Array.isArray(rawExamples) && rawExamples.length > 0) {\n return rawExamples\n .filter((value): value is Record<string, unknown> => !!value && typeof value === 'object')\n .slice(0, 2);\n }\n\n if (toolName === 'mcp:import') return [];\n if (toolName === 'listAllAaiApps') return [{}];\n return [];\n}\n","/**\n * App Registry\n *\n * Manages the registry of discovered and imported apps.\n */\n\nimport type { RuntimeAppRecord } from '../types/aai-json.js';\nimport { logger } from '../utils/logger.js';\n\nexport class AppRegistry {\n private registry = new Map<string, RuntimeAppRecord>();\n\n set(appId: string, record: RuntimeAppRecord): void {\n this.registry.set(appId, record);\n }\n\n get(appId: string): RuntimeAppRecord | undefined {\n return this.registry.get(appId);\n }\n\n has(appId: string): boolean {\n return this.registry.has(appId);\n }\n\n delete(appId: string): boolean {\n return this.registry.delete(appId);\n }\n\n getAll(): RuntimeAppRecord[] {\n return Array.from(this.registry.values());\n }\n\n values(): IterableIterator<RuntimeAppRecord> {\n return this.registry.values();\n }\n\n filter(predicate: (record: RuntimeAppRecord) => boolean): RuntimeAppRecord[] {\n return this.getAll().filter(predicate);\n }\n\n getByProtocol(protocol: string): RuntimeAppRecord[] {\n return this.filter((app) => app.descriptor.access.protocol === protocol);\n }\n\n get size(): number {\n return this.registry.size;\n }\n\n async loadFromDiscovery(discoveryFn: () => Promise<RuntimeAppRecord[]>): Promise<number> {\n try {\n const discoveredApps = await discoveryFn();\n for (const app of discoveredApps) {\n this.registry.set(app.appId, app);\n }\n logger.info({ count: discoveredApps.length }, 'App registry loaded from discovery');\n return discoveredApps.length;\n } catch (err) {\n logger.error({ err }, 'Failed to load app registry from discovery');\n throw err;\n }\n }\n}\n","export type LanguageTag = string;\n\nexport type InternationalizedName = {\n default: string;\n} & Record<LanguageTag, string>;\n\nexport interface CommandConfig {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\nexport interface McpStdioConfig extends CommandConfig {\n transport: 'stdio';\n timeout?: number;\n}\n\nexport interface McpRemoteConfig {\n transport: 'streamable-http' | 'sse';\n url: string;\n timeout?: number;\n headers?: Record<string, string>;\n}\n\nexport type McpConfig = McpStdioConfig | McpRemoteConfig;\n\nexport interface SkillPathConfig {\n path: string;\n url?: never;\n}\n\nexport interface SkillUrlConfig {\n url: string;\n path?: never;\n}\n\nexport type SkillConfig = SkillPathConfig | SkillUrlConfig;\n\nexport interface AcpAgentConfig extends CommandConfig {}\n\nexport interface CliConfig extends CommandConfig {}\n\nexport interface McpAccess {\n protocol: 'mcp';\n config: McpConfig;\n}\n\nexport interface SkillAccess {\n protocol: 'skill';\n config: SkillConfig;\n}\n\nexport interface AcpAgentAccess {\n protocol: 'acp-agent';\n config: AcpAgentConfig;\n}\n\nexport interface CliAccess {\n protocol: 'cli';\n config: CliConfig;\n}\n\nexport type Access = McpAccess | SkillAccess | AcpAgentAccess | CliAccess;\n\nexport interface Exposure {\n summary: string;\n keywords?: string[];\n}\n\nexport interface CommandDiscoveryCheck {\n kind: 'command';\n command: string;\n}\n\nexport interface FileDiscoveryCheck {\n kind: 'file';\n path: string;\n}\n\nexport interface PathDiscoveryCheck {\n kind: 'path';\n path: string;\n}\n\nexport type DiscoveryCheck =\n | CommandDiscoveryCheck\n | FileDiscoveryCheck\n | PathDiscoveryCheck;\n\nexport interface DiscoveryRule {\n checks: DiscoveryCheck[];\n}\n\nexport interface AaiJson {\n schemaVersion: '2.0';\n version: string;\n app: {\n name: InternationalizedName;\n iconUrl?: string;\n };\n discovery?: DiscoveryRule;\n access: Access;\n exposure: Exposure;\n}\n\nexport interface RuntimeAppRecord {\n appId: string;\n descriptor: AaiJson;\n source: 'desktop' | 'web' | 'mcp-import' | 'skill-import' | 'acp-agent' | 'cli';\n location?: string;\n toolSchemas?: Record<string, Record<string, unknown>>;\n}\n\nexport interface DetailedCapability {\n title: string;\n body: string;\n}\n\nexport function getLocalizedName(name: InternationalizedName, locale: LanguageTag): string {\n if (name[locale]) {\n return name[locale];\n }\n\n const family = locale.split('-')[0];\n const fallback = Object.keys(name).find((key) => key !== 'default' && key.startsWith(family));\n if (fallback && name[fallback]) {\n return name[fallback];\n }\n\n return name.default;\n}\n\nexport function isMcpAccess(access: Access): access is McpAccess {\n return access.protocol === 'mcp';\n}\n\nexport function isSkillAccess(access: Access): access is SkillAccess {\n return access.protocol === 'skill';\n}\n\nexport function isAcpAgentAccess(access: Access): access is AcpAgentAccess {\n return access.protocol === 'acp-agent';\n}\n\nexport function isCliAccess(access: Access): access is CliAccess {\n return access.protocol === 'cli';\n}\n\nexport function isSkillPathConfig(config: SkillConfig): config is SkillPathConfig {\n return 'path' in config;\n}\n\nexport function isMcpStdioConfig(config: McpConfig): config is McpStdioConfig {\n return config.transport === 'stdio';\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { AaiError } from '../errors/errors.js';\nimport { isSkillPathConfig } from '../types/aai-json.js';\nimport type {\n DetailedCapability,\n SkillConfig,\n SkillExecutorConfig,\n ExecutionResult,\n} from '../types/index.js';\nimport type { AppCapabilities } from '../types/capabilities.js';\n\nimport type { Executor } from './interface.js';\n\n/**\n * Skill Executor implementation\n *\n * Implements the unified Executor interface for skill-based apps.\n */\nexport class SkillExecutor implements Executor {\n readonly protocol = 'skill';\n\n async connect(_appId: string, _config: SkillConfig & SkillExecutorConfig): Promise<void> {\n // Skills don't maintain connections\n }\n\n async disconnect(_appId: string): Promise<void> {\n // Skills don't maintain connections\n }\n\n /**\n * Load app-level capabilities for skills\n * Skills have a single \"read\" tool for reading SKILL.md\n */\n async loadAppCapabilities(\n _appId: string,\n _config: SkillConfig & SkillExecutorConfig\n ): Promise<AppCapabilities> {\n return {\n title: 'Skill',\n tools: [\n {\n name: 'read',\n description: 'Read the skill documentation (SKILL.md)',\n inputSchema: { type: 'object' as const, properties: {} },\n },\n ],\n };\n }\n\n\n async execute(\n _appId: string,\n config: SkillConfig & SkillExecutorConfig,\n operation: string,\n args: Record<string, unknown>\n ): Promise<ExecutionResult> {\n try {\n if (operation !== 'read') {\n throw new AaiError(\n 'UNKNOWN_TOOL',\n `Skill-backed apps only support tool \"read\", got \"${operation}\"`\n );\n }\n\n const data = await this.readSkill(config, args);\n return { success: true, data };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n async health(_appId: string): Promise<boolean> {\n // Skills are always \"healthy\" as they don't maintain connections\n return true;\n }\n\n // Legacy methods for backward compatibility\n\n async loadSkillDetail(config: SkillConfig & SkillExecutorConfig): Promise<DetailedCapability> {\n const content = await readSkillMarkdown(config);\n return {\n title: 'Skill Details',\n body: content,\n };\n }\n\n async executeSkill(\n config: SkillConfig & SkillExecutorConfig,\n toolName: string,\n args: Record<string, unknown>\n ): Promise<string> {\n const result = await this.execute('', config, toolName, args);\n if (!result.success) {\n throw new AaiError('EXECUTION_ERROR', result.error ?? 'Execution failed');\n }\n return result.data as string;\n }\n\n private async readSkill(\n config: SkillConfig & SkillExecutorConfig,\n args: Record<string, unknown>\n ): Promise<string> {\n const content = await readSkillMarkdown(config);\n const section = typeof args.section === 'string' ? args.section.trim() : '';\n if (!section) {\n return content;\n }\n\n const marker = new RegExp(`^#+\\\\s+${escapeRegExp(section)}\\\\s*$`, 'im');\n const match = content.match(marker);\n if (match?.index === undefined) {\n return content;\n }\n\n return content.slice(match.index);\n }\n}\n\nasync function readSkillMarkdown(config: SkillConfig & SkillExecutorConfig): Promise<string> {\n if (isSkillPathConfig(config)) {\n return readFile(join(config.path, 'SKILL.md'), 'utf-8');\n }\n\n const response = await fetch(`${config.url.replace(/\\/$/, '')}/SKILL.md`);\n if (!response.ok) {\n throw new AaiError(\n 'SERVICE_UNAVAILABLE',\n `Failed to fetch remote skill: ${config.url} (${response.status})`\n );\n }\n return response.text();\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nlet singleton: SkillExecutor | undefined;\n\nexport function getSkillExecutor(): SkillExecutor {\n if (!singleton) {\n singleton = new SkillExecutor();\n }\n return singleton;\n}\n\n// Export legacy functions for backward compatibility\nexport const legacyLoadSkillDetail = (config: SkillConfig & SkillExecutorConfig) =>\n new SkillExecutor().loadSkillDetail(config);\nexport const legacyExecuteSkill = (\n config: SkillConfig & SkillExecutorConfig,\n toolName: string,\n args: Record<string, unknown>\n) => new SkillExecutor().executeSkill(config, toolName, args);\n","/**\n * Execution Coordinator\n *\n * Handles execution routing to appropriate executors\n * and inactivity timeout management.\n */\n\nimport type { AaiJson } from '../types/aai-json.js';\nimport { logger } from '../utils/logger.js';\nimport { getAcpExecutor } from '../executors/acp.js';\nimport { getMcpExecutor } from '../executors/mcp.js';\nimport { legacyExecuteSkill as executeSkill } from '../executors/skill.js';\nimport { getSkillExecutor } from '../executors/skill.js';\nimport type { Executor } from '../executors/interface.js';\nimport type { ExecutionObserver } from '../executors/events.js';\nimport { isAcpAgentAccess, isMcpAccess, isSkillAccess } from '../types/aai-json.js';\n\nconst DOWNSTREAM_INACTIVITY_TIMEOUT_MS = 10 * 60_000;\n\nexport interface ExecutionRequest {\n appId: string;\n toolName: string;\n args: Record<string, unknown>;\n}\n\nexport class ExecutionCoordinator {\n async execute(\n appId: string,\n descriptor: AaiJson,\n toolName: string,\n args: Record<string, unknown>,\n observer?: ExecutionObserver\n ): Promise<unknown> {\n const access = descriptor.access;\n\n if (isMcpAccess(access)) {\n const executor = getMcpExecutor();\n return executor.callTool({ appId, config: access.config }, toolName, args, observer);\n }\n\n if (isSkillAccess(access)) {\n return executeSkill(access.config as any, toolName, args);\n }\n\n if (isAcpAgentAccess(access)) {\n const executor = getAcpExecutor();\n if (observer && executor.executeWithObserver) {\n return executor.executeWithObserver(appId, access.config, toolName, args, observer);\n }\n return executor.execute(appId, access.config, toolName, args);\n }\n\n throw new Error(`Unsupported protocol ${JSON.stringify(access)}`);\n }\n\n async executeWithInactivityTimeout(\n appId: string,\n descriptor: AaiJson,\n toolName: string,\n args: Record<string, unknown>,\n observer?: ExecutionObserver\n ): Promise<unknown> {\n const timeoutMs = DOWNSTREAM_INACTIVITY_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n let completed = false;\n let timer: NodeJS.Timeout | undefined;\n\n const finish = (callback: () => void) => {\n if (completed) return;\n completed = true;\n if (timer) clearTimeout(timer);\n callback();\n };\n\n const scheduleTimeout = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n const error = new Error(\n `Downstream '${appId}' timed out after ${timeoutMs}ms without any activity`\n );\n void this.cleanupTimedOutExecution(appId, descriptor).finally(() => {\n finish(() => reject(error));\n });\n }, timeoutMs);\n };\n\n const activityObserver = this.wrapExecutionObserver(observer, scheduleTimeout);\n scheduleTimeout();\n\n this.execute(appId, descriptor, toolName, args, activityObserver).then(\n (result) => finish(() => resolve(result)),\n (error) => finish(() => reject(error))\n );\n });\n }\n\n getExecutor(protocol: string): Executor {\n switch (protocol) {\n case 'mcp':\n return getMcpExecutor();\n case 'skill':\n return getSkillExecutor();\n case 'acp-agent':\n return getAcpExecutor();\n default:\n throw new Error(`Protocol '${protocol}' does not support app capabilities`);\n }\n }\n\n private wrapExecutionObserver(\n observer: ExecutionObserver | undefined,\n onActivity: () => void\n ): ExecutionObserver {\n return {\n onMessage: async (event) => {\n onActivity();\n await observer?.onMessage?.(event);\n },\n onProgress: async (event) => {\n onActivity();\n await observer?.onProgress?.(event);\n },\n onTaskStatus: async (event) => {\n onActivity();\n await observer?.onTaskStatus?.(event);\n },\n };\n }\n\n private async cleanupTimedOutExecution(appId: string, descriptor: AaiJson): Promise<void> {\n const access = descriptor.access;\n try {\n if (isMcpAccess(access)) {\n await getMcpExecutor().close(appId);\n return;\n }\n if (isAcpAgentAccess(access)) {\n await getAcpExecutor().disconnect(appId);\n }\n } catch (err) {\n logger.warn({ appId, err }, 'Failed to clean up timed out downstream execution');\n }\n }\n}\n","import { execFileSync } from \"node:child_process\";\n\nexport type SupportedLocale = \"en\" | \"zh-CN\" | \"zh-TW\";\n\n/**\n * Get the system locale on macOS\n */\nexport function getSystemLocale(): SupportedLocale {\n try {\n // On macOS, use defaults to get the locale\n const output = execFileSync(\n \"defaults\",\n [\"read\", \"-g\", \"AppleLocale\"],\n { encoding: \"utf-8\", timeout: 1000 }\n ).trim();\n\n return normalizeLocale(output);\n } catch {\n // Fallback to environment variable\n const envLocale = process.env.LANG || process.env.LC_ALL || process.env.LC_MESSAGES || \"en\";\n return normalizeLocale(envLocale);\n }\n}\n\n/**\n * Normalize locale string to supported format\n */\nfunction normalizeLocale(locale: string): SupportedLocale {\n const lower = locale.toLowerCase().replace(/[^a-z-]/g, \"\");\n\n // Chinese variants\n if (lower.startsWith(\"zh-hans\") || lower === \"zh-cn\" || lower === \"zh_cn\") {\n return \"zh-CN\";\n }\n if (lower.startsWith(\"zh-hant\") || lower === \"zh-tw\" || lower === \"zh_tw\" || lower === \"zh-hk\" || lower === \"zh_hk\") {\n return \"zh-TW\";\n }\n if (lower.startsWith(\"zh\")) {\n return \"zh-CN\"; // Default to Simplified Chinese\n }\n\n // Default to English\n return \"en\";\n}\n","import type { AaiJson } from '../types/aai-json.js';\nimport type { AppCapabilities, ToolSchema } from '../types/capabilities.js';\nimport {\n getLocalizedName,\n isSkillAccess,\n isSkillPathConfig,\n type InternationalizedName,\n} from '../types/aai-json.js';\nimport { getSystemLocale } from '../utils/locale.js';\n\n// ============================================================================\n// Templates\n// ============================================================================\n\nconst TEMPLATE_GUIDE_TOOL_SUMMARY = `{{LOCALIZED_NAME}} — {{SUMMARY}} Call this to see available tools and usage.`;\n\nconst TEMPLATE_APP_GUIDE = `# {{LOCALIZED_NAME}}\n\n- App ID: {{LOCAL_ID}}\n- Summary: {{SUMMARY}}\n\n## Tools\n\n{{TOOLS}}\n\n{{EXAMPLES_SECTION}}{{NOTES_SECTION}}`;\n\nconst TEMPLATE_MCP_APP_GUIDE = `# {{LOCALIZED_NAME}}\n\nThis is only an operation guide for tools in this app. To perform the actual operation, you must call \\`aai:exec\\`.\n\nThe \\`aai:exec\\` tool accepts three parameters: \\`app\\`, \\`tool\\`, and \\`args\\`.\nFor this app, set \\`app\\` to \"{{LOCAL_ID}}\", set \\`tool\\` to one of the tool names below, and refer to the schema of the selected tool below for \\`args\\`.\n\n## Tools\n\n{{TOOLS}}`;\n\nconst TEMPLATE_ACP_APP_GUIDE = `# {{LOCALIZED_NAME}}\n\nThis is only an operation guide for tools in this app. To perform the actual operation, you must call \\`aai:exec\\`.\n\nThe \\`aai:exec\\` tool accepts three parameters: \\`app\\`, \\`tool\\`, and \\`args\\`.\nFor this app, set \\`app\\` to \"{{LOCAL_ID}}\", set \\`tool\\` to one of the tool names below, and use each tool's example below as the reference for \\`args\\`.\n\n## Tools\n\n{{TOOLS}}{{NOTES_SECTION}}`;\n\nconst TEMPLATE_TOOL_ITEM = `### {{NAME}}\n\n{{DESCRIPTION}}\n\n{{SCHEMA}}`;\n\nconst TEMPLATE_TOOL_ITEM_NO_SCHEMA = `### {{NAME}}\n\n{{DESCRIPTION}}`;\n\n// ============================================================================\n// Public Functions\n// ============================================================================\n\nexport function generateGuideToolSummary(_appId: string, descriptor: AaiJson): string {\n const localizedName = getEnglishName(descriptor.app.name);\n const params = {\n LOCALIZED_NAME: localizedName,\n SUMMARY: normalizeGuideToolSummary(descriptor.exposure.summary),\n };\n\n switch (descriptor.access.protocol) {\n case 'mcp':\n return renderTemplate(TEMPLATE_GUIDE_TOOL_SUMMARY, params);\n case 'skill':\n return renderTemplate(TEMPLATE_GUIDE_TOOL_SUMMARY, params);\n case 'cli':\n return renderTemplate(TEMPLATE_GUIDE_TOOL_SUMMARY, params);\n case 'acp-agent':\n return renderTemplate(TEMPLATE_GUIDE_TOOL_SUMMARY, params);\n }\n}\n\n/**\n * Generate app guide using the new AppCapabilities interface\n */\nexport function generateAppGuideMarkdown(\n appId: string,\n descriptor: AaiJson,\n capabilities: AppCapabilities\n): string {\n const protocol = descriptor.access.protocol;\n if (protocol === 'mcp') {\n return generateMcpAppGuideMarkdown(appId, descriptor, capabilities);\n }\n if (protocol === 'acp-agent') {\n return generateAcpAppGuideMarkdown(appId, descriptor, capabilities);\n }\n\n const locale = getSystemLocale();\n const localizedName = getLocalizedName(descriptor.app.name, locale);\n const toolsSection = buildToolsSection(capabilities);\n const examplesSection = buildExamplesSection(protocol, capabilities);\n const notesSection = buildNotesSection(protocol, descriptor);\n\n return renderTemplate(TEMPLATE_APP_GUIDE, {\n LOCALIZED_NAME: localizedName,\n LOCAL_ID: appId,\n SUMMARY: descriptor.exposure.summary,\n TOOLS: toolsSection,\n EXAMPLES_SECTION: examplesSection\n ? `\\n## Examples\\n\\nExecute via \\`aai:exec\\` with \\`app: \"${appId}\"\\`:\\n\\n${examplesSection}\\n`\n : '',\n NOTES_SECTION: notesSection ? `\\n## Notes\\n\\n${notesSection}\\n` : '',\n });\n}\n\nfunction generateMcpAppGuideMarkdown(\n appId: string,\n descriptor: AaiJson,\n capabilities: AppCapabilities\n): string {\n const locale = getSystemLocale();\n const localizedName = getLocalizedName(descriptor.app.name, locale);\n const toolsSection = buildToolsSection(capabilities);\n\n return renderTemplate(TEMPLATE_MCP_APP_GUIDE, {\n LOCALIZED_NAME: localizedName,\n LOCAL_ID: appId,\n TOOLS: toolsSection,\n });\n}\n\nfunction generateAcpAppGuideMarkdown(\n appId: string,\n descriptor: AaiJson,\n capabilities: AppCapabilities\n): string {\n const locale = getSystemLocale();\n const localizedName = getLocalizedName(descriptor.app.name, locale);\n const toolsSection = buildAcpToolsSection(appId, capabilities);\n const notesSection = buildNotesSection('acp-agent', descriptor);\n\n return renderTemplate(TEMPLATE_ACP_APP_GUIDE, {\n LOCALIZED_NAME: localizedName,\n LOCAL_ID: appId,\n TOOLS: toolsSection,\n NOTES_SECTION: notesSection ? `\\n\\n## Notes\\n\\n${notesSection}\\n` : '',\n });\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction buildToolsSection(\n capabilities: AppCapabilities,\n options: { includeSchema?: boolean } = {}\n): string {\n if (capabilities.tools.length === 0) {\n return 'No tools available.';\n }\n\n const includeSchema = options.includeSchema ?? true;\n return capabilities.tools\n .map((tool) => {\n const desc = tool.description?.trim();\n const shortDesc = desc ? truncateDescription(desc) : 'No description provided.';\n return renderTemplate(includeSchema ? TEMPLATE_TOOL_ITEM : TEMPLATE_TOOL_ITEM_NO_SCHEMA, {\n NAME: tool.name,\n DESCRIPTION: shortDesc,\n SCHEMA: includeSchema ? formatToolSchema(tool) : '',\n });\n })\n .join('\\n');\n}\n\nfunction formatToolSchema(tool: ToolSchema): string {\n const schema: Record<string, unknown> = { inputSchema: tool.inputSchema };\n if (tool.outputSchema) {\n schema.outputSchema = tool.outputSchema;\n }\n return ['```json', JSON.stringify(schema, null, 2), '```'].join('\\n');\n}\n\nfunction truncateDescription(desc: string): string {\n const firstSentence = desc.split(/(?<=[.!?])\\s/)[0];\n return firstSentence.length <= 120 ? firstSentence : `${firstSentence.slice(0, 117)}...`;\n}\n\nfunction buildExamplesSection(protocol: string, capabilities: AppCapabilities): string {\n switch (protocol) {\n case 'mcp':\n return '';\n\n case 'acp-agent':\n return '';\n\n case 'skill':\n return buildSkillExamples(capabilities);\n\n case 'cli':\n return buildCliExamples(capabilities);\n\n default:\n return '';\n }\n}\n\nfunction buildNotesSection(protocol: string, descriptor: AaiJson): string {\n switch (protocol) {\n case 'acp-agent':\n return 'session/new returns promptCapabilities. turn/start.prompt must match those capabilities.';\n case 'skill':\n return [\n 'Execute via `aai:exec` with the app id above.',\n buildSkillDirSection(descriptor),\n ].join('\\n');\n case 'cli':\n return 'Pass args.argv as a string array and args.stdin as optional text.';\n default:\n return '';\n }\n}\n\nfunction buildSkillDirSection(descriptor: AaiJson): string {\n if (isSkillAccess(descriptor.access) && isSkillPathConfig(descriptor.access.config)) {\n return `AAI Gateway managed skill directory: \\`${descriptor.access.config.path}\\`.`;\n }\n return 'AAI Gateway managed skill directory: use the local skill path configured for this imported skill.';\n}\n\nfunction buildAcpToolsSection(appId: string, capabilities: AppCapabilities): string {\n if (capabilities.tools.length === 0) {\n return 'No tools available.';\n }\n\n return capabilities.tools\n .map((tool) => {\n const desc = tool.description?.trim();\n const shortDesc = desc ? truncateDescription(desc) : 'No description provided.';\n const example = buildAcpExample(tool.name, appId);\n\n return [\n `### ${tool.name}`,\n '',\n shortDesc,\n '',\n 'args:',\n '',\n example ? JSON.stringify(example, null, 2) : 'No example available.',\n ].join('\\n');\n })\n .join('\\n\\n');\n}\n\nfunction buildSkillExamples(capabilities: AppCapabilities): string {\n if (!capabilities.tools.some((tool) => tool.name === 'read')) {\n return '';\n }\n\n return renderExampleJson({\n tool: 'read',\n args: {},\n });\n}\n\nfunction buildCliExamples(capabilities: AppCapabilities): string {\n const primaryTool = capabilities.tools.find((tool) => tool.name === 'run')?.name ?? 'run';\n return renderExampleJson({\n tool: primaryTool,\n args: {\n argv: ['--help'],\n },\n });\n}\n\nfunction buildAcpExample(toolName: string, appId: string): Record<string, unknown> | null {\n switch (toolName) {\n case 'session/new':\n return {\n app: appId,\n tool: 'session/new',\n args: {\n cwd: '/absolute/path/to/project',\n },\n };\n case 'turn/start':\n return {\n app: appId,\n tool: 'turn/start',\n args: {\n sessionId: '<sessionId>',\n prompt: [{ type: 'text', text: 'Summarize the current project.' }],\n },\n };\n case 'turn/poll':\n return {\n app: appId,\n tool: 'turn/poll',\n args: {\n turnId: '<turnId>',\n },\n };\n case 'turn/respondPermission':\n return {\n app: appId,\n tool: 'turn/respondPermission',\n args: {\n turnId: '<turnId>',\n permissionId: '<permissionId>',\n decision: {\n type: 'select',\n optionId: '<optionId>',\n },\n },\n };\n case 'turn/cancel':\n return {\n app: appId,\n tool: 'turn/cancel',\n args: {\n turnId: '<turnId>',\n },\n };\n default:\n return null;\n }\n}\n\nfunction renderExampleJson(payload: Record<string, unknown>): string {\n return ['```json', JSON.stringify(payload, null, 2), '```'].join('\\n');\n}\n\nfunction normalizeGuideToolSummary(summary: string): string {\n return summary.trim().replace(/\\s+/g, ' ');\n}\n\nfunction getEnglishName(name: InternationalizedName): string {\n return name.en ?? name['en-US'] ?? name.default;\n}\n\n// ============================================================================\n// Simple Template Engine\n// ============================================================================\n\ninterface TemplateVars {\n [key: string]: string | number | boolean | undefined;\n}\n\n/**\n * Simple template renderer supporting {{variable}} and {{#if}}...{{/if}} blocks.\n */\nfunction renderTemplate(template: string, vars: TemplateVars): string {\n let output = template;\n\n // Handle if blocks: {{#if VAR}}...{{/if}}\n output = output.replace(/\\{\\{#if (\\w+)\\}\\}([\\s\\S]*?)\\{\\{\\/if\\}\\}/g, (_, varName, content) => {\n const value = vars[varName];\n if (value && value !== 'false' && value !== '0') {\n return content;\n }\n return '';\n });\n\n // Handle variable replacement\n output = output.replace(/\\{\\{(\\w+)\\}\\}/g, (_, varName) => {\n const value = vars[varName];\n return value !== undefined ? String(value) : '';\n });\n\n return output;\n}\n","/**\n * Guide Service\n *\n * Handles generation of guides and tool summaries.\n */\n\nimport type { AaiJson, RuntimeAppRecord } from '../types/aai-json.js';\nimport type { AppCapabilities } from '../types/capabilities.js';\nimport {\n generateAppGuideMarkdown,\n generateGuideToolSummary,\n} from '../guides/app-guide-generator.js';\n\nexport class GuideService {\n generateAppGuide(appId: string, descriptor: AaiJson, capabilities: AppCapabilities): string {\n return generateAppGuideMarkdown(appId, descriptor, capabilities);\n }\n\n generateToolSummary(appId: string, descriptor: AaiJson): string {\n return generateGuideToolSummary(appId, descriptor);\n }\n\n buildToolListForCaller(\n apps: RuntimeAppRecord[],\n gatewayToolDefinitions: Array<{\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n listInputSchema?: Record<string, unknown>;\n }>\n ): Array<{\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n }> {\n return [\n ...apps.map((app) => ({\n name: `app:${app.appId}`,\n description: this.generateToolSummary(app.appId, app.descriptor),\n inputSchema: { type: 'object', properties: {} },\n })),\n ...gatewayToolDefinitions.map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.listInputSchema ?? tool.inputSchema,\n })),\n ];\n }\n}\n","/**\n * Import Service\n *\n * Handles MCP server and skill import logic.\n */\n\nimport type { AaiJson, McpConfig, RuntimeAppRecord } from '../types/aai-json.js';\nimport { getMcpExecutor } from '../executors/mcp.js';\nimport { importMcpServer, importSkill } from './importer.js';\nimport {\n deleteAppPolicyState,\n removeAppFromAllAgents,\n saveAppPolicyState,\n} from '../storage/agent-state.js';\nimport { getSkillRegistry } from '../storage/skill-registry.js';\nimport { getManagedAppDir } from '../storage/paths.js';\nimport { rm } from 'node:fs/promises';\nimport type { CallerContext } from '../types/caller.js';\n\nexport interface ImportResult {\n appId: string;\n descriptor: AaiJson;\n managedPath: string;\n tools: Array<{ name: string; description?: string; inputSchema?: Record<string, unknown> }>;\n}\n\nexport class ImportService {\n constructor(\n private readonly appRegistry: {\n set(appId: string, record: RuntimeAppRecord): void;\n delete(appId: string): boolean;\n }\n ) {}\n\n async importMcp(\n options: {\n name?: string;\n config: McpConfig;\n summary: string;\n enableScope: 'current' | 'all';\n },\n caller: CallerContext\n ): Promise<ImportResult> {\n const result = await importMcpServer(getMcpExecutor(), {\n name: options.name,\n config: options.config,\n summary: options.summary,\n });\n\n await saveAppPolicyState(result.entry.appId, {\n defaultEnabled: options.enableScope === 'current' ? 'importer-only' : 'all',\n importerAgentId: caller.id,\n updatedAt: new Date().toISOString(),\n });\n\n this.appRegistry.set(result.entry.appId, {\n appId: result.entry.appId,\n descriptor: result.descriptor,\n source: 'mcp-import',\n location: result.entry.descriptorPath,\n });\n\n return {\n appId: result.entry.appId,\n descriptor: result.descriptor,\n managedPath: result.entry.descriptorPath,\n tools: result.tools,\n };\n }\n\n async importSkill(\n options: { path: string },\n caller: CallerContext\n ): Promise<ImportResult> {\n const result = await importSkill({ path: options.path });\n\n await saveAppPolicyState(result.appId, {\n defaultEnabled: 'importer-only',\n importerAgentId: caller.id,\n updatedAt: new Date().toISOString(),\n });\n\n this.appRegistry.set(result.appId, {\n appId: result.appId,\n descriptor: result.descriptor,\n source: 'skill-import',\n location: result.managedPath,\n });\n\n return {\n appId: result.appId,\n descriptor: result.descriptor,\n managedPath: result.managedPath,\n tools: [],\n };\n }\n\n async removeApp(appId: string): Promise<void> {\n const { getMcpRegistry } = await import('../storage/mcp-registry.js');\n const registry = getMcpRegistry();\n\n const mcpEntry = await registry.get(appId);\n if (mcpEntry) {\n await registry.delete(appId);\n } else {\n await getSkillRegistry().delete(appId);\n }\n\n await deleteAppPolicyState(appId);\n await removeAppFromAllAgents(appId);\n await rm(getManagedAppDir(appId), { recursive: true, force: true });\n }\n}\n","import type { AaiJson } from '../../types/aai-json.js';\n\nexport const appId = 'claude';\n\nexport const descriptor: AaiJson = {\n schemaVersion: '2.0',\n version: '1.0.0',\n app: {\n name: {\n default: 'Claude Code',\n en: 'Claude Code',\n 'zh-CN': 'Claude Code',\n },\n },\n discovery: {\n checks: [\n { kind: 'command', command: 'npx' },\n { kind: 'command', command: 'claude' },\n ],\n },\n access: {\n protocol: 'acp-agent',\n config: {\n command: 'npx',\n args: ['-y', '@zed-industries/claude-agent-acp'],\n },\n },\n exposure: {\n summary: 'AI assistant for code editing, analysis, and development tasks.',\n },\n};\n","import type { AaiJson } from '../../types/aai-json.js';\n\nexport const appId = 'codex';\n\nexport const descriptor: AaiJson = {\n schemaVersion: '2.0',\n version: '1.0.0',\n app: {\n name: {\n default: 'Codex',\n en: 'Codex',\n 'zh-CN': 'Codex',\n },\n },\n discovery: {\n checks: [\n { kind: 'command', command: 'npx' },\n { kind: 'command', command: 'codex' },\n ],\n },\n access: {\n protocol: 'acp-agent',\n config: {\n command: 'npx',\n args: ['-y', '@zed-industries/codex-acp'],\n },\n },\n exposure: {\n summary: 'AI assistant powered by OpenAI for code generation and editing tasks.',\n },\n};\n","import type { AaiJson } from '../../types/aai-json.js';\n\nexport const appId = 'opencode';\n\nexport const descriptor: AaiJson = {\n schemaVersion: '2.0',\n version: '1.0.0',\n app: {\n name: {\n default: 'OpenCode',\n en: 'OpenCode',\n 'zh-CN': 'OpenCode',\n },\n },\n discovery: {\n checks: [{ kind: 'command', command: 'opencode' }],\n },\n access: {\n protocol: 'acp-agent',\n config: {\n command: 'opencode',\n args: ['acp'],\n },\n },\n exposure: {\n summary: 'AI assistant for editing files, running commands, and automating development tasks.',\n },\n};\n","/**\n * Seed Pre-built Descriptors\n *\n * Writes pre-built ACP agent descriptors into the managed apps directory\n * on every startup (always overwrites to ensure latest version).\n */\n\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport type { AaiJson } from '../types/aai-json.js';\nimport { getManagedAppDir } from '../storage/paths.js';\nimport { logger } from '../utils/logger.js';\n\ninterface PrebuiltDescriptor {\n appId: string;\n descriptor: AaiJson;\n}\n\nasync function loadPrebuiltDescriptors(): Promise<PrebuiltDescriptor[]> {\n const modules = import.meta.glob('../discovery/descriptors/*-agent.ts', { eager: true });\n const descriptors: PrebuiltDescriptor[] = [];\n\n for (const [path, mod] of Object.entries(modules)) {\n const module = mod as { appId?: string; descriptor?: AaiJson };\n if (module.appId && module.descriptor) {\n descriptors.push({ appId: module.appId, descriptor: module.descriptor });\n } else {\n logger.warn({ path }, 'Pre-built descriptor module missing appId or descriptor export');\n }\n }\n\n return descriptors;\n}\n\nexport async function seedPrebuiltDescriptors(): Promise<number> {\n const descriptors = await loadPrebuiltDescriptors();\n let seeded = 0;\n\n for (const { appId, descriptor } of descriptors) {\n try {\n const appDir = getManagedAppDir(appId);\n await mkdir(appDir, { recursive: true });\n await writeFile(\n join(appDir, 'aai.json'),\n JSON.stringify(descriptor, null, 2),\n 'utf-8'\n );\n seeded++;\n logger.debug({ appId }, 'Pre-built descriptor seeded');\n } catch (err) {\n logger.error({ appId, err }, 'Failed to seed pre-built descriptor');\n }\n }\n\n logger.info({ count: seeded }, 'Pre-built descriptors seeded');\n return seeded;\n}\n","/**\n * Background Task Framework\n *\n * Provides a unified interface for background tasks that run during AAI Gateway lifetime.\n * Tasks can:\n * - Run once at startup (potentially with dependencies on other tasks)\n * - Run periodically at a specified interval\n * - Be gracefully stopped\n */\n\nimport { logger } from '../../utils/logger.js';\n\nexport interface BackgroundTask {\n readonly name: string;\n readonly dependencies?: string[];\n start(): Promise<void>;\n stop(): void;\n}\n\nexport class BackgroundTaskManager {\n private tasks = new Map<string, BackgroundTask>();\n private intervals = new Map<string, NodeJS.Timeout>();\n private started = false;\n\n register(task: BackgroundTask): void {\n if (this.tasks.has(task.name)) {\n logger.warn({ task: task.name }, 'Background task already registered, skipping');\n return;\n }\n this.tasks.set(task.name, task);\n logger.debug(\n { task: task.name, dependencies: task.dependencies },\n 'Background task registered'\n );\n }\n\n async startAll(): Promise<void> {\n if (this.started) {\n logger.warn('Background task manager already started');\n return;\n }\n this.started = true;\n\n const executionOrder = this.resolveDependencies();\n logger.info({ count: this.tasks.size, order: executionOrder }, 'Starting all background tasks');\n\n for (const name of executionOrder) {\n const task = this.tasks.get(name);\n if (!task) {\n continue;\n }\n\n try {\n await task.start();\n logger.info({ task: name }, 'Background task started');\n } catch (err) {\n logger.error({ task: name, err }, 'Background task failed to start');\n }\n }\n }\n\n private resolveDependencies(): string[] {\n const visited = new Set<string>();\n const result: string[] = [];\n\n const visit = (name: string) => {\n if (visited.has(name)) {\n return;\n }\n visited.add(name);\n\n const task = this.tasks.get(name);\n if (task?.dependencies) {\n for (const dep of task.dependencies) {\n if (this.tasks.has(dep)) {\n visit(dep);\n }\n }\n }\n\n result.push(name);\n };\n\n for (const name of this.tasks.keys()) {\n visit(name);\n }\n\n return result;\n }\n\n stopAll(): void {\n if (!this.started) {\n return;\n }\n\n logger.info({ count: this.tasks.size }, 'Stopping all background tasks');\n\n for (const [, interval] of this.intervals) {\n clearInterval(interval);\n }\n this.intervals.clear();\n\n for (const [name, task] of this.tasks) {\n try {\n task.stop();\n logger.debug({ task: name }, 'Background task stopped');\n } catch (err) {\n logger.error({ task: name, err }, 'Background task failed to stop');\n }\n }\n\n this.started = false;\n logger.info('All background tasks stopped');\n }\n\n schedulePeriodic(taskName: string, intervalMs: number, fn: () => void): void {\n const existing = this.intervals.get(taskName);\n if (existing) {\n clearInterval(existing);\n }\n\n const interval = setInterval(() => {\n try {\n fn();\n } catch (err) {\n logger.error({ task: taskName, err }, 'Background task periodic run failed');\n }\n }, intervalMs);\n\n this.intervals.set(taskName, interval);\n logger.debug({ task: taskName, intervalMs }, 'Background task scheduled for periodic run');\n }\n}\n","/**\n * ACP Pre-warm Background Task\n *\n * Pre-initializes all discovered ACP agents so the first prompt doesn't pay\n * the full initialization + session-creation penalty.\n *\n * Depends on: discovery\n */\n\nimport { logger } from '../../utils/logger.js';\nimport type { BackgroundTask } from './task-manager.js';\nimport type { AppRegistry } from '../app-registry.js';\n\nexport class AcpPrewarmBackgroundTask implements BackgroundTask {\n readonly name = 'acp-prewarm';\n readonly dependencies: string[] = [];\n\n constructor(private readonly appRegistry: AppRegistry) {}\n\n async start(): Promise<void> {\n const acpApps = this.appRegistry.getByProtocol('acp-agent');\n\n if (acpApps.length === 0) {\n logger.debug('No ACP agents to pre-warm');\n return;\n }\n\n logger.info({ count: acpApps.length }, 'Pre-warming ACP agents');\n\n for (const app of acpApps) {\n const { getAcpExecutor } = await import('../../executors/acp.js');\n const config = app.descriptor.access.config as import('../../types/index.js').AcpAgentConfig;\n void getAcpExecutor()\n .connect(app.appId, config)\n .then(() => {\n logger.info({ appId: app.appId }, 'ACP agent pre-warm completed');\n })\n .catch((err) => {\n logger.warn({ appId: app.appId, err }, 'ACP agent pre-warm failed (will retry lazily)');\n });\n }\n }\n\n stop(): void {}\n}\n","/**\n * Turn Cleanup Background Task\n *\n * Cleans up turns that were finished but not polled by clients.\n * Runs periodically to remove turns older than the retention period.\n */\n\nimport { getAcpExecutor } from '../../executors/acp.js';\nimport { logger } from '../../utils/logger.js';\nimport type { BackgroundTask } from './task-manager.js';\n\nconst TURN_RETENTION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\nconst CLEANUP_INTERVAL_MS = 60 * 60 * 1000; // 1 hour\n\nexport class TurnCleanupTask implements BackgroundTask {\n readonly name = 'turn-cleanup';\n\n async start(): Promise<void> {\n logger.info(\n {\n retentionDays: TURN_RETENTION_MS / (24 * 60 * 60 * 1000),\n intervalHours: CLEANUP_INTERVAL_MS / (60 * 60 * 1000),\n },\n 'Turn cleanup task starting'\n );\n\n // Run immediately on start\n this.run();\n\n // Then run periodically\n const executor = getAcpExecutor();\n if ('scheduleTurnCleanup' in executor && typeof executor.scheduleTurnCleanup === 'function') {\n executor.scheduleTurnCleanup(CLEANUP_INTERVAL_MS, TURN_RETENTION_MS);\n }\n }\n\n stop(): void {\n const executor = getAcpExecutor();\n if (\n 'unscheduleTurnCleanup' in executor &&\n typeof executor.unscheduleTurnCleanup === 'function'\n ) {\n executor.unscheduleTurnCleanup();\n }\n logger.info({ task: this.name }, 'Turn cleanup task stopped');\n }\n\n private run(): void {\n try {\n const executor = getAcpExecutor();\n if (\n 'cleanupFinishedTurns' in executor &&\n typeof executor.cleanupFinishedTurns === 'function'\n ) {\n const cleaned = executor.cleanupFinishedTurns(TURN_RETENTION_MS);\n if (cleaned > 0) {\n logger.info({ task: this.name, cleanedTurns: cleaned }, 'Turn cleanup completed');\n }\n }\n } catch (err) {\n logger.error({ task: this.name, err }, 'Turn cleanup run failed');\n }\n }\n}\n","/**\n * Gateway — Core Business Logic\n *\n * Handles all AAI Gateway operations: app resolution, import,\n * enable/disable, guide generation, and tool execution.\n * Protocol-agnostic — does not depend on MCP types.\n */\n\nimport type { RuntimeAppRecord } from '../types/aai-json.js';\nimport { logger } from '../utils/logger.js';\nimport { AaiError } from '../errors/errors.js';\nimport { getMcpExecutor } from '../executors/mcp.js';\nimport { loadManagedDescriptors } from '../storage/managed-registry.js';\nimport {\n disableAppForAgent,\n enableAppForAgent,\n loadAppPolicyState,\n upsertAgentState,\n} from '../storage/agent-state.js';\nimport { getDotenvPath } from '../utils/dotenv.js';\nimport { discoverMcpImport, EXPOSURE_LIMITS } from './importer.js';\nimport {\n SEARCH_DISCOVER_TOOL_NAME,\n buildSearchDiscoverResponse,\n parseSearchDiscoverArguments,\n} from './search-guidance.js';\nimport type { ParsedMcpImportArgs, ParsedSkillImportArgs } from './parsers.js';\nimport {\n parseMcpImportArguments,\n parseSkillImportArguments,\n summarizeMcpImportRequest,\n summarizeSkillImportRequest,\n summarizeRawImportArgs,\n summarizeExecArgs,\n summarizeExecResult,\n} from './parsers.js';\nimport type { CallerContext } from '../types/caller.js';\nimport {\n buildGatewayToolDefinitions,\n getGatewayToolDefinition,\n generateGatewayToolGuide,\n isGatewayExecutionTool,\n type GatewayToolDefinition,\n} from './tool-definitions.js';\nimport { AppRegistry } from './app-registry.js';\nimport { ExecutionCoordinator } from './execution-coordinator.js';\nimport { GuideService } from './guide-service.js';\nimport { ImportService } from './import-service.js';\nimport { seedPrebuiltDescriptors } from './seed.js';\nimport { BackgroundTaskManager } from './background/task-manager.js';\nimport { AcpPrewarmBackgroundTask } from './background/acp-prewarm-task.js';\nimport { TurnCleanupTask } from './background/turn-cleanup.js';\nimport { deriveCallerId } from '../storage/agent-state.js';\n\n// ============================================================\n// Result types (protocol-agnostic)\n// ============================================================\n\nexport interface GatewayTextResult {\n text: string;\n isError?: boolean;\n structuredContent?: Record<string, unknown>;\n}\n\nexport interface GatewayToolInfo {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n}\n\n// ============================================================\n// Gateway class\n// ============================================================\n\nexport class Gateway {\n private readonly appRegistry = new AppRegistry();\n private readonly guideService = new GuideService();\n private executionCoordinator!: ExecutionCoordinator;\n private importService!: ImportService;\n private readonly backgroundTasks = new BackgroundTaskManager();\n\n async initialize(): Promise<void> {\n this.executionCoordinator = new ExecutionCoordinator();\n this.importService = new ImportService(this.appRegistry);\n\n // Seed pre-built descriptors (always overwrite)\n await seedPrebuiltDescriptors();\n\n // Load all managed descriptors (imports + seeded)\n await this.appRegistry.loadFromDiscovery(() => loadManagedDescriptors());\n\n // Start background tasks\n this.backgroundTasks.register(new AcpPrewarmBackgroundTask(this.appRegistry));\n this.backgroundTasks.register(new TurnCleanupTask());\n await this.backgroundTasks.startAll();\n }\n\n // ============================================================\n // Caller identity\n // ============================================================\n\n createCallerContext(clientVersion: { name?: string; version?: string } | undefined): CallerContext {\n const name = clientVersion?.name?.trim() || 'Unknown Client';\n return {\n id: deriveCallerId({ callerName: name }),\n name,\n version: clientVersion?.version,\n transport: 'mcp',\n type: 'unknown',\n };\n }\n\n // ============================================================\n // Tool listing\n // ============================================================\n\n async listTools(caller: CallerContext): Promise<GatewayToolInfo[]> {\n const visibleApps = await this.listVisibleApps(caller);\n return [\n ...visibleApps.map((app) => ({\n name: `app:${app.appId}`,\n description: this.guideService.generateToolSummary(app.appId, app.descriptor),\n inputSchema: { type: 'object' as const, properties: {} },\n })),\n ...buildGatewayToolDefinitions().map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.listInputSchema ?? tool.inputSchema,\n })),\n ];\n }\n\n getGatewayToolDefinition(name: string): GatewayToolDefinition | undefined {\n return getGatewayToolDefinition(name);\n }\n\n // ============================================================\n // App guide\n // ============================================================\n\n async handleAppGuide(appId: string, caller: CallerContext): Promise<GatewayTextResult> {\n const result = await this.resolveManagedApp(appId, caller);\n if (!result) {\n throw new AaiError('UNKNOWN_APP', `App not found: ${appId}`);\n }\n if ('disabled' in result) {\n throw new AaiError(\n 'UNKNOWN_APP',\n `App \"${appId}\" is currently disabled for this agent. To enable it, call the enableApp tool with app: \"${appId}\". Please present this message to the user in their preferred language.`\n );\n }\n\n const { descriptor } = result.app;\n const access = descriptor.access;\n const executor = this.executionCoordinator.getExecutor(access.protocol);\n const capabilities = await executor.loadAppCapabilities(appId, access.config as any);\n\n return {\n text: this.guideService.generateAppGuide(appId, descriptor, capabilities),\n };\n }\n\n // ============================================================\n // Gateway tool guide (mcp:import, skill:import)\n // ============================================================\n\n handleGatewayToolGuide(toolName: string): GatewayTextResult {\n const tool = getGatewayToolDefinition(toolName);\n if (!tool) {\n throw new AaiError('UNKNOWN_TOOL', `Unknown tool: ${toolName}`);\n }\n return { text: generateGatewayToolGuide(tool) };\n }\n\n // ============================================================\n // Exec\n // ============================================================\n\n async handleExec(\n requestId: string | number,\n appIdOrUrl: string | undefined,\n toolName: string,\n args: Record<string, unknown>,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n if (!appIdOrUrl || appIdOrUrl === 'gateway') {\n if (isGatewayExecutionTool(toolName)) {\n return this.executeGatewayTool(toolName, args, caller);\n }\n throw new AaiError('INVALID_REQUEST', \"aai:exec requires 'app' for app tools\");\n }\n\n const resolved = await this.resolveApp(appIdOrUrl, caller);\n const startedAt = Date.now();\n\n logger.info(\n {\n requestId,\n app: resolved.appId,\n protocol: resolved.descriptor.access.protocol,\n tool: toolName,\n args: summarizeExecArgs(args),\n },\n 'aai:exec received'\n );\n\n try {\n const result = await this.executionCoordinator.executeWithInactivityTimeout(\n resolved.appId,\n resolved.descriptor,\n toolName,\n args\n );\n logger.info(\n {\n requestId,\n app: resolved.appId,\n protocol: resolved.descriptor.access.protocol,\n tool: toolName,\n durationMs: Date.now() - startedAt,\n result: summarizeExecResult(result),\n },\n 'aai:exec completed'\n );\n return this.toTextResult(result);\n } catch (err) {\n logger.error(\n {\n requestId,\n app: resolved.appId,\n protocol: resolved.descriptor.access.protocol,\n tool: toolName,\n durationMs: Date.now() - startedAt,\n err,\n },\n 'aai:exec failed'\n );\n throw err;\n }\n }\n\n // ============================================================\n // MCP Import\n // ============================================================\n\n async handleMcpImport(\n options: ParsedMcpImportArgs,\n rawArgs: Record<string, unknown> | undefined,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n try {\n logger.info(\n {\n tool: 'mcp:import',\n phase: options.metadata ? 'import' : 'inspect',\n request: summarizeMcpImportRequest(options),\n },\n 'MCP import request started'\n );\n\n if (!options.metadata) {\n const preview = await discoverMcpImport(getMcpExecutor(), {\n name: options.name,\n config: options.config,\n });\n\n logger.info(\n {\n tool: 'mcp:import',\n phase: 'inspect',\n appId: preview.appId,\n appName: preview.name,\n toolCount: preview.tools.length,\n },\n 'MCP import inspection completed'\n );\n\n return {\n text: [\n 'MCP inspection completed. No import record has been created yet.',\n `App name: ${preview.name}`,\n '',\n 'Available tools:',\n formatToolPreview(preview.tools),\n '',\n 'Next step:',\n '1. Summarize when this MCP should be used.',\n `2. Confirm a summary (in English, max ${EXPOSURE_LIMITS.summaryLength} chars) with the user. Communicate in the user\\'s preferred language, but the actual summary value must be English.`,\n '3. Ask the user whether this imported MCP should be enabled only for the current agent or for all agents.',\n '4. Call `mcp:import` again with the same source config plus `summary` and `enableScope`.',\n ].join('\\n'),\n };\n }\n\n const result = await this.importService.importMcp(\n {\n name: options.name,\n config: options.config,\n summary: options.metadata.summary,\n enableScope: options.metadata.enableScope,\n },\n caller\n );\n\n logger.info(\n {\n tool: 'mcp:import',\n phase: 'import',\n appId: result.appId,\n descriptorPath: result.managedPath,\n toolCount: result.tools.length,\n },\n 'MCP import completed'\n );\n\n const capabilities = {\n title: 'MCP Tools',\n tools: result.tools.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n inputSchema: t.inputSchema ?? { type: 'object' as const, properties: {} },\n })),\n };\n\n return {\n text: [\n `Imported MCP app: ${result.descriptor.app.name.default}`,\n `App ID: ${result.appId}`,\n `App tool prefix: app:${result.appId}`,\n `Descriptor: ${result.managedPath}`,\n `Summary: ${result.descriptor.exposure.summary}`,\n `Default enabled for: ${options.metadata.enableScope === 'current' ? 'importing agent only' : 'all agents'}`,\n '',\n this.guideService.generateAppGuide(result.appId, result.descriptor, capabilities),\n ].join('\\n'),\n };\n } catch (err) {\n logger.error(\n { tool: 'mcp:import', request: summarizeRawImportArgs(rawArgs), err },\n 'MCP import failed'\n );\n\n if (isMissingEnvVarsError(err)) {\n return buildMissingEnvVarsResult(err);\n }\n\n return createErrorResult('MCP import failed.', err);\n }\n }\n\n // ============================================================\n // Skill Import\n // ============================================================\n\n async handleSkillImport(\n options: ParsedSkillImportArgs,\n rawArgs: Record<string, unknown> | undefined,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n try {\n logger.info(\n {\n tool: 'skill:import',\n phase: 'import',\n request: summarizeSkillImportRequest(options),\n },\n 'Skill import request started'\n );\n\n const result = await this.importService.importSkill({ path: options.path }, caller);\n\n logger.info(\n {\n tool: 'skill:import',\n phase: 'import',\n appId: result.appId,\n managedPath: result.managedPath,\n },\n 'Skill import completed'\n );\n\n const executor = this.executionCoordinator.getExecutor(result.descriptor.access.protocol);\n let capabilities;\n try {\n capabilities = await executor.loadAppCapabilities(\n result.appId,\n result.descriptor.access.config as any\n );\n } catch {\n capabilities = {\n title: 'Skill',\n tools: [\n {\n name: 'read',\n description: 'Read the skill documentation',\n inputSchema: { type: 'object' as const, properties: {} },\n },\n ],\n };\n }\n\n return {\n text: [\n `Imported skill: ${result.descriptor.app.name.default}`,\n `App ID: ${result.appId}`,\n `App tool prefix: app:${result.appId}`,\n `Skill directory: ${result.managedPath}`,\n `Summary: ${result.descriptor.exposure.summary}`,\n 'Default enabled for: importing agent only',\n '',\n this.guideService.generateAppGuide(result.appId, result.descriptor, capabilities),\n ].join('\\n'),\n };\n } catch (err) {\n logger.error(\n { tool: 'skill:import', request: summarizeRawImportArgs(rawArgs), err },\n 'Skill import failed'\n );\n return createErrorResult('Skill import failed.', err);\n }\n }\n\n // ============================================================\n // Search / Discover\n // ============================================================\n\n handleSearchDiscover(args: Record<string, unknown> | undefined): GatewayTextResult {\n try {\n parseSearchDiscoverArguments(args);\n return { text: buildSearchDiscoverResponse() };\n } catch (err) {\n throw new AaiError('INVALID_REQUEST', err instanceof Error ? err.message : String(err));\n }\n }\n\n // ============================================================\n // List / Enable / Disable / Remove\n // ============================================================\n\n async handleListAllApps(caller: CallerContext): Promise<GatewayTextResult> {\n const apps = await this.listManageableApps(caller);\n const payload = {\n apps: apps.map(({ app, enabled }) => ({\n app: app.appId,\n name: app.descriptor.app.name.default,\n summary: app.descriptor.exposure.summary,\n source: app.source,\n enabled,\n removable: app.source === 'mcp-import' || app.source === 'skill-import',\n })),\n };\n\n return {\n text: JSON.stringify(payload, null, 2),\n structuredContent: payload,\n };\n }\n\n async handleDisableApp(\n args: Record<string, unknown> | undefined,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n const appId = typeof args?.app === 'string' ? args.app.trim() : '';\n if (!appId) {\n throw new AaiError('INVALID_REQUEST', \"disableApp requires 'app'\");\n }\n\n await this.resolveManageableApp(appId);\n await disableAppForAgent(caller.id, appId);\n\n const payload = { app: appId, disabledFor: caller.id };\n return {\n text: JSON.stringify(payload, null, 2),\n structuredContent: payload,\n };\n }\n\n async handleEnableApp(\n args: Record<string, unknown> | undefined,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n const appId = typeof args?.app === 'string' ? args.app.trim() : '';\n if (!appId) {\n throw new AaiError('INVALID_REQUEST', \"enableApp requires 'app'\");\n }\n\n await this.resolveManageableApp(appId);\n await enableAppForAgent(caller.id, appId);\n\n const payload = { app: appId, enabledFor: caller.id };\n return {\n text: JSON.stringify(payload, null, 2),\n structuredContent: payload,\n };\n }\n\n async handleRemoveApp(\n args: Record<string, unknown> | undefined,\n _caller: CallerContext\n ): Promise<GatewayTextResult> {\n const appId = typeof args?.app === 'string' ? args.app.trim() : '';\n if (!appId) {\n throw new AaiError('INVALID_REQUEST', \"removeApp requires 'app'\");\n }\n\n if (args?.confirm !== true) {\n throw new AaiError(\n 'INVALID_REQUEST',\n \"removeApp requires 'confirm: true' after the agent explains the global impact and the user explicitly confirms.\"\n );\n }\n\n const app = await this.resolveManageableApp(appId);\n if (app.source !== 'mcp-import' && app.source !== 'skill-import') {\n throw new AaiError(\n 'INVALID_REQUEST',\n `removeApp only supports AAI Gateway managed imports. '${appId}' is a '${app.source}' app.`\n );\n }\n\n await this.importService.removeApp(appId);\n\n const payload = { app: appId, removedFrom: 'all-agents' };\n return {\n text: JSON.stringify(payload, null, 2),\n structuredContent: payload,\n };\n }\n\n // ============================================================\n // Notification hook (called by server after state changes)\n // ============================================================\n\n get toolsChanged(): boolean {\n // marker for server to check; or use callback\n return false;\n }\n\n // ============================================================\n // Internal: Gateway tool routing\n // ============================================================\n\n private async executeGatewayTool(\n toolName: string,\n args: Record<string, unknown>,\n caller: CallerContext\n ): Promise<GatewayTextResult> {\n if (toolName === SEARCH_DISCOVER_TOOL_NAME) {\n return this.handleSearchDiscover(args);\n }\n if (toolName === 'listAllAaiApps') {\n return this.handleListAllApps(caller);\n }\n if (toolName === 'disableApp') {\n return this.handleDisableApp(args, caller);\n }\n if (toolName === 'enableApp') {\n return this.handleEnableApp(args, caller);\n }\n if (toolName === 'removeApp') {\n return this.handleRemoveApp(args, caller);\n }\n if (toolName === 'mcp:import') {\n return this.handleMcpImport(parseMcpImportArguments(args), args, caller);\n }\n if (toolName === 'skill:import') {\n return this.handleSkillImport(parseSkillImportArguments(args), args, caller);\n }\n throw new AaiError('UNKNOWN_TOOL', `Unknown tool: ${toolName}`);\n }\n\n // ============================================================\n // Internal: App resolution\n // ============================================================\n\n private async resolveManagedApp(\n appId: string,\n caller: CallerContext\n ): Promise<{ app: RuntimeAppRecord } | { disabled: true; appId: string } | undefined> {\n const existing = this.appRegistry.get(appId);\n if (!existing) return undefined;\n\n if (await this.isAppEnabledForCaller(existing, caller)) {\n return { app: existing };\n }\n return { disabled: true, appId };\n }\n\n private async resolveManageableApp(appId: string): Promise<RuntimeAppRecord> {\n const existing = this.appRegistry.get(appId);\n if (!existing) {\n throw new AaiError('UNKNOWN_APP', `App not found: ${appId}`);\n }\n return existing;\n }\n\n private async resolveApp(appIdOrUrl: string, caller: CallerContext): Promise<RuntimeAppRecord> {\n const result = await this.resolveManagedApp(appIdOrUrl, caller);\n if (result && 'app' in result) return result.app;\n if (result && 'disabled' in result) {\n throw new AaiError(\n 'UNKNOWN_APP',\n `App \"${appIdOrUrl}\" is currently disabled for this agent. To enable it, call the enableApp tool with app: \"${appIdOrUrl}\". Please present this message to the user in their preferred language.`\n );\n }\n throw new AaiError('UNKNOWN_APP', `App not found: ${appIdOrUrl}`);\n }\n\n // ============================================================\n // Internal: Visibility\n // ============================================================\n\n private async listVisibleApps(caller: CallerContext): Promise<RuntimeAppRecord[]> {\n const apps = Array.from(this.appRegistry.values());\n const enabledApps = await Promise.all(\n apps.map(async (app) => ((await this.isAppEnabledForCaller(app, caller)) ? app : null))\n );\n return enabledApps.filter((app): app is RuntimeAppRecord => app !== null);\n }\n\n private async listManageableApps(caller: CallerContext): Promise<\n Array<{ app: RuntimeAppRecord; enabled: boolean }>\n > {\n const apps = Array.from(this.appRegistry.values());\n return Promise.all(\n apps.map(async (app) => ({\n app,\n enabled: await this.isAppEnabledForCaller(app, caller),\n }))\n );\n }\n\n private async isAppEnabledForCaller(\n app: RuntimeAppRecord,\n caller: CallerContext\n ): Promise<boolean> {\n const agentState = await upsertAgentState({\n agentId: caller.id,\n callerName: caller.name,\n agentType: caller.type,\n });\n\n const override = agentState.appOverrides[app.appId];\n if (override === 'enabled') return true;\n if (override === 'disabled') return false;\n\n const policy = await loadAppPolicyState(app.appId);\n if (!policy || policy.defaultEnabled === 'all') return true;\n\n return policy.importerAgentId === caller.id;\n }\n\n // ============================================================\n // Internal: Result formatting\n // ============================================================\n\n private toTextResult(result: unknown): GatewayTextResult {\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n return {\n text: JSON.stringify(result, null, 2),\n structuredContent: result as Record<string, unknown>,\n };\n }\n return {\n text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),\n };\n }\n}\n\n// ============================================================\n// Standalone helpers\n// ============================================================\n\nfunction formatToolPreview(tools: Array<{ name: string; description?: string }>): string {\n if (tools.length === 0) return 'No MCP tools reported.';\n return tools.map((tool) => `- ${tool.name}: ${tool.description ?? ''}`.trimEnd()).join('\\n');\n}\n\nexport function createErrorResult(summary: string, err: unknown): GatewayTextResult {\n const details: string[] = [summary];\n\n if (err instanceof AaiError) {\n details.push(`Error: ${err.message}`);\n if (err.data && Object.keys(err.data).length > 0) {\n details.push('', 'Details:', JSON.stringify(err.data, null, 2));\n }\n } else if (err instanceof Error) {\n details.push(`Error: ${err.message}`);\n } else {\n details.push(`Error: ${String(err)}`);\n }\n\n return { text: details.join('\\n'), isError: true };\n}\n\nfunction isMissingEnvVarsError(err: unknown): boolean {\n if (err instanceof AaiError) {\n const data = err.data as Record<string, unknown> | undefined;\n if (data?.code === 'MISSING_ENV_VARS') return true;\n }\n if (err instanceof Error && /Missing environment variables/i.test(err.message)) return true;\n return false;\n}\n\nfunction extractMissingVarNames(err: unknown): string[] {\n if (err instanceof AaiError) {\n const data = err.data as Record<string, unknown> | undefined;\n if (Array.isArray(data?.missingVars)) return data.missingVars as string[];\n }\n if (err instanceof Error) {\n const matches = err.message.match(/\\$\\{([^}]+)\\}/g);\n if (matches) return matches.map((m) => m.slice(2, -1));\n }\n return [];\n}\n\nfunction buildMissingEnvVarsResult(err: unknown): GatewayTextResult {\n const envFile = getDotenvPath();\n const missingVars = extractMissingVarNames(err);\n const varList = missingVars.length > 0 ? missingVars : ['<VARIABLE_NAME>'];\n\n const lines: string[] = [\n 'MCP import failed: missing environment variables.',\n '',\n '## What to do',\n '',\n `The following environment variables are required but not set: ${varList.map((v) => `\\`${v}\\``).join(', ')}`,\n '',\n '### Step 1 — Obtain the values',\n '',\n ...varList.map(\n (v) =>\n `- \\`${v}\\`: search the web for where to obtain this key (e.g. the provider\\'s developer portal or API dashboard).`\n ),\n '',\n '### Step 2 — Save to the AAI env file',\n '',\n `Open the env file for the user with a shell command:`,\n '```',\n `open ${envFile}`,\n '```',\n `Ask the user to add the values in the format:`,\n '```',\n ...varList.map((v) => `${v}=<paste_value_here>`),\n '```',\n '',\n 'Do not read or display the contents of this file — it contains sensitive secrets.',\n '',\n '### Step 3 — Retry',\n '',\n 'After the user confirms the values have been saved, call `mcp:import` again with the same parameters.',\n ];\n\n return { text: lines.join('\\n'), isError: true };\n}\n","/**\n * MCP Server\n *\n * Thin protocol layer — handles MCP request/response serialization\n * and delegates all business logic to Gateway (core/gateway.ts).\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n type CallToolResult,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport { AaiError } from '../errors/errors.js';\nimport type { CallerContext } from '../types/caller.js';\nimport { logger } from '../utils/logger.js';\nimport { AAI_GATEWAY_NAME, AAI_GATEWAY_VERSION } from '../version.js';\nimport { Gateway, type GatewayTextResult } from '../core/gateway.js';\nimport { normalizeArgumentsWithSchema } from '../core/parsers.js';\n\nconst TOOLS_CHANGING_OPERATIONS = new Set([\n 'mcp:import', 'skill:import', 'disableApp', 'enableApp', 'removeApp',\n]);\n\nexport class AaiGatewayServer {\n private readonly server: Server;\n private readonly gateway = new Gateway();\n private callerContext?: CallerContext;\n\n constructor() {\n this.server = new Server(\n { name: AAI_GATEWAY_NAME, version: AAI_GATEWAY_VERSION },\n {\n capabilities: {\n tools: { listChanged: true },\n logging: {},\n },\n }\n );\n this.setupHandlers();\n }\n\n async initialize(): Promise<void> {\n await this.gateway.initialize();\n }\n\n async start(): Promise<void> {\n await this.initialize();\n const transport = new StdioServerTransport();\n await this.server.connect(transport);\n logger.info('AAI Gateway started (stdio)');\n }\n\n // ============================================================\n // MCP Protocol Handlers\n // ============================================================\n\n private setupHandlers(): void {\n this.server.oninitialized = () => {\n const clientVersion = this.server.getClientVersion();\n this.callerContext = this.gateway.createCallerContext(clientVersion);\n };\n\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n const tools = await this.gateway.listTools(this.requireCaller());\n return { tools };\n });\n\n this.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {\n const { name, arguments: rawArgs } = request.params;\n const caller = this.requireCaller();\n\n // Normalize args against tool schema if available\n const toolDef = this.gateway.getGatewayToolDefinition(name);\n const args = toolDef\n ? (normalizeArgumentsWithSchema(rawArgs, toolDef.inputSchema) as\n | Record<string, unknown>\n | undefined)\n : rawArgs;\n\n // app:<id> → guide\n if (name.startsWith('app:')) {\n return this.toCallToolResult(\n await this.gateway.handleAppGuide(name.slice(4), caller)\n );\n }\n\n // aai:exec → dispatch\n if (name === 'aai:exec') {\n const payload = args as { app?: string; tool: string; args?: Record<string, unknown> };\n const result = await this.gateway.handleExec(\n extra.requestId,\n payload.app,\n payload.tool,\n payload.args ?? {},\n caller\n );\n if (TOOLS_CHANGING_OPERATIONS.has(payload.tool) && !result.isError) {\n await this.notifyToolsListChanged();\n }\n return this.toCallToolResult(result);\n }\n\n // mcp:import / skill:import → always return guide (actual import via aai:exec)\n if (name === 'mcp:import' || name === 'skill:import') {\n return this.toCallToolResult(this.gateway.handleGatewayToolGuide(name));\n }\n\n // Management tools routed through exec\n if (\n name === 'search:discover' ||\n name === 'listAllAaiApps' ||\n name === 'disableApp' ||\n name === 'enableApp' ||\n name === 'removeApp'\n ) {\n const toolArgs = (args as Record<string, unknown> | undefined) ?? {};\n let result: GatewayTextResult;\n\n switch (name) {\n case 'search:discover':\n result = this.gateway.handleSearchDiscover(toolArgs);\n break;\n case 'listAllAaiApps':\n result = await this.gateway.handleListAllApps(caller);\n break;\n case 'disableApp':\n result = await this.gateway.handleDisableApp(toolArgs, caller);\n await this.notifyToolsListChanged();\n break;\n case 'enableApp':\n result = await this.gateway.handleEnableApp(toolArgs, caller);\n await this.notifyToolsListChanged();\n break;\n case 'removeApp':\n result = await this.gateway.handleRemoveApp(toolArgs, caller);\n await this.notifyToolsListChanged();\n break;\n default:\n throw new AaiError('UNKNOWN_TOOL', `Unknown tool: ${name}`);\n }\n\n return this.toCallToolResult(result);\n }\n\n throw new AaiError('UNKNOWN_TOOL', `Unknown tool: ${name}`);\n });\n }\n\n // ============================================================\n // Helpers\n // ============================================================\n\n private requireCaller(): CallerContext {\n if (this.callerContext) return this.callerContext;\n return {\n id: 'unknown-client',\n name: 'Unknown Client',\n transport: 'mcp',\n type: 'unknown',\n };\n }\n\n private async notifyToolsListChanged(): Promise<void> {\n try {\n await this.server.sendToolListChanged();\n logger.debug('Sent tools/listChanged notification');\n } catch (error) {\n logger.error({ err: error }, 'Failed to send tools/listChanged notification');\n }\n }\n\n private toCallToolResult(result: GatewayTextResult): CallToolResult {\n return {\n content: [{ type: 'text', text: result.text }],\n ...(result.isError ? { isError: true } : {}),\n ...(result.structuredContent ? { structuredContent: result.structuredContent } : {}),\n };\n }\n}\n\nexport async function createGatewayServer(): Promise<AaiGatewayServer> {\n return new AaiGatewayServer();\n}\n"],"mappings":"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"}
|