@easynet/agent-tool 1.0.24 → 1.0.25
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/api/extension/createExtension.d.ts +38 -0
- package/dist/api/extension/createExtension.d.ts.map +1 -0
- package/dist/api/extension/dynamicImportAdapter.d.ts +3 -2
- package/dist/api/extension/dynamicImportAdapter.d.ts.map +1 -1
- package/dist/api/extension/generateExtensionManifest.d.ts +24 -0
- package/dist/api/extension/generateExtensionManifest.d.ts.map +1 -0
- package/dist/api/extension/index.d.ts +4 -0
- package/dist/api/extension/index.d.ts.map +1 -1
- package/dist/api/extension/registerExtension.d.ts +6 -5
- package/dist/api/extension/registerExtension.d.ts.map +1 -1
- package/dist/api/extension/registerFromManifest.d.ts +2 -2
- package/dist/api/extension/registerFromManifest.d.ts.map +1 -1
- package/dist/api/main.cjs +14 -14
- package/dist/api/main.js +3 -3
- package/dist/api/runtimeFromConfig.d.ts +8 -8
- package/dist/api/runtimeFromConfig.d.ts.map +1 -1
- package/dist/{chunk-AT3N7SQK.cjs → chunk-5CDN24FP.cjs} +11 -10
- package/dist/chunk-5CDN24FP.cjs.map +1 -0
- package/dist/{chunk-ZRDI2RKU.js → chunk-AO2RY5AI.js} +3 -3
- package/dist/{chunk-ZRDI2RKU.js.map → chunk-AO2RY5AI.js.map} +1 -1
- package/dist/{chunk-AH4NI4GN.cjs → chunk-AOEZBP6L.cjs} +18 -46
- package/dist/chunk-AOEZBP6L.cjs.map +1 -0
- package/dist/{chunk-P2LVZGZ4.cjs → chunk-B5CAENK6.cjs} +7 -7
- package/dist/{chunk-P2LVZGZ4.cjs.map → chunk-B5CAENK6.cjs.map} +1 -1
- package/dist/{chunk-QP5FIRC2.js → chunk-JEP26OIY.js} +3 -3
- package/dist/{chunk-QP5FIRC2.js.map → chunk-JEP26OIY.js.map} +1 -1
- package/dist/{chunk-FWIMPZC2.cjs → chunk-NA2YBWZJ.cjs} +14 -14
- package/dist/{chunk-FWIMPZC2.cjs.map → chunk-NA2YBWZJ.cjs.map} +1 -1
- package/dist/{chunk-BOMOGAFZ.js → chunk-P5YQNWQT.js} +5 -4
- package/dist/chunk-P5YQNWQT.js.map +1 -0
- package/dist/{chunk-BPHY6UVK.js → chunk-SO32CIHJ.js} +17 -45
- package/dist/chunk-SO32CIHJ.js.map +1 -0
- package/dist/index.cjs +166 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +112 -21
- package/dist/index.js.map +1 -1
- package/dist/tools/function/scanner.d.ts.map +1 -1
- package/dist/utils/cli/index.cjs +17 -17
- package/dist/utils/cli/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-AH4NI4GN.cjs.map +0 -1
- package/dist/chunk-AT3N7SQK.cjs.map +0 -1
- package/dist/chunk-BOMOGAFZ.js.map +0 -1
- package/dist/chunk-BPHY6UVK.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/security/ssrf.ts","../src/security/sandbox.ts","../src/api/extension/contextRunner.ts","../src/api/extension/dynamicImportAdapter.ts","../src/api/extension/loadToolYaml.ts","../src/api/extension/registerFromManifest.ts","../src/api/extension/resolvePackageRoot.ts","../src/api/extension/registerExtension.ts","../src/api/extension/groupPrefix.ts","../src/tools/mcp/MCPClientAdapter.ts","../src/tools/mcp/connectMCP.ts","../src/tools/mcp/MCPProcessManager.ts","../src/tools/mcp/registerMCPTools.ts"],"names":["path","existsSync","readFileSync","dirname","basename"],"mappings":"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","file":"index.js","sourcesContent":["import { lookup } from \"node:dns/promises\";\nimport { createTaggedError } from \"../core/runtime/Retry.js\";\n\n/**\n * Options for validateUrl. Unified rule: allow iff host is in allowedHosts AND not in blockedHosts.\n * - \"Default allow all + blocklist\": allowedHosts: [\"*\"], blockedHosts: [\"*.internal\", ...]\n * - \"Default disallow all + allowlist\": allowedHosts: [\"api.github.com\", ...], blockedHosts: []\n */\nexport interface ValidateUrlOptions {\n /** Allow only these hosts. Use [\"*\"] for allow-all. Supports \"*.example.com\", exact host. */\n allowedHosts: string[];\n /** Block these hosts even if allowed. Supports \"*.internal\", exact host. Merged with allowlist. */\n blockedHosts: string[];\n /** CIDR ranges to block (resolved IP). */\n blockedCidrs: string[];\n}\n\n/**\n * Validate a URL: allow iff (host in allowedHosts) AND (host not in blockedHosts). Then check blockedCidrs on resolved IP.\n *\n * @throws HTTP_DISALLOWED_HOST if the URL is blocked\n */\nexport async function validateUrl(url: string, options: ValidateUrlOptions): Promise<URL> {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Invalid URL: ${url}`,\n { url },\n );\n }\n\n // Only allow http/https\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Protocol not allowed: ${parsed.protocol}. Only http: and https: are supported.`,\n { url, protocol: parsed.protocol },\n );\n }\n\n const hostname = parsed.hostname;\n\n if (!isHostAllowed(hostname, options.allowedHosts)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" is not in the allowed hosts list`,\n { url, hostname, allowedHosts: options.allowedHosts },\n );\n }\n if (isHostBlocked(hostname, options.blockedHosts)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" is in the blocked hosts list`,\n { url, hostname, blockedHosts: options.blockedHosts },\n );\n }\n\n // DNS resolve and check against blocked CIDRs\n try {\n const { address } = await lookup(hostname);\n if (isIpInBlockedCidrs(address, options.blockedCidrs)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" resolves to blocked IP: ${address}`,\n { url, hostname, resolvedIp: address },\n );\n }\n } catch (err) {\n // Re-throw our tagged errors\n if (err instanceof Error && (err as any).kind === \"HTTP_DISALLOWED_HOST\") {\n throw err;\n }\n // DNS resolution failure — block by default\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `DNS resolution failed for host \"${hostname}\": ${err instanceof Error ? err.message : String(err)}`,\n { url, hostname },\n );\n }\n\n return parsed;\n}\n\n/**\n * Check if a hostname matches any entry in the allowed hosts list.\n * Supports: exact \"*\" (allow any host), wildcard prefix (e.g. \"*.github.com\"), or exact host.\n */\nfunction isHostAllowed(hostname: string, allowedHosts: string[]): boolean {\n for (const pattern of allowedHosts) {\n if (pattern === \"*\") {\n return true;\n }\n if (pattern.startsWith(\"*.\")) {\n const suffix = pattern.slice(1); // \".github.com\"\n if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {\n return true;\n }\n } else if (hostname === pattern) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a hostname matches any entry in the blocked hosts list (same pattern rules as allowlist).\n */\nfunction isHostBlocked(hostname: string, blockedHosts: string[]): boolean {\n for (const pattern of blockedHosts) {\n if (pattern === \"*\") {\n return true;\n }\n if (pattern.startsWith(\"*.\")) {\n const suffix = pattern.slice(1);\n if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {\n return true;\n }\n } else if (hostname === pattern) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if an IPv4 address falls within any blocked CIDR range.\n */\nexport function isIpInBlockedCidrs(ip: string, cidrs: string[]): boolean {\n // Handle IPv4-mapped IPv6\n const normalizedIp = normalizeIp(ip);\n if (!normalizedIp) return false;\n\n for (const cidr of cidrs) {\n if (cidr.includes(\":\")) {\n // IPv6 CIDR — skip for IPv4 addresses\n if (!ip.includes(\":\")) continue;\n if (isIpv6InCidr(ip, cidr)) return true;\n } else {\n if (isIpv4InCidr(normalizedIp, cidr)) return true;\n }\n }\n return false;\n}\n\nfunction normalizeIp(ip: string): string | null {\n // Handle IPv4-mapped IPv6 (e.g. \"::ffff:127.0.0.1\")\n if (ip.startsWith(\"::ffff:\")) {\n return ip.slice(7);\n }\n // Pure IPv4\n if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(ip)) {\n return ip;\n }\n return null;\n}\n\nfunction isIpv4InCidr(ip: string, cidr: string): boolean {\n const [cidrIp, prefixStr] = cidr.split(\"/\");\n if (!cidrIp || !prefixStr) return false;\n\n const prefix = parseInt(prefixStr, 10);\n if (isNaN(prefix) || prefix < 0 || prefix > 32) return false;\n\n const ipNum = ipv4ToNum(ip);\n const cidrNum = ipv4ToNum(cidrIp);\n if (ipNum === null || cidrNum === null) return false;\n\n const mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0;\n return (ipNum & mask) === (cidrNum & mask);\n}\n\nfunction ipv4ToNum(ip: string): number | null {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let num = 0;\n for (const part of parts) {\n const n = parseInt(part, 10);\n if (isNaN(n) || n < 0 || n > 255) return null;\n num = (num << 8) | n;\n }\n return num >>> 0;\n}\n\nfunction isIpv6InCidr(ip: string, cidr: string): boolean {\n // Simplified IPv6 CIDR matching for common cases (::1, fc00::, fe80::)\n const [cidrIp, prefixStr] = cidr.split(\"/\");\n if (!cidrIp || !prefixStr) return false;\n\n const prefix = parseInt(prefixStr, 10);\n if (isNaN(prefix)) return false;\n\n const ipBytes = expandIpv6(ip);\n const cidrBytes = expandIpv6(cidrIp);\n if (!ipBytes || !cidrBytes) return false;\n\n // Compare prefix bits\n const fullBytes = Math.floor(prefix / 8);\n for (let i = 0; i < fullBytes && i < 16; i++) {\n if (ipBytes[i] !== cidrBytes[i]) return false;\n }\n\n const remainingBits = prefix % 8;\n if (remainingBits > 0 && fullBytes < 16) {\n const mask = (~0 << (8 - remainingBits)) & 0xff;\n if ((ipBytes[fullBytes]! & mask) !== (cidrBytes[fullBytes]! & mask)) return false;\n }\n\n return true;\n}\n\nfunction expandIpv6(ip: string): number[] | null {\n // Remove zone ID\n const zoneIdx = ip.indexOf(\"%\");\n if (zoneIdx !== -1) ip = ip.slice(0, zoneIdx);\n\n const parts = ip.split(\"::\");\n if (parts.length > 2) return null;\n\n const bytes: number[] = new Array(16).fill(0);\n\n const expandGroup = (group: string): number[] => {\n if (!group) return [];\n return group.split(\":\").flatMap((hex) => {\n const val = parseInt(hex || \"0\", 16);\n return [(val >> 8) & 0xff, val & 0xff];\n });\n };\n\n if (parts.length === 1) {\n const expanded = expandGroup(parts[0]!);\n if (expanded.length !== 16) return null;\n return expanded;\n }\n\n const left = expandGroup(parts[0]!);\n const right = expandGroup(parts[1]!);\n\n if (left.length + right.length > 16) return null;\n\n for (let i = 0; i < left.length; i++) bytes[i] = left[i]!;\n for (let i = 0; i < right.length; i++) bytes[16 - right.length + i] = right[i]!;\n\n return bytes;\n}\n","import { resolve, normalize, dirname, basename } from \"node:path\";\nimport { realpath, access } from \"node:fs/promises\";\nimport { createTaggedError } from \"../core/runtime/Retry.js\";\n\n/**\n * Resolve an input path to an absolute path within the sandbox.\n * Throws PATH_OUTSIDE_SANDBOX if the resolved path escapes the sandbox root.\n *\n * For existing files: uses realpath to resolve symlinks.\n * For non-existing files (write targets): resolves the parent directory.\n */\nexport async function resolveSandboxedPath(\n inputPath: string,\n sandboxRoot: string,\n): Promise<string> {\n // Resolve the sandbox root itself with realpath to handle platform symlinks\n // (e.g. macOS /var -> /private/var)\n let normalizedRoot: string;\n try {\n normalizedRoot = await realpath(resolve(sandboxRoot));\n } catch {\n normalizedRoot = normalize(resolve(sandboxRoot));\n }\n\n // Resolve against sandbox root\n const resolved = resolve(normalizedRoot, inputPath);\n\n let real: string;\n try {\n // Try to resolve symlinks for existing paths\n await access(resolved);\n real = await realpath(resolved);\n } catch {\n // Path does not exist — resolve parent to check containment\n const parentDir = dirname(resolved);\n let realParent: string;\n try {\n await access(parentDir);\n realParent = await realpath(parentDir);\n } catch {\n // Parent also doesn't exist — use normalized resolved path\n // (will fail at actual FS operation if truly invalid)\n realParent = normalize(parentDir);\n }\n real = resolve(realParent, basename(resolved));\n }\n\n if (!isWithinRoot(real, normalizedRoot)) {\n throw createTaggedError(\n \"PATH_OUTSIDE_SANDBOX\",\n `Path \"${inputPath}\" resolves to \"${real}\" which is outside sandbox \"${normalizedRoot}\"`,\n { inputPath, resolvedPath: real, sandboxRoot: normalizedRoot },\n );\n }\n\n return real;\n}\n\nfunction isWithinRoot(path: string, root: string): boolean {\n const normalizedPath = normalize(path);\n const normalizedRoot = normalize(root);\n return normalizedPath === normalizedRoot || normalizedPath.startsWith(normalizedRoot + \"/\");\n}\n","/**\n * Generic context injection for extension tools (e.g. builtin).\n * Any extension that needs to inject config (sandbox, allowedHosts, etc.) into handlers uses this.\n */\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport interface ContextRunner<T> {\n runWith(ctx: T, fn: () => Promise<unknown>): Promise<unknown>;\n getContext(): T;\n}\n\n/**\n * Create a context runner for an extension. Handlers call getContext() to read config.\n * Adapter calls runWith(ctx, () => handler(args)) so getContext() returns ctx.\n */\nexport function createContextRunner<T>(): ContextRunner<T> {\n const storage = new AsyncLocalStorage<T>();\n return {\n runWith(ctx: T, fn: () => Promise<unknown>): Promise<unknown> {\n return storage.run(ctx, fn);\n },\n getContext(): T {\n const ctx = storage.getStore();\n if (ctx === undefined) {\n throw new Error(\"Extension context not set; invoke only through the extension adapter.\");\n }\n return ctx;\n },\n };\n}\n","/**\n * Generic adapter for extensions that discover tools via manifest and load handlers by dynamic import.\n * Any extension (builtin, etc.) that uses @tool scan → manifest and runs handlers with injected context uses this.\n */\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { ToolAdapter, ToolSpec } from \"../../core/types/ToolSpec.js\";\nimport type { ExecContext } from \"../../core/types/ToolIntent.js\";\nimport type { Evidence } from \"../../core/types/ToolResult.js\";\n\nexport interface ExtensionToolResult {\n result: unknown;\n evidence: Evidence[];\n}\n\nexport interface DynamicImportAdapterOptions<TContext> {\n kind: string;\n packageRoot: string;\n getExtensionContext: (execCtx: ExecContext) => TContext;\n contextRunner: { runWith(ctx: TContext, fn: () => Promise<ExtensionToolResult>): Promise<ExtensionToolResult> };\n}\n\n/**\n * Create an adapter that loads handlers by spec._meta.sourcePath and exportName, then runs with extension context.\n */\nexport function createDynamicImportAdapter<TContext>(\n options: DynamicImportAdapterOptions<TContext>,\n): ToolAdapter {\n const { kind, packageRoot, getExtensionContext, contextRunner } = options;\n return {\n kind: kind as ToolAdapter[\"kind\"],\n async invoke(\n spec: ToolSpec,\n args: unknown,\n execCtx: ExecContext,\n ): Promise<{ result: unknown; raw?: unknown }> {\n const meta = spec._meta as {\n sourcePath?: string;\n exportName?: string;\n defaultArgs?: Record<string, unknown>;\n } | undefined;\n const sourcePath = meta?.sourcePath;\n const exportName = meta?.exportName;\n if (!sourcePath || !exportName) {\n throw new Error(`Extension tool ${spec.name} missing _meta.sourcePath or _meta.exportName`);\n }\n const defaultArgs = meta?.defaultArgs ?? {};\n const mergedArgs =\n Object.keys(defaultArgs).length === 0\n ? (args as Record<string, unknown>)\n : { ...defaultArgs, ...(args as Record<string, unknown>) };\n const modulePath = path.join(packageRoot, `${sourcePath}.js`);\n const mod = await import(pathToFileURL(modulePath).href);\n const handler = mod[exportName];\n if (typeof handler !== \"function\") {\n throw new Error(\n `Extension tool ${spec.name}: export \"${exportName}\" from ${sourcePath} is not a function`,\n );\n }\n const ctx = getExtensionContext(execCtx);\n const output = await contextRunner.runWith(ctx, () => handler(mergedArgs));\n return { result: output.result, raw: { evidence: output.evidence } };\n },\n };\n}\n","/**\n * Load per-tool default args/config from <base>.tool.yaml (framework-defined format).\n *\n * Supported YAML format:\n * tool:\n * list:\n * - name: fetchText\n * timeoutMs: 5000\n * maxBytes: 1048576\n * (find item where name === tool base name, use rest as defaultArgs)\n */\nimport { readFileSync, existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport yaml from \"js-yaml\";\n\n/**\n * Load tool.yaml for a given tool. Path: packageRoot / dirname(sourcePath) / basename(sourcePath).tool.yaml\n * Returns default args (and config) for the tool, or undefined if file missing or no matching entry.\n */\nexport function loadToolYaml(\n packageRoot: string,\n sourcePath: string,\n): Record<string, unknown> | undefined {\n const dir = path.dirname(sourcePath);\n const base = path.basename(sourcePath);\n const yamlPath = path.join(packageRoot, dir, `${base}.tool.yaml`);\n if (!existsSync(yamlPath)) return undefined;\n try {\n const raw = readFileSync(yamlPath, \"utf-8\");\n const data = yaml.load(raw) as unknown;\n if (data == null || typeof data !== \"object\" || Array.isArray(data)) return undefined;\n const obj = data as Record<string, unknown>;\n const list = obj?.tool as Record<string, unknown> | undefined;\n const arr = list?.list;\n if (!Array.isArray(arr)) return undefined;\n const item = arr.find(\n (e: unknown) => e != null && typeof e === \"object\" && (e as Record<string, unknown>).name === base,\n ) as Record<string, unknown> | undefined;\n if (!item || typeof item !== \"object\") return undefined;\n const { name: _n, ...rest } = item;\n if (Object.keys(rest).length === 0) return undefined;\n return rest;\n } catch {\n return undefined;\n }\n}\n","/**\n * Generic manifest-based registration for extensions.\n * Reads a JSON manifest (from @tool scan) and registers ToolSpecs with the registry.\n * Optional: when packageRoot is provided, loads <base>.tool.yaml per tool (tool.list format) and sets defaultArgs in _meta.\n */\nimport { readFileSync, existsSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { createToolSpec } from \"../../core/types/ToolSpec.js\";\nimport type { ToolSpec, HitlSideEffect } from \"../../core/types/ToolSpec.js\";\nimport type { ToolRegistry } from \"../../core/registry/ToolRegistry.js\";\nimport { loadToolYaml } from \"./loadToolYaml.js\";\n\n/** Manifest entry shape (convention for @tool scan output). */\nexport interface ExtensionManifestEntry {\n coreName: string;\n description: string;\n inputSchema: object;\n outputSchema: object;\n sourcePath: string;\n exportName: string;\n sideEffect: HitlSideEffect;\n}\n\n/** Loaded manifest: entries + optional kind from manifest file. */\nexport interface LoadedExtensionManifest {\n kind?: string;\n entries: ExtensionManifestEntry[];\n}\n\nexport interface RegisterFromManifestOptions {\n /** Path to manifest JSON (or directory containing core-tools-manifest.json). */\n manifestPathOrDir: string;\n /** Tool kind; if omitted, uses manifest.kind or \"extension\". */\n kind?: string;\n /** Filter: only register these tool names. */\n only?: string[];\n /** Filter: only register tools whose name starts with one of these prefixes. */\n namePrefixes?: string[];\n /** Extension package root (e.g. dist); when set, loads <base>.tool.yaml per tool and sets defaultArgs in _meta. */\n packageRoot?: string;\n}\n\n/**\n * Load manifest from path. Supports array or { kind?, tools: ExtensionManifestEntry[] }.\n * Returns entries + optional kind so framework can use dynamic kind from manifest.\n */\nexport function loadExtensionManifest(manifestPathOrDir: string): LoadedExtensionManifest {\n const p = path.resolve(manifestPathOrDir);\n let manifestPath: string;\n if (existsSync(p) && statSync(p).isFile()) {\n manifestPath = p;\n } else {\n const inDir = path.join(p, \"core-tools-manifest.json\");\n const inDist = path.join(p, \"dist\", \"core-tools-manifest.json\");\n manifestPath = existsSync(inDir) ? inDir : inDist;\n }\n const raw = readFileSync(manifestPath, \"utf-8\");\n const parsed = JSON.parse(raw) as ExtensionManifestEntry[] | { kind?: string; tools: ExtensionManifestEntry[] };\n if (Array.isArray(parsed)) {\n return { entries: parsed };\n }\n return { kind: parsed.kind, entries: parsed.tools ?? [] };\n}\n\n/**\n * Register tools from a manifest with the registry. Returns the list of registered specs.\n * Extension packages call this from their registerCoreTools (or equivalent) with their package root.\n */\nexport function registerToolsFromManifest(\n registry: ToolRegistry,\n options: RegisterFromManifestOptions,\n): ToolSpec[] {\n const { manifestPathOrDir, kind: kindOpt, only, namePrefixes, packageRoot } = options;\n const loaded = loadExtensionManifest(manifestPathOrDir);\n const kind = (kindOpt ?? loaded.kind ?? \"extension\") as ToolSpec[\"kind\"];\n const entries = loaded.entries;\n const onlySet = only?.length ? new Set(only) : null;\n const registered: ToolSpec[] = [];\n\n for (const entry of entries) {\n let spec = createToolSpec({\n name: entry.coreName,\n kind,\n description: entry.description,\n inputSchema: entry.inputSchema,\n outputSchema: entry.outputSchema,\n capabilities: [],\n sideEffect: entry.sideEffect,\n });\n if (onlySet && !onlySet.has(spec.name)) continue;\n if (namePrefixes?.length && !namePrefixes.some((prefix) => spec.name.startsWith(prefix))) {\n continue;\n }\n const defaultArgs =\n packageRoot != null ? loadToolYaml(packageRoot, entry.sourcePath) : undefined;\n spec = {\n ...spec,\n _meta: {\n ...spec._meta,\n sourcePath: entry.sourcePath,\n exportName: entry.exportName,\n ...(defaultArgs != null && Object.keys(defaultArgs).length > 0 && { defaultArgs }),\n },\n } as ToolSpec;\n registry.register(spec);\n registered.push(spec);\n }\n return registered;\n}\n","/**\n * Resolve extension package root for dynamic import (dist when built, else dir).\n * Accepts import.meta.url (file:) or a directory path (e.g. __dirname).\n */\nimport path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\n\nexport function resolveExtensionPackageRoot(metaUrlOrPath: string): string {\n const dir = metaUrlOrPath.startsWith(\"file:\")\n ? path.dirname(fileURLToPath(metaUrlOrPath))\n : path.resolve(metaUrlOrPath);\n const dist = path.join(dir, \"dist\");\n return existsSync(dist) ? dist : dir;\n}\n","/**\n * One-shot: load manifest from package (dynamic scan), register all specs, create adapter.\n * Framework reads manifest (kind + tools); extension only passes packagePath, config, getContextRunner.\n */\nimport type { ToolAdapter } from \"../../core/types/ToolSpec.js\";\nimport type { ToolRegistry } from \"../../core/registry/ToolRegistry.js\";\nimport type { ExecContext } from \"../../core/types/ToolIntent.js\";\nimport type { ContextRunner } from \"./contextRunner.js\";\nimport { createDynamicImportAdapter } from \"./dynamicImportAdapter.js\";\nimport type { ExtensionToolResult } from \"./dynamicImportAdapter.js\";\nimport { registerToolsFromManifest, loadExtensionManifest } from \"./registerFromManifest.js\";\nimport { resolveExtensionPackageRoot } from \"./resolvePackageRoot.js\";\n\nexport interface RegisterExtensionOptions<TContext> {\n /** Package root (e.g. __dirname of extension's entry). Manifest is read from here. */\n packagePath: string;\n /** Tool kind; if omitted, uses manifest.kind or \"extension\". */\n kind?: string;\n /** Extension config; passed into context as { execCtx, config }. */\n config: unknown;\n /** Returns the context runner (extension's createContextRunner()). */\n getContextRunner: () => ContextRunner<TContext>;\n /** Filter: only register these tool names. */\n only?: string[];\n /** Filter: only register tools whose name starts with one of these prefixes. */\n namePrefixes?: string[];\n}\n\n/**\n * Load manifest from package (dynamic: kind + tools from file), register all specs, create and return adapter.\n */\nexport function registerExtension<TContext extends { execCtx: ExecContext; config: unknown }>(\n registry: ToolRegistry,\n options: RegisterExtensionOptions<TContext>,\n): ToolAdapter {\n const { packagePath, kind: kindOpt, config, getContextRunner, only, namePrefixes } = options;\n const packageRoot = resolveExtensionPackageRoot(packagePath);\n const contextRunner = getContextRunner();\n const loaded = loadExtensionManifest(packagePath);\n const kind = kindOpt ?? loaded.kind ?? \"extension\";\n\n registerToolsFromManifest(registry, {\n manifestPathOrDir: packagePath,\n kind,\n only,\n namePrefixes,\n packageRoot,\n });\n\n const adapter = createDynamicImportAdapter<TContext>({\n kind,\n packageRoot,\n getExtensionContext: (execCtx: ExecContext) => ({ execCtx, config } as TContext),\n contextRunner: {\n runWith(ctx: TContext, fn: () => Promise<ExtensionToolResult>) {\n return contextRunner.runWith(ctx, fn) as Promise<ExtensionToolResult>;\n },\n },\n });\n return adapter;\n}\n","/**\n * Convert \"groups\" + \"only\" options and a group→prefix map into only/namePrefixes for registerToolsFromManifest.\n * Extensions define their own group names and prefixes (e.g. fs -> \"core/fs.\").\n */\nexport interface GroupPrefixOptions {\n /** Only register tools in these groups (e.g. [\"fs\", \"http\"]). */\n groups?: string[];\n /** Only register these tool names. Takes precedence over groups. */\n only?: string[];\n /** Map group name -> name prefix (e.g. { fs: \"core/fs.\", http: \"core/http.\" }). */\n groupPrefixMap: Record<string, string>;\n}\n\nexport interface ResolvedOnlyNamePrefixes {\n only?: string[];\n namePrefixes?: string[];\n}\n\n/**\n * Resolve groups/only + groupPrefixMap to only and namePrefixes for registerToolsFromManifest.\n */\nexport function getGroupNamePrefixes(options: GroupPrefixOptions): ResolvedOnlyNamePrefixes {\n const { groups, only, groupPrefixMap } = options;\n const onlySet = only?.length ? new Set(only) : null;\n const namePrefixes =\n !onlySet && groups?.length ? groups.map((g) => groupPrefixMap[g]).filter(Boolean) : undefined;\n return {\n ...(onlySet ? { only: Array.from(onlySet) } : {}),\n ...(namePrefixes?.length ? { namePrefixes } : {}),\n };\n}\n","/**\n * ToolAdapter for MCP tools: holds SDK Client reference, invoke() calls client.callTool.\n * Framework-level support so scripts use registerMCPToolsFromConfig instead of inline MCP logic.\n */\n\nimport type { ToolAdapter, ToolSpec } from \"../../core/types/ToolSpec.js\";\nimport type { ExecContext } from \"../../core/types/ToolIntent.js\";\nimport { MCP_KIND } from \"./types.js\";\n\n/** SDK Client type (avoid hard typing on @modelcontextprotocol/sdk in this file for optional dep). */\nexport interface MCPClientLike {\n callTool(params: { name: string; arguments: Record<string, unknown> }): Promise<CallToolResult>;\n}\n\nexport interface CallToolResult {\n content?: Array<{ type: string; text?: string }>;\n toolResult?: unknown;\n}\n\nfunction textFromCallToolResult(result: CallToolResult): string {\n if (result.content?.length) {\n const parts = result.content\n .filter((c) => c.type === \"text\" && c.text != null)\n .map((c) => c.text);\n if (parts.length) return parts.join(\"\\n\");\n }\n if (result.toolResult !== undefined) return JSON.stringify(result.toolResult);\n return JSON.stringify(result);\n}\n\n/**\n * Adapter that invokes MCP tools via the SDK Client (callTool).\n * Register with runtime after connecting and listing tools; specs must have kind MCP_KIND.\n */\nexport class MCPClientAdapter implements ToolAdapter {\n readonly kind = MCP_KIND;\n\n constructor(private readonly client: MCPClientLike) {}\n\n async invoke(\n spec: ToolSpec,\n args: unknown,\n _ctx: ExecContext\n ): Promise<{ result: unknown; raw?: unknown }> {\n const params = args != null && typeof args === \"object\" && !Array.isArray(args)\n ? (args as Record<string, unknown>)\n : {};\n const result = await this.client.callTool({ name: spec.name, arguments: params });\n const text = textFromCallToolResult(result);\n let resultValue: unknown = text;\n try {\n resultValue = JSON.parse(text) as unknown;\n } catch {\n // keep as string\n }\n return { result: resultValue, raw: result };\n }\n}\n","/**\n * Connect to an MCP server via stdio using MCPConnectionInfo.\n * Framework-level: uses @modelcontextprotocol/sdk Client + StdioClientTransport.\n */\n\nimport type { MCPConnectionInfo } from \"./MCPProcessManager.js\";\nimport type { ToolSpec } from \"../../core/types/ToolSpec.js\";\nimport { DEFAULT_INPUT_SCHEMA, DEFAULT_OUTPUT_SCHEMA } from \"../../core/types/ToolSpec.js\";\nimport { MCP_KIND } from \"./types.js\";\n\nexport interface MCPConnectResult {\n /** SDK Client; use listTools() and callTool(). */\n client: MCPClientLike;\n /** Transport; call close() when done. */\n transport: MCPTransportLike;\n}\n\nexport interface MCPClientLike {\n connect(transport: MCPTransportLike): Promise<void>;\n listTools(params?: unknown): Promise<{ tools: MCPToolDef[] }>;\n callTool(params: { name: string; arguments: Record<string, unknown> }): Promise<CallToolResult>;\n}\n\nexport interface MCPTransportLike {\n close(): Promise<void>;\n}\n\nexport interface MCPToolDef {\n name: string;\n description?: string;\n inputSchema?: object;\n}\n\nexport interface CallToolResult {\n content?: Array<{ type: string; text?: string }>;\n toolResult?: unknown;\n}\n\n/**\n * Connect to MCP server via stdio. Only stdio is supported; url/SSE not implemented here.\n * Requires @modelcontextprotocol/sdk. Returns client and transport; caller must call transport.close() when done.\n */\nexport async function connectMCP(connectionInfo: MCPConnectionInfo): Promise<MCPConnectResult> {\n if (connectionInfo.type !== \"stdio\" || !connectionInfo.command) {\n throw new Error(\n `MCP stdio requires connectionInfo.type \"stdio\" and command; got type=${connectionInfo.type}`\n );\n }\n\n const { Client } = await import(\"@modelcontextprotocol/sdk/client\");\n const { StdioClientTransport } = await import(\n \"@modelcontextprotocol/sdk/client/stdio.js\"\n );\n\n const serverParams = {\n command: connectionInfo.command,\n args: connectionInfo.args ?? [],\n env: connectionInfo.env,\n cwd: connectionInfo.cwd,\n };\n const transport = new StdioClientTransport(serverParams);\n const client = new Client({ name: \"agent-tool\", version: \"1.0.0\" });\n await client.connect(transport);\n return {\n client: client as unknown as MCPClientLike,\n transport: transport as unknown as MCPTransportLike,\n };\n}\n\n/**\n * Convert MCP listTools() result to ToolSpec[] (kind MCP_KIND) for registry.\n */\nexport function mcpToolsToSpecs(tools: MCPToolDef[]): ToolSpec[] {\n return tools.map((t) => ({\n name: t.name,\n version: \"1.0.0\",\n kind: MCP_KIND,\n description: t.description ?? `MCP tool: ${t.name}`,\n inputSchema: t.inputSchema ?? DEFAULT_INPUT_SCHEMA,\n outputSchema: DEFAULT_OUTPUT_SCHEMA,\n capabilities: [],\n }));\n}\n","import type { MCPServerConfig } from \"../discoveryFactory.js\";\n\n/**\n * Connection info for an MCP server.\n */\nexport interface MCPConnectionInfo {\n /** Transport type: \"url\" for SSE/HTTP, \"stdio\" for command-based */\n type: \"url\" | \"stdio\";\n /** SSE/HTTP URL (when type=\"url\") */\n url?: string;\n /** Command to spawn (when type=\"stdio\") */\n command?: string;\n /** Command arguments (when type=\"stdio\") */\n args?: string[];\n /** Environment variables (when type=\"stdio\") */\n env?: Record<string, string>;\n /** Working directory when spawning (when type=\"stdio\") */\n cwd?: string;\n}\n\n/**\n * Manages MCP server connection information extracted from directory discovery.\n */\nexport class MCPProcessManager {\n private readonly connections = new Map<string, MCPConnectionInfo>();\n\n getConnectionInfo(toolName: string, config: MCPServerConfig): MCPConnectionInfo {\n const cached = this.connections.get(toolName);\n if (cached) return cached;\n const info: MCPConnectionInfo = config.url\n ? { type: \"url\", url: config.url }\n : {\n type: \"stdio\",\n command: config.command!,\n args: config.args,\n env: config.env,\n cwd: config.cwd,\n };\n this.connections.set(toolName, info);\n return info;\n }\n\n remove(toolName: string): boolean {\n return this.connections.delete(toolName);\n }\n\n getToolNames(): string[] {\n return [...this.connections.keys()];\n }\n\n dispose(): void {\n this.connections.clear();\n }\n}\n","/**\n * High-level API: load mcp.json, connect to MCP server, register tools with runtime.\n * Framework-level so scripts call registerMCPToolsFromConfig() instead of inline MCP logic.\n */\n\nimport { basename, dirname, join } from \"node:path\";\nimport type { PTCRuntime } from \"../../core/runtime/PTCRuntime.js\";\nimport type { ToolRegistry } from \"../../core/registry/ToolRegistry.js\";\nimport { MCP_KIND } from \"./types.js\";\nimport { loadMCPTool } from \"./MCPLoader.js\";\nimport { MCPProcessManager } from \"./MCPProcessManager.js\";\nimport { connectMCP, mcpToolsToSpecs } from \"./connectMCP.js\";\nimport { MCPClientAdapter } from \"./MCPClientAdapter.js\";\n\nexport interface RegisterMCPToolsOptions {\n /** Path to mcp.json (or dir containing it). Default: process.env.MCP_CONFIG_PATH or \"mcp.json\" in cwd. */\n configPath?: string;\n /** Tool name for getConnectionInfo (default \"mcp\"). */\n toolName?: string;\n}\n\nexport interface RegisterMCPToolsResult {\n /** Transport; caller must call transport.close() when done. */\n transport: { close(): Promise<void> };\n}\n\n/**\n * Load mcp config (from configPath or MCP_CONFIG_PATH), connect via stdio, list tools,\n * register ToolSpec[] with registry and MCPClientAdapter with runtime. Returns transport for cleanup.\n */\nexport async function registerMCPToolsFromConfig(\n runtime: PTCRuntime,\n registry: ToolRegistry,\n options: RegisterMCPToolsOptions = {}\n): Promise<RegisterMCPToolsResult> {\n const configPath = options.configPath ?? process.env.MCP_CONFIG_PATH ?? join(process.cwd(), \"mcp.json\");\n const dirPath = dirname(configPath);\n const entryPoint = basename(configPath);\n const toolName = options.toolName ?? MCP_KIND;\n\n const loaded = await loadMCPTool(dirPath, { kind: MCP_KIND, name: toolName, entryPoint });\n if (!loaded.mcpConfig) {\n throw new Error(\"mcp.json must have command or url\");\n }\n const manager = new MCPProcessManager();\n const connectionInfo = manager.getConnectionInfo(toolName, loaded.mcpConfig);\n\n const { client, transport } = await connectMCP(connectionInfo);\n const { tools } = await client.listTools();\n const specs = mcpToolsToSpecs(tools);\n registry.bulkRegister(specs);\n runtime.registerAdapter(new MCPClientAdapter(client));\n\n return { transport };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/security/ssrf.ts","../src/security/sandbox.ts","../src/api/extension/contextRunner.ts","../src/api/extension/dynamicImportAdapter.ts","../src/api/extension/loadToolYaml.ts","../src/api/extension/registerFromManifest.ts","../src/api/extension/resolvePackageRoot.ts","../src/api/extension/registerExtension.ts","../src/api/extension/createExtension.ts","../src/api/extension/generateExtensionManifest.ts","../src/api/extension/groupPrefix.ts","../src/tools/mcp/MCPClientAdapter.ts","../src/tools/mcp/connectMCP.ts","../src/tools/mcp/MCPProcessManager.ts","../src/tools/mcp/registerMCPTools.ts"],"names":["path","existsSync","readFileSync","fileURLToPath","dirname","basename"],"mappings":";;;;;;;;;;;;;;;;;;AAsBA,eAAsB,WAAA,CAAY,KAAa,OAAA,EAA2C;AACxF,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAI,IAAI,GAAG,CAAA;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,iBAAA;AAAA,MACJ,sBAAA;AAAA,MACA,gBAAgB,GAAG,CAAA,CAAA;AAAA,MACnB,EAAE,GAAA;AAAI,KACR;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,CAAO,QAAA,KAAa,OAAA,IAAW,MAAA,CAAO,aAAa,QAAA,EAAU;AAC/D,IAAA,MAAM,iBAAA;AAAA,MACJ,sBAAA;AAAA,MACA,CAAA,sBAAA,EAAyB,OAAO,QAAQ,CAAA,sCAAA,CAAA;AAAA,MACxC,EAAE,GAAA,EAAK,QAAA,EAAU,MAAA,CAAO,QAAA;AAAS,KACnC;AAAA,EACF;AAEA,EAAA,MAAM,WAAW,MAAA,CAAO,QAAA;AAExB,EAAA,IAAI,CAAC,aAAA,CAAc,QAAA,EAAU,OAAA,CAAQ,YAAY,CAAA,EAAG;AAClD,IAAA,MAAM,iBAAA;AAAA,MACJ,sBAAA;AAAA,MACA,SAAS,QAAQ,CAAA,kCAAA,CAAA;AAAA,MACjB,EAAE,GAAA,EAAK,QAAA,EAAU,YAAA,EAAc,QAAQ,YAAA;AAAa,KACtD;AAAA,EACF;AACA,EAAA,IAAI,aAAA,CAAc,QAAA,EAAU,OAAA,CAAQ,YAAY,CAAA,EAAG;AACjD,IAAA,MAAM,iBAAA;AAAA,MACJ,sBAAA;AAAA,MACA,SAAS,QAAQ,CAAA,8BAAA,CAAA;AAAA,MACjB,EAAE,GAAA,EAAK,QAAA,EAAU,YAAA,EAAc,QAAQ,YAAA;AAAa,KACtD;AAAA,EACF;AAGA,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,MAAM,OAAO,QAAQ,CAAA;AACzC,IAAA,IAAI,kBAAA,CAAmB,OAAA,EAAS,OAAA,CAAQ,YAAY,CAAA,EAAG;AACrD,MAAA,MAAM,iBAAA;AAAA,QACJ,sBAAA;AAAA,QACA,CAAA,MAAA,EAAS,QAAQ,CAAA,0BAAA,EAA6B,OAAO,CAAA,CAAA;AAAA,QACrD,EAAE,GAAA,EAAK,QAAA,EAAU,UAAA,EAAY,OAAA;AAAQ,OACvC;AAAA,IACF;AAAA,EACF,SAAS,GAAA,EAAK;AAEZ,IAAA,IAAI,GAAA,YAAe,KAAA,IAAU,GAAA,CAAY,IAAA,KAAS,sBAAA,EAAwB;AACxE,MAAA,MAAM,GAAA;AAAA,IACR;AAEA,IAAA,MAAM,iBAAA;AAAA,MACJ,sBAAA;AAAA,MACA,CAAA,gCAAA,EAAmC,QAAQ,CAAA,GAAA,EAAM,GAAA,YAAe,QAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA,CAAA;AAAA,MACjG,EAAE,KAAK,QAAA;AAAS,KAClB;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAMA,SAAS,aAAA,CAAc,UAAkB,YAAA,EAAiC;AACxE,EAAA,KAAA,MAAW,WAAW,YAAA,EAAc;AAClC,IAAA,IAAI,YAAY,GAAA,EAAK;AACnB,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,IAAI,CAAA,EAAG;AAC5B,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAA;AAC9B,MAAA,IAAI,QAAA,CAAS,SAAS,MAAM,CAAA,IAAK,aAAa,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,EAAG;AAC9D,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF,CAAA,MAAA,IAAW,aAAa,OAAA,EAAS;AAC/B,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAKA,SAAS,aAAA,CAAc,UAAkB,YAAA,EAAiC;AACxE,EAAA,KAAA,MAAW,WAAW,YAAA,EAAc;AAClC,IAAA,IAAI,YAAY,GAAA,EAAK;AACnB,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,IAAI,CAAA,EAAG;AAC5B,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAA;AAC9B,MAAA,IAAI,QAAA,CAAS,SAAS,MAAM,CAAA,IAAK,aAAa,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,EAAG;AAC9D,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF,CAAA,MAAA,IAAW,aAAa,OAAA,EAAS;AAC/B,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,kBAAA,CAAmB,IAAY,KAAA,EAA0B;AAEvE,EAAA,MAAM,YAAA,GAAe,YAAY,EAAE,CAAA;AACnC,EAAA,IAAI,CAAC,cAAc,OAAO,KAAA;AAE1B,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AAEtB,MAAA,IAAI,CAAC,EAAA,CAAG,QAAA,CAAS,GAAG,CAAA,EAAG;AACvB,MAAA,IAAI,YAAA,CAAa,EAAA,EAAI,IAAI,CAAA,EAAG,OAAO,IAAA;AAAA,IACrC,CAAA,MAAO;AACL,MAAA,IAAI,YAAA,CAAa,YAAA,EAAc,IAAI,CAAA,EAAG,OAAO,IAAA;AAAA,IAC/C;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,YAAY,EAAA,EAA2B;AAE9C,EAAA,IAAI,EAAA,CAAG,UAAA,CAAW,SAAS,CAAA,EAAG;AAC5B,IAAA,OAAO,EAAA,CAAG,MAAM,CAAC,CAAA;AAAA,EACnB;AAEA,EAAA,IAAI,sBAAA,CAAuB,IAAA,CAAK,EAAE,CAAA,EAAG;AACnC,IAAA,OAAO,EAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,YAAA,CAAa,IAAY,IAAA,EAAuB;AACvD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AAC1C,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,SAAA,EAAW,OAAO,KAAA;AAElC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,SAAA,EAAW,EAAE,CAAA;AACrC,EAAA,IAAI,MAAM,MAAM,CAAA,IAAK,SAAS,CAAA,IAAK,MAAA,GAAS,IAAI,OAAO,KAAA;AAEvD,EAAA,MAAM,KAAA,GAAQ,UAAU,EAAE,CAAA;AAC1B,EAAA,MAAM,OAAA,GAAU,UAAU,MAAM,CAAA;AAChC,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAA,KAAY,IAAA,EAAM,OAAO,KAAA;AAE/C,EAAA,MAAM,OAAO,MAAA,KAAW,CAAA,GAAI,IAAK,EAAC,IAAM,KAAK,MAAA,KAAa,CAAA;AAC1D,EAAA,OAAA,CAAQ,KAAA,GAAQ,WAAW,OAAA,GAAU,IAAA,CAAA;AACvC;AAEA,SAAS,UAAU,EAAA,EAA2B;AAC5C,EAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,KAAA,CAAM,GAAG,CAAA;AAC1B,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAC/B,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,CAAA,GAAI,QAAA,CAAS,IAAA,EAAM,EAAE,CAAA;AAC3B,IAAA,IAAI,MAAM,CAAC,CAAA,IAAK,IAAI,CAAA,IAAK,CAAA,GAAI,KAAK,OAAO,IAAA;AACzC,IAAA,GAAA,GAAO,OAAO,CAAA,GAAK,CAAA;AAAA,EACrB;AACA,EAAA,OAAO,GAAA,KAAQ,CAAA;AACjB;AAEA,SAAS,YAAA,CAAa,IAAY,IAAA,EAAuB;AAEvD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AAC1C,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,SAAA,EAAW,OAAO,KAAA;AAElC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,SAAA,EAAW,EAAE,CAAA;AACrC,EAAA,IAAI,KAAA,CAAM,MAAM,CAAA,EAAG,OAAO,KAAA;AAE1B,EAAA,MAAM,OAAA,GAAU,WAAW,EAAE,CAAA;AAC7B,EAAA,MAAM,SAAA,GAAY,WAAW,MAAM,CAAA;AACnC,EAAA,IAAI,CAAC,OAAA,IAAW,CAAC,SAAA,EAAW,OAAO,KAAA;AAGnC,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACvC,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,SAAA,IAAa,CAAA,GAAI,IAAI,CAAA,EAAA,EAAK;AAC5C,IAAA,IAAI,QAAQ,CAAC,CAAA,KAAM,SAAA,CAAU,CAAC,GAAG,OAAO,KAAA;AAAA,EAC1C;AAEA,EAAA,MAAM,gBAAgB,MAAA,GAAS,CAAA;AAC/B,EAAA,IAAI,aAAA,GAAgB,CAAA,IAAK,SAAA,GAAY,EAAA,EAAI;AACvC,IAAA,MAAM,IAAA,GAAQ,EAAC,IAAM,CAAA,GAAI,aAAA,GAAkB,GAAA;AAC3C,IAAA,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA,GAAK,IAAA,OAAW,UAAU,SAAS,CAAA,GAAK,OAAO,OAAO,KAAA;AAAA,EAC9E;AAEA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,WAAW,EAAA,EAA6B;AAE/C,EAAA,MAAM,OAAA,GAAU,EAAA,CAAG,OAAA,CAAQ,GAAG,CAAA;AAC9B,EAAA,IAAI,YAAY,EAAA,EAAI,EAAA,GAAK,EAAA,CAAG,KAAA,CAAM,GAAG,OAAO,CAAA;AAE5C,EAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,KAAA,CAAM,IAAI,CAAA;AAC3B,EAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,OAAO,IAAA;AAE7B,EAAA,MAAM,QAAkB,IAAI,KAAA,CAAM,EAAE,CAAA,CAAE,KAAK,CAAC,CAAA;AAE5C,EAAA,MAAM,WAAA,GAAc,CAAC,KAAA,KAA4B;AAC/C,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAC;AACpB,IAAA,OAAO,MAAM,KAAA,CAAM,GAAG,CAAA,CAAE,OAAA,CAAQ,CAAC,GAAA,KAAQ;AACvC,MAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,IAAO,GAAA,EAAK,EAAE,CAAA;AACnC,MAAA,OAAO,CAAE,GAAA,IAAO,CAAA,GAAK,GAAA,EAAM,MAAM,GAAI,CAAA;AAAA,IACvC,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,KAAA,CAAM,CAAC,CAAE,CAAA;AACtC,IAAA,IAAI,QAAA,CAAS,MAAA,KAAW,EAAA,EAAI,OAAO,IAAA;AACnC,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,KAAA,CAAM,CAAC,CAAE,CAAA;AAClC,EAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,CAAC,CAAE,CAAA;AAEnC,EAAA,IAAI,IAAA,CAAK,MAAA,GAAS,KAAA,CAAM,MAAA,GAAS,IAAI,OAAO,IAAA;AAE5C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,EAAQ,KAAK,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA;AACvD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,EAAQ,CAAA,EAAA,EAAK,KAAA,CAAM,EAAA,GAAK,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,GAAI,MAAM,CAAC,CAAA;AAE7E,EAAA,OAAO,KAAA;AACT;AC3OA,eAAsB,oBAAA,CACpB,WACA,WAAA,EACiB;AAGjB,EAAA,IAAI,cAAA;AACJ,EAAA,IAAI;AACF,IAAA,cAAA,GAAiB,MAAM,QAAA,CAAS,OAAA,CAAQ,WAAW,CAAC,CAAA;AAAA,EACtD,CAAA,CAAA,MAAQ;AACN,IAAA,cAAA,GAAiB,SAAA,CAAU,OAAA,CAAQ,WAAW,CAAC,CAAA;AAAA,EACjD;AAGA,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,cAAA,EAAgB,SAAS,CAAA;AAElD,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AAEF,IAAA,MAAM,OAAO,QAAQ,CAAA;AACrB,IAAA,IAAA,GAAO,MAAM,SAAS,QAAQ,CAAA;AAAA,EAChC,CAAA,CAAA,MAAQ;AAEN,IAAA,MAAM,SAAA,GAAY,QAAQ,QAAQ,CAAA;AAClC,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,SAAS,CAAA;AACtB,MAAA,UAAA,GAAa,MAAM,SAAS,SAAS,CAAA;AAAA,IACvC,CAAA,CAAA,MAAQ;AAGN,MAAA,UAAA,GAAa,UAAU,SAAS,CAAA;AAAA,IAClC;AACA,IAAA,IAAA,GAAO,OAAA,CAAQ,UAAA,EAAY,QAAA,CAAS,QAAQ,CAAC,CAAA;AAAA,EAC/C;AAEA,EAAA,IAAI,CAAC,YAAA,CAAa,IAAA,EAAM,cAAc,CAAA,EAAG;AACvC,IAAA,MAAM,iBAAA;AAAA,MACJ,sBAAA;AAAA,MACA,CAAA,MAAA,EAAS,SAAS,CAAA,eAAA,EAAkB,IAAI,+BAA+B,cAAc,CAAA,CAAA,CAAA;AAAA,MACrF,EAAE,SAAA,EAAW,YAAA,EAAc,IAAA,EAAM,aAAa,cAAA;AAAe,KAC/D;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,YAAA,CAAaA,OAAc,IAAA,EAAuB;AACzD,EAAA,MAAM,cAAA,GAAiB,UAAUA,KAAI,CAAA;AACrC,EAAA,MAAM,cAAA,GAAiB,UAAU,IAAI,CAAA;AACrC,EAAA,OAAO,cAAA,KAAmB,cAAA,IAAkB,cAAA,CAAe,UAAA,CAAW,iBAAiB,GAAG,CAAA;AAC5F;AC/CO,SAAS,mBAAA,GAA2C;AACzD,EAAA,MAAM,OAAA,GAAU,IAAI,iBAAA,EAAqB;AACzC,EAAA,OAAO;AAAA,IACL,OAAA,CAAQ,KAAQ,EAAA,EAA8C;AAC5D,MAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,EAAE,CAAA;AAAA,IAC5B,CAAA;AAAA,IACA,UAAA,GAAgB;AACd,MAAA,MAAM,GAAA,GAAM,QAAQ,QAAA,EAAS;AAC7B,MAAA,IAAI,QAAQ,MAAA,EAAW;AACrB,QAAA,MAAM,IAAI,MAAM,uEAAuE,CAAA;AAAA,MACzF;AACA,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,GACF;AACF;ACHO,SAAS,2BACd,OAAA,EACa;AACb,EAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,mBAAA,EAAqB,eAAc,GAAI,OAAA;AAClE,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,MAAM,MAAA,CACJ,IAAA,EACA,IAAA,EACA,OAAA,EAC6C;AAC7C,MAAA,MAAM,OAAO,IAAA,CAAK,KAAA;AAKlB,MAAA,MAAM,aAAa,IAAA,EAAM,UAAA;AACzB,MAAA,MAAM,aAAa,IAAA,EAAM,UAAA;AACzB,MAAA,IAAI,CAAC,UAAA,IAAc,CAAC,UAAA,EAAY;AAC9B,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,IAAA,CAAK,IAAI,CAAA,6CAAA,CAA+C,CAAA;AAAA,MAC5F;AACA,MAAA,MAAM,WAAA,GAAc,IAAA,EAAM,WAAA,IAAe,EAAC;AAC1C,MAAA,MAAM,UAAA,GACJ,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA,CAAE,MAAA,KAAW,CAAA,GAC/B,IAAA,GACD,EAAE,GAAG,WAAA,EAAa,GAAI,IAAA,EAAiC;AAC7D,MAAA,MAAM,aAAaA,KAAA,CAAK,IAAA,CAAK,WAAA,EAAa,CAAA,EAAG,UAAU,CAAA,GAAA,CAAK,CAAA;AAC5D,MAAA,MAAM,GAAA,GAAM,MAAM,OAAO,aAAA,CAAc,UAAU,CAAA,CAAE,IAAA,CAAA;AACnD,MAAA,MAAM,OAAA,GAAU,IAAI,UAAU,CAAA;AAC9B,MAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AACjC,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,kBAAkB,IAAA,CAAK,IAAI,CAAA,UAAA,EAAa,UAAU,UAAU,UAAU,CAAA,kBAAA;AAAA,SACxE;AAAA,MACF;AACA,MAAA,MAAM,GAAA,GAAM,mBAAA,CAAoB,OAAA,EAAS,IAAI,CAAA;AAC7C,MAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,OAAA,CAAQ,KAAK,MAAM,OAAA,CAAQ,UAAU,CAAC,CAAA;AACzE,MAAA,OAAO,EAAE,QAAQ,MAAA,CAAO,MAAA,EAAQ,KAAK,EAAE,QAAA,EAAU,MAAA,CAAO,QAAA,EAAS,EAAE;AAAA,IACrE;AAAA,GACF;AACF;AC9CO,SAAS,YAAA,CACd,aACA,UAAA,EACqC;AACrC,EAAA,MAAM,GAAA,GAAMA,KAAAA,CAAK,OAAA,CAAQ,UAAU,CAAA;AACnC,EAAA,MAAM,IAAA,GAAOA,KAAAA,CAAK,QAAA,CAAS,UAAU,CAAA;AACrC,EAAA,MAAM,WAAWA,KAAAA,CAAK,IAAA,CAAK,aAAa,GAAA,EAAK,CAAA,EAAG,IAAI,CAAA,UAAA,CAAY,CAAA;AAChE,EAAA,IAAI,CAAC,UAAA,CAAW,QAAQ,CAAA,EAAG,OAAO,MAAA;AAClC,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAC1C,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA;AAC1B,IAAA,IAAI,IAAA,IAAQ,QAAQ,OAAO,IAAA,KAAS,YAAY,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG,OAAO,KAAA,CAAA;AAC5E,IAAA,MAAM,GAAA,GAAM,IAAA;AACZ,IAAA,MAAM,OAAO,GAAA,EAAK,IAAA;AAClB,IAAA,MAAM,MAAM,IAAA,EAAM,IAAA;AAClB,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAG,GAAG,OAAO,KAAA,CAAA;AAChC,IAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AAAA,MACf,CAAC,MAAe,CAAA,IAAK,IAAA,IAAQ,OAAO,CAAA,KAAM,QAAA,IAAa,EAA8B,IAAA,KAAS;AAAA,KAChG;AACA,IAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,UAAU,OAAO,KAAA,CAAA;AAC9C,IAAA,MAAM,EAAE,IAAA,EAAM,EAAA,EAAI,GAAG,MAAK,GAAI,IAAA;AAC9B,IAAA,IAAI,OAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,KAAW,GAAG,OAAO,KAAA,CAAA;AAC3C,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;;;ACCO,SAAS,sBAAsB,iBAAA,EAAoD;AACxF,EAAA,MAAM,CAAA,GAAIA,KAAAA,CAAK,OAAA,CAAQ,iBAAiB,CAAA;AACxC,EAAA,IAAI,YAAA;AACJ,EAAA,IAAIC,WAAW,CAAC,CAAA,IAAK,SAAS,CAAC,CAAA,CAAE,QAAO,EAAG;AACzC,IAAA,YAAA,GAAe,CAAA;AAAA,EACjB,CAAA,MAAO;AACL,IAAA,MAAM,KAAA,GAAQD,KAAAA,CAAK,IAAA,CAAK,CAAA,EAAG,0BAA0B,CAAA;AACrD,IAAA,MAAM,MAAA,GAASA,KAAAA,CAAK,IAAA,CAAK,CAAA,EAAG,QAAQ,0BAA0B,CAAA;AAC9D,IAAA,YAAA,GAAeC,UAAAA,CAAW,KAAK,CAAA,GAAI,KAAA,GAAQ,MAAA;AAAA,EAC7C;AACA,EAAA,MAAM,GAAA,GAAMC,YAAAA,CAAa,YAAA,EAAc,OAAO,CAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AACzB,IAAA,OAAO,EAAE,SAAS,MAAA,EAAO;AAAA,EAC3B;AACA,EAAA,OAAO,EAAE,MAAM,MAAA,CAAO,IAAA,EAAM,SAAS,MAAA,CAAO,KAAA,IAAS,EAAC,EAAE;AAC1D;AAMO,SAAS,yBAAA,CACd,UACA,OAAA,EACY;AACZ,EAAA,MAAM,EAAE,iBAAA,EAAmB,IAAA,EAAM,SAAS,IAAA,EAAM,YAAA,EAAc,aAAY,GAAI,OAAA;AAC9E,EAAA,MAAM,MAAA,GAAS,sBAAsB,iBAAiB,CAAA;AACtD,EAAA,MAAM,IAAA,GAAQ,OAAA,IAAW,MAAA,CAAO,IAAA,IAAQ,WAAA;AACxC,EAAA,MAAM,UAAU,MAAA,CAAO,OAAA;AACvB,EAAA,MAAM,UAAU,IAAA,EAAM,MAAA,GAAS,IAAI,GAAA,CAAI,IAAI,CAAA,GAAI,IAAA;AAC/C,EAAA,MAAM,aAAyB,EAAC;AAEhC,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,IAAI,OAAO,cAAA,CAAe;AAAA,MACxB,MAAM,KAAA,CAAM,QAAA;AAAA,MACZ,IAAA;AAAA,MACA,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,cAAc,KAAA,CAAM,YAAA;AAAA,MACpB,cAAc,EAAC;AAAA,MACf,YAAY,KAAA,CAAM;AAAA,KACnB,CAAA;AACD,IAAA,IAAI,WAAW,CAAC,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAG;AACxC,IAAA,IAAI,YAAA,EAAc,MAAA,IAAU,CAAC,YAAA,CAAa,IAAA,CAAK,CAAC,MAAA,KAAW,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,MAAM,CAAC,CAAA,EAAG;AACxF,MAAA;AAAA,IACF;AACA,IAAA,MAAM,cACJ,WAAA,IAAe,IAAA,GAAO,aAAa,WAAA,EAAa,KAAA,CAAM,UAAU,CAAA,GAAI,MAAA;AACtE,IAAA,IAAA,GAAO;AAAA,MACL,GAAG,IAAA;AAAA,MACH,KAAA,EAAO;AAAA,QACL,GAAG,IAAA,CAAK,KAAA;AAAA,QACR,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,GAAI,WAAA,IAAe,IAAA,IAAQ,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA,CAAE,MAAA,GAAS,CAAA,IAAK,EAAE,WAAA;AAAY;AAClF,KACF;AACA,IAAA,QAAA,CAAS,SAAS,IAAI,CAAA;AACtB,IAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,EACtB;AACA,EAAA,OAAO,UAAA;AACT;ACpGO,SAAS,4BAA4B,aAAA,EAA+B;AACzE,EAAA,MAAM,GAAA,GAAM,aAAA,CAAc,UAAA,CAAW,OAAO,CAAA,GACxCF,KAAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,aAAa,CAAC,CAAA,GACzCA,KAAAA,CAAK,QAAQ,aAAa,CAAA;AAC9B,EAAA,MAAM,IAAA,GAAOA,KAAAA,CAAK,IAAA,CAAK,GAAA,EAAK,MAAM,CAAA;AAClC,EAAA,OAAOC,UAAAA,CAAW,IAAI,CAAA,GAAI,IAAA,GAAO,GAAA;AACnC;;;ACkBO,SAAS,iBAAA,CACd,UACA,OAAA,EACa;AACb,EAAA,MAAM,EAAE,aAAa,IAAA,EAAM,OAAA,EAAS,QAAQ,gBAAA,EAAkB,IAAA,EAAM,cAAa,GAAI,OAAA;AACrF,EAAA,MAAM,WAAA,GAAc,4BAA4B,WAAW,CAAA;AAC3D,EAAA,MAAM,gBAAgB,gBAAA,EAAiB;AACvC,EAAA,MAAM,MAAA,GAAS,sBAAsB,WAAW,CAAA;AAChD,EAAA,MAAM,IAAA,GAAO,OAAA,IAAW,MAAA,CAAO,IAAA,IAAQ,WAAA;AAEvC,EAAA,yBAAA,CAA0B,QAAA,EAAU;AAAA,IAClC,iBAAA,EAAmB,WAAA;AAAA,IACnB,IAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,UAAU,0BAAA,CAAqC;AAAA,IACnD,IAAA;AAAA,IACA,WAAA;AAAA,IACA,mBAAA,EAAqB,CAAC,OAAA,EAAsB,IAAA,MACzC;AAAA,MACC,OAAA;AAAA,MACA,QAAS,MAAA,KAAW,MAAA,GAChB,EAAE,GAAI,QAAoC,GAAK,IAAA,CAAK,KAAA,EAAiE,WAAA,IAAe,EAAC,EAAG,GACtI,IAAA,CAAK,KAAA,EAAiE,eAAe;AAAC,KAC9F,CAAA;AAAA,IACF,aAAA,EAAe;AAAA,MACb,OAAA,CAAQ,KAAe,EAAA,EAAwC;AAC7D,QAAA,OAAO,aAAA,CAAc,OAAA,CAAQ,GAAA,EAAK,EAAE,CAAA;AAAA,MACtC;AAAA;AACF,GACD,CAAA;AACD,EAAA,OAAO,OAAA;AACT;;;ACXA,SAAS,mBAAmB,OAAA,EAAwE;AAClG,EAAA,IAAI,QAAQ,WAAA,IAAe,IAAA,IAAQ,QAAQ,WAAA,KAAgB,EAAA,SAAW,OAAA,CAAQ,WAAA;AAC9E,EAAA,IAAI,OAAA,CAAQ,UAAA,EAAY,GAAA,EAAK,OAAOD,KAAAA,CAAK,QAAQG,aAAAA,CAAc,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAC,CAAA;AACtF,EAAA,MAAM,IAAI,MAAM,oDAAoD,CAAA;AACtE;AAEO,SAAS,gBACd,OAAA,EAC6C;AAC7C,EAAA,MAAM,WAAA,GAAc,mBAAmB,OAAO,CAAA;AAC9C,EAAA,MAAM,OAAO,OAAA,CAAQ,IAAA;AACrB,EAAA,MAAM,WAAA,GAAc,aAAA,IAAiB,OAAA,GAAU,OAAA,CAAQ,WAAA,GAAc,MAAA;AAErE,EAAA,MAAM,gBAAgB,mBAAA,EAAyB;AAE/C,EAAA,OAAO;AAAA,IACL,QAAA,CAAS,QAAA,EAAU,gBAAA,EAAkB,IAAA,EAAM;AACzC,MAAA,MAAM,MAAA,GAAS,WAAA,GACV,WAAA,CAA4C,gBAA+B,CAAA,GAC5E,MAAA;AACJ,MAAA,OAAO,kBAAkB,QAAA,EAAU;AAAA,QACjC,WAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAA;AAAA,QACA,kBAAkB,MAAM,aAAA;AAAA,QACxB,IAAA,EAAM,IAAA,EAAM,IAAA,IAAS,gBAAA,EAA6D,IAAA;AAAA,QAClF,YAAA,EAAc,IAAA,EAAM,YAAA,IAAiB,gBAAA,EAA6D;AAAA,OACnG,CAAA;AAAA,IACH,CAAA;AAAA,IACA,UAAA,GAA4C;AAC1C,MAAA,OAAO,cAAc,UAAA,EAAW;AAAA,IAClC,CAAA;AAAA,IACA,OAAA,CAAW,KAAoC,EAAA,EAAkC;AAC/E,MAAA,OAAO,aAAA,CAAc,OAAA,CAAQ,GAAA,EAAK,EAAE,CAAA;AAAA,IACtC;AAAA,GACF;AACF;AC/DO,SAAS,0BACd,WAAA,GAAsB,OAAA,CAAQ,KAAI,EAClC,OAAA,GAA4C,EAAC,EACyB;AACtE,EAAA,MAAM,IAAA,GAAOH,KAAAA,CAAK,OAAA,CAAQ,WAAW,CAAA;AACrC,EAAA,MAAM,MAAA,GAASA,MAAK,OAAA,CAAQ,OAAA,CAAQ,UAAUA,KAAAA,CAAK,IAAA,CAAK,IAAA,EAAM,MAAM,CAAC,CAAA;AACrE,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,MAAA;AAE7B,EAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,YAAA,CAAa;AAAA,IACrC,WAAA,EAAa,IAAA;AAAA,IACb,OAAA,EAAS,OAAA,CAAQ,OAAA,IAAW,CAAC,SAAS,CAAA;AAAA,IACtC,cAAc,OAAA,CAAQ;AAAA,GACvB,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,OAAA,CAAQ,IAAA,CAAK,0CAA0C,MAAM,CAAA;AAAA,EAC/D;AAEA,EAAA,MAAM,OAAA,GAAoC,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AAC5D,IAAA,MAAM,mBAAmB,IAAA,CAAK,UAAA,IAAc,EAAA,EAAI,OAAA,CAAQ,gBAAgB,EAAE,CAAA;AAC1E,IAAA,MAAM,QAAA,GAAW,GAAG,IAAI,CAAA,CAAA,EAAI,gBAAgB,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAC,CAAA,CAAA;AAC/D,IAAA,MAAM,UAAA,GACH,IAAA,CAAK,KAAA,EAAO,IAAA,EAAM,UAAA,IAAiC,MAAA;AACtD,IAAA,OAAO;AAAA,MACL,QAAA;AAAA,MACA,WAAA,EAAa,KAAK,WAAA,IAAe,eAAA;AAAA,MACjC,aAAa,IAAA,CAAK,WAAA,IAAe,EAAE,IAAA,EAAM,QAAA,EAAU,sBAAsB,IAAA,EAAK;AAAA,MAC9E,cAAc,IAAA,CAAK,YAAA,IAAgB,EAAE,IAAA,EAAM,QAAA,EAAU,sBAAsB,IAAA,EAAK;AAAA,MAChF,UAAA,EAAY,eAAA;AAAA,MACZ,UAAA,EAAY,KAAK,UAAA,IAAc,EAAA;AAAA,MAC/B;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAI,CAACC,WAAW,MAAM,CAAA,YAAa,MAAA,EAAQ,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAC9D,EAAA,MAAM,YAAA,GAAeD,KAAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,0BAA0B,CAAA;AACjE,EAAA,aAAA;AAAA,IACE,YAAA;AAAA,IACA,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,OAAO,OAAA,EAAQ,EAAG,MAAM,CAAC,CAAA;AAAA,IAChD;AAAA,GACF;AAEA,EAAA,IAAI,cAAA,GAAiB,CAAA;AACrB,EAAA,MAAM,WAAW,OAAA,CAAQ,gBAAA;AACzB,EAAA,IAAI,UAAU,MAAA,EAAQ;AACpB,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,MAAA,MAAM,MAAA,GAASA,KAAAA,CAAK,IAAA,CAAK,IAAA,EAAM,CAAC,CAAA;AAChC,MAAA,MAAM,OAAA,GAAUA,KAAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,CAAC,CAAA;AACnC,MAAA,IAAI,CAACC,UAAAA,CAAW,MAAM,CAAA,EAAG;AACzB,MAAA,IAAI;AACF,QAAA,KAAA,MAAW,KAAK,WAAA,CAAY,MAAA,EAAQ,EAAE,aAAA,EAAe,IAAA,EAAM,CAAA,EAAG;AAC5D,UAAA,IAAI,EAAE,MAAA,EAAO,IAAK,EAAE,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA,EAAG;AAC/C,YAAA,IAAI,CAACA,WAAW,OAAO,CAAA,YAAa,OAAA,EAAS,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAChE,YAAA,YAAA,CAAaD,KAAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,CAAA,CAAE,IAAI,CAAA,EAAGA,KAAAA,CAAK,IAAA,CAAK,OAAA,EAAS,CAAA,CAAE,IAAI,CAAC,CAAA;AAClE,YAAA,cAAA,EAAA;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,YAAA,EAAc,UAAA,EAAY,OAAA,CAAQ,QAAQ,cAAA,EAAe;AACpE;;;ACxEO,SAAS,qBAAqB,OAAA,EAAuD;AAC1F,EAAA,MAAM,EAAE,MAAA,EAAQ,IAAA,EAAM,cAAA,EAAe,GAAI,OAAA;AACzC,EAAA,MAAM,UAAU,IAAA,EAAM,MAAA,GAAS,IAAI,GAAA,CAAI,IAAI,CAAA,GAAI,IAAA;AAC/C,EAAA,MAAM,YAAA,GACJ,CAAC,OAAA,IAAW,MAAA,EAAQ,SAAS,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,eAAe,CAAC,CAAC,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,GAAI,MAAA;AACtF,EAAA,OAAO;AAAA,IACL,GAAI,UAAU,EAAE,IAAA,EAAM,MAAM,IAAA,CAAK,OAAO,CAAA,EAAE,GAAI,EAAC;AAAA,IAC/C,GAAI,YAAA,EAAc,MAAA,GAAS,EAAE,YAAA,KAAiB;AAAC,GACjD;AACF;;;ACXA,SAAS,uBAAuB,MAAA,EAAgC;AAC9D,EAAA,IAAI,MAAA,CAAO,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,QAAQ,MAAA,CAAO,OAAA,CAClB,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,MAAA,IAAU,CAAA,CAAE,QAAQ,IAAI,CAAA,CACjD,IAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AACpB,IAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EAC1C;AACA,EAAA,IAAI,OAAO,UAAA,KAAe,MAAA,SAAkB,IAAA,CAAK,SAAA,CAAU,OAAO,UAAU,CAAA;AAC5E,EAAA,OAAO,IAAA,CAAK,UAAU,MAAM,CAAA;AAC9B;AAMO,IAAM,mBAAN,MAA8C;AAAA,EAGnD,YAA6B,MAAA,EAAuB;AAAvB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAAwB;AAAA,EAF5C,IAAA,GAAO,QAAA;AAAA,EAIhB,MAAM,MAAA,CACJ,IAAA,EACA,IAAA,EACA,IAAA,EAC6C;AAC7C,IAAA,MAAM,MAAA,GAAS,IAAA,IAAQ,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,GACzE,IAAA,GACD,EAAC;AACL,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,MAAA,CAAO,QAAA,CAAS,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,SAAA,EAAW,MAAA,EAAQ,CAAA;AAChF,IAAA,MAAM,IAAA,GAAO,uBAAuB,MAAM,CAAA;AAC1C,IAAA,IAAI,WAAA,GAAuB,IAAA;AAC3B,IAAA,IAAI;AACF,MAAA,WAAA,GAAc,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,IAC/B,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,OAAO,EAAE,MAAA,EAAQ,WAAA,EAAa,GAAA,EAAK,MAAA,EAAO;AAAA,EAC5C;AACF;;;ACfA,eAAsB,WAAW,cAAA,EAA8D;AAC7F,EAAA,IAAI,cAAA,CAAe,IAAA,KAAS,OAAA,IAAW,CAAC,eAAe,OAAA,EAAS;AAC9D,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,qEAAA,EAAwE,eAAe,IAAI,CAAA;AAAA,KAC7F;AAAA,EACF;AAEA,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,OAAO,kCAAkC,CAAA;AAClE,EAAA,MAAM,EAAE,oBAAA,EAAqB,GAAI,MAAM,OACrC,2CACF,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,SAAS,cAAA,CAAe,OAAA;AAAA,IACxB,IAAA,EAAM,cAAA,CAAe,IAAA,IAAQ,EAAC;AAAA,IAC9B,KAAK,cAAA,CAAe,GAAA;AAAA,IACpB,KAAK,cAAA,CAAe;AAAA,GACtB;AACA,EAAA,MAAM,SAAA,GAAY,IAAI,oBAAA,CAAqB,YAAY,CAAA;AACvD,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,CAAO,EAAE,MAAM,YAAA,EAAc,OAAA,EAAS,SAAS,CAAA;AAClE,EAAA,MAAM,MAAA,CAAO,QAAQ,SAAS,CAAA;AAC9B,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA;AAAA,GACF;AACF;AAKO,SAAS,gBAAgB,KAAA,EAAiC;AAC/D,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACvB,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,OAAA,EAAS,OAAA;AAAA,IACT,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,CAAA,CAAE,WAAA,IAAe,CAAA,UAAA,EAAa,EAAE,IAAI,CAAA,CAAA;AAAA,IACjD,WAAA,EAAa,EAAE,WAAA,IAAe,oBAAA;AAAA,IAC9B,YAAA,EAAc,qBAAA;AAAA,IACd,cAAc;AAAC,GACjB,CAAE,CAAA;AACJ;;;AC3DO,IAAM,oBAAN,MAAwB;AAAA,EACZ,WAAA,uBAAkB,GAAA,EAA+B;AAAA,EAElE,iBAAA,CAAkB,UAAkB,MAAA,EAA4C;AAC9E,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,QAAQ,CAAA;AAC5C,IAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,IAAA,MAAM,IAAA,GAA0B,OAAO,GAAA,GACnC,EAAE,MAAM,KAAA,EAAO,GAAA,EAAK,MAAA,CAAO,GAAA,EAAI,GAC/B;AAAA,MACE,IAAA,EAAM,OAAA;AAAA,MACN,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,KAAK,MAAA,CAAO,GAAA;AAAA,MACZ,KAAK,MAAA,CAAO;AAAA,KACd;AACJ,IAAA,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,QAAA,EAAU,IAAI,CAAA;AACnC,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,OAAO,QAAA,EAA2B;AAChC,IAAA,OAAO,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,QAAQ,CAAA;AAAA,EACzC;AAAA,EAEA,YAAA,GAAyB;AACvB,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA;AAAA,EACpC;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AAAA,EACzB;AACF;;;ACvBA,eAAsB,0BAAA,CACpB,OAAA,EACA,QAAA,EACA,OAAA,GAAmC,EAAC,EACH;AACjC,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,UAAA,IAAc,OAAA,CAAQ,GAAA,CAAI,mBAAmB,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAI,EAAG,UAAU,CAAA;AACtG,EAAA,MAAM,OAAA,GAAUI,QAAQ,UAAU,CAAA;AAClC,EAAA,MAAM,UAAA,GAAaC,SAAS,UAAU,CAAA;AACtC,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,QAAA;AAErC,EAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,OAAA,EAAS,EAAE,MAAM,QAAA,EAAU,IAAA,EAAM,QAAA,EAAU,UAAA,EAAY,CAAA;AACxF,EAAA,IAAI,CAAC,OAAO,SAAA,EAAW;AACrB,IAAA,MAAM,IAAI,MAAM,mCAAmC,CAAA;AAAA,EACrD;AACA,EAAA,MAAM,OAAA,GAAU,IAAI,iBAAA,EAAkB;AACtC,EAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,iBAAA,CAAkB,QAAA,EAAU,OAAO,SAAS,CAAA;AAE3E,EAAA,MAAM,EAAE,MAAA,EAAQ,SAAA,EAAU,GAAI,MAAM,WAAW,cAAc,CAAA;AAC7D,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,OAAO,SAAA,EAAU;AACzC,EAAA,MAAM,KAAA,GAAQ,gBAAgB,KAAK,CAAA;AACnC,EAAA,QAAA,CAAS,aAAa,KAAK,CAAA;AAC3B,EAAA,OAAA,CAAQ,eAAA,CAAgB,IAAI,gBAAA,CAAiB,MAAM,CAAC,CAAA;AAEpD,EAAA,OAAO,EAAE,SAAA,EAAU;AACrB","file":"index.js","sourcesContent":["import { lookup } from \"node:dns/promises\";\nimport { createTaggedError } from \"../core/runtime/Retry.js\";\n\n/**\n * Options for validateUrl. Unified rule: allow iff host is in allowedHosts AND not in blockedHosts.\n * - \"Default allow all + blocklist\": allowedHosts: [\"*\"], blockedHosts: [\"*.internal\", ...]\n * - \"Default disallow all + allowlist\": allowedHosts: [\"api.github.com\", ...], blockedHosts: []\n */\nexport interface ValidateUrlOptions {\n /** Allow only these hosts. Use [\"*\"] for allow-all. Supports \"*.example.com\", exact host. */\n allowedHosts: string[];\n /** Block these hosts even if allowed. Supports \"*.internal\", exact host. Merged with allowlist. */\n blockedHosts: string[];\n /** CIDR ranges to block (resolved IP). */\n blockedCidrs: string[];\n}\n\n/**\n * Validate a URL: allow iff (host in allowedHosts) AND (host not in blockedHosts). Then check blockedCidrs on resolved IP.\n *\n * @throws HTTP_DISALLOWED_HOST if the URL is blocked\n */\nexport async function validateUrl(url: string, options: ValidateUrlOptions): Promise<URL> {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Invalid URL: ${url}`,\n { url },\n );\n }\n\n // Only allow http/https\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Protocol not allowed: ${parsed.protocol}. Only http: and https: are supported.`,\n { url, protocol: parsed.protocol },\n );\n }\n\n const hostname = parsed.hostname;\n\n if (!isHostAllowed(hostname, options.allowedHosts)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" is not in the allowed hosts list`,\n { url, hostname, allowedHosts: options.allowedHosts },\n );\n }\n if (isHostBlocked(hostname, options.blockedHosts)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" is in the blocked hosts list`,\n { url, hostname, blockedHosts: options.blockedHosts },\n );\n }\n\n // DNS resolve and check against blocked CIDRs\n try {\n const { address } = await lookup(hostname);\n if (isIpInBlockedCidrs(address, options.blockedCidrs)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" resolves to blocked IP: ${address}`,\n { url, hostname, resolvedIp: address },\n );\n }\n } catch (err) {\n // Re-throw our tagged errors\n if (err instanceof Error && (err as any).kind === \"HTTP_DISALLOWED_HOST\") {\n throw err;\n }\n // DNS resolution failure — block by default\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `DNS resolution failed for host \"${hostname}\": ${err instanceof Error ? err.message : String(err)}`,\n { url, hostname },\n );\n }\n\n return parsed;\n}\n\n/**\n * Check if a hostname matches any entry in the allowed hosts list.\n * Supports: exact \"*\" (allow any host), wildcard prefix (e.g. \"*.github.com\"), or exact host.\n */\nfunction isHostAllowed(hostname: string, allowedHosts: string[]): boolean {\n for (const pattern of allowedHosts) {\n if (pattern === \"*\") {\n return true;\n }\n if (pattern.startsWith(\"*.\")) {\n const suffix = pattern.slice(1); // \".github.com\"\n if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {\n return true;\n }\n } else if (hostname === pattern) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a hostname matches any entry in the blocked hosts list (same pattern rules as allowlist).\n */\nfunction isHostBlocked(hostname: string, blockedHosts: string[]): boolean {\n for (const pattern of blockedHosts) {\n if (pattern === \"*\") {\n return true;\n }\n if (pattern.startsWith(\"*.\")) {\n const suffix = pattern.slice(1);\n if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {\n return true;\n }\n } else if (hostname === pattern) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if an IPv4 address falls within any blocked CIDR range.\n */\nexport function isIpInBlockedCidrs(ip: string, cidrs: string[]): boolean {\n // Handle IPv4-mapped IPv6\n const normalizedIp = normalizeIp(ip);\n if (!normalizedIp) return false;\n\n for (const cidr of cidrs) {\n if (cidr.includes(\":\")) {\n // IPv6 CIDR — skip for IPv4 addresses\n if (!ip.includes(\":\")) continue;\n if (isIpv6InCidr(ip, cidr)) return true;\n } else {\n if (isIpv4InCidr(normalizedIp, cidr)) return true;\n }\n }\n return false;\n}\n\nfunction normalizeIp(ip: string): string | null {\n // Handle IPv4-mapped IPv6 (e.g. \"::ffff:127.0.0.1\")\n if (ip.startsWith(\"::ffff:\")) {\n return ip.slice(7);\n }\n // Pure IPv4\n if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(ip)) {\n return ip;\n }\n return null;\n}\n\nfunction isIpv4InCidr(ip: string, cidr: string): boolean {\n const [cidrIp, prefixStr] = cidr.split(\"/\");\n if (!cidrIp || !prefixStr) return false;\n\n const prefix = parseInt(prefixStr, 10);\n if (isNaN(prefix) || prefix < 0 || prefix > 32) return false;\n\n const ipNum = ipv4ToNum(ip);\n const cidrNum = ipv4ToNum(cidrIp);\n if (ipNum === null || cidrNum === null) return false;\n\n const mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0;\n return (ipNum & mask) === (cidrNum & mask);\n}\n\nfunction ipv4ToNum(ip: string): number | null {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let num = 0;\n for (const part of parts) {\n const n = parseInt(part, 10);\n if (isNaN(n) || n < 0 || n > 255) return null;\n num = (num << 8) | n;\n }\n return num >>> 0;\n}\n\nfunction isIpv6InCidr(ip: string, cidr: string): boolean {\n // Simplified IPv6 CIDR matching for common cases (::1, fc00::, fe80::)\n const [cidrIp, prefixStr] = cidr.split(\"/\");\n if (!cidrIp || !prefixStr) return false;\n\n const prefix = parseInt(prefixStr, 10);\n if (isNaN(prefix)) return false;\n\n const ipBytes = expandIpv6(ip);\n const cidrBytes = expandIpv6(cidrIp);\n if (!ipBytes || !cidrBytes) return false;\n\n // Compare prefix bits\n const fullBytes = Math.floor(prefix / 8);\n for (let i = 0; i < fullBytes && i < 16; i++) {\n if (ipBytes[i] !== cidrBytes[i]) return false;\n }\n\n const remainingBits = prefix % 8;\n if (remainingBits > 0 && fullBytes < 16) {\n const mask = (~0 << (8 - remainingBits)) & 0xff;\n if ((ipBytes[fullBytes]! & mask) !== (cidrBytes[fullBytes]! & mask)) return false;\n }\n\n return true;\n}\n\nfunction expandIpv6(ip: string): number[] | null {\n // Remove zone ID\n const zoneIdx = ip.indexOf(\"%\");\n if (zoneIdx !== -1) ip = ip.slice(0, zoneIdx);\n\n const parts = ip.split(\"::\");\n if (parts.length > 2) return null;\n\n const bytes: number[] = new Array(16).fill(0);\n\n const expandGroup = (group: string): number[] => {\n if (!group) return [];\n return group.split(\":\").flatMap((hex) => {\n const val = parseInt(hex || \"0\", 16);\n return [(val >> 8) & 0xff, val & 0xff];\n });\n };\n\n if (parts.length === 1) {\n const expanded = expandGroup(parts[0]!);\n if (expanded.length !== 16) return null;\n return expanded;\n }\n\n const left = expandGroup(parts[0]!);\n const right = expandGroup(parts[1]!);\n\n if (left.length + right.length > 16) return null;\n\n for (let i = 0; i < left.length; i++) bytes[i] = left[i]!;\n for (let i = 0; i < right.length; i++) bytes[16 - right.length + i] = right[i]!;\n\n return bytes;\n}\n","import { resolve, normalize, dirname, basename } from \"node:path\";\nimport { realpath, access } from \"node:fs/promises\";\nimport { createTaggedError } from \"../core/runtime/Retry.js\";\n\n/**\n * Resolve an input path to an absolute path within the sandbox.\n * Throws PATH_OUTSIDE_SANDBOX if the resolved path escapes the sandbox root.\n *\n * For existing files: uses realpath to resolve symlinks.\n * For non-existing files (write targets): resolves the parent directory.\n */\nexport async function resolveSandboxedPath(\n inputPath: string,\n sandboxRoot: string,\n): Promise<string> {\n // Resolve the sandbox root itself with realpath to handle platform symlinks\n // (e.g. macOS /var -> /private/var)\n let normalizedRoot: string;\n try {\n normalizedRoot = await realpath(resolve(sandboxRoot));\n } catch {\n normalizedRoot = normalize(resolve(sandboxRoot));\n }\n\n // Resolve against sandbox root\n const resolved = resolve(normalizedRoot, inputPath);\n\n let real: string;\n try {\n // Try to resolve symlinks for existing paths\n await access(resolved);\n real = await realpath(resolved);\n } catch {\n // Path does not exist — resolve parent to check containment\n const parentDir = dirname(resolved);\n let realParent: string;\n try {\n await access(parentDir);\n realParent = await realpath(parentDir);\n } catch {\n // Parent also doesn't exist — use normalized resolved path\n // (will fail at actual FS operation if truly invalid)\n realParent = normalize(parentDir);\n }\n real = resolve(realParent, basename(resolved));\n }\n\n if (!isWithinRoot(real, normalizedRoot)) {\n throw createTaggedError(\n \"PATH_OUTSIDE_SANDBOX\",\n `Path \"${inputPath}\" resolves to \"${real}\" which is outside sandbox \"${normalizedRoot}\"`,\n { inputPath, resolvedPath: real, sandboxRoot: normalizedRoot },\n );\n }\n\n return real;\n}\n\nfunction isWithinRoot(path: string, root: string): boolean {\n const normalizedPath = normalize(path);\n const normalizedRoot = normalize(root);\n return normalizedPath === normalizedRoot || normalizedPath.startsWith(normalizedRoot + \"/\");\n}\n","/**\n * Generic context injection for extension tools (e.g. builtin).\n * Any extension that needs to inject config (sandbox, allowedHosts, etc.) into handlers uses this.\n */\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport interface ContextRunner<T> {\n runWith(ctx: T, fn: () => Promise<unknown>): Promise<unknown>;\n getContext(): T;\n}\n\n/**\n * Create a context runner for an extension. Handlers call getContext() to read config.\n * Adapter calls runWith(ctx, () => handler(args)) so getContext() returns ctx.\n */\nexport function createContextRunner<T>(): ContextRunner<T> {\n const storage = new AsyncLocalStorage<T>();\n return {\n runWith(ctx: T, fn: () => Promise<unknown>): Promise<unknown> {\n return storage.run(ctx, fn);\n },\n getContext(): T {\n const ctx = storage.getStore();\n if (ctx === undefined) {\n throw new Error(\"Extension context not set; invoke only through the extension adapter.\");\n }\n return ctx;\n },\n };\n}\n","/**\n * Generic adapter for extensions that discover tools via manifest and load handlers by dynamic import.\n * Any extension (builtin, etc.) that uses @tool scan → manifest and runs handlers with injected context uses this.\n */\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { ToolAdapter, ToolSpec } from \"../../core/types/ToolSpec.js\";\nimport type { ExecContext } from \"../../core/types/ToolIntent.js\";\nimport type { Evidence } from \"../../core/types/ToolResult.js\";\n\nexport interface ExtensionToolResult {\n result: unknown;\n evidence: Evidence[];\n}\n\nexport interface DynamicImportAdapterOptions<TContext> {\n kind: string;\n packageRoot: string;\n /** Build context from execCtx and (optional) tool spec. When spec is provided, config can be merged from spec._meta.defaultArgs. */\n getExtensionContext: (execCtx: ExecContext, spec: ToolSpec) => TContext;\n contextRunner: { runWith(ctx: TContext, fn: () => Promise<ExtensionToolResult>): Promise<ExtensionToolResult> };\n}\n\n/**\n * Create an adapter that loads handlers by spec._meta.sourcePath and exportName, then runs with extension context.\n */\nexport function createDynamicImportAdapter<TContext>(\n options: DynamicImportAdapterOptions<TContext>,\n): ToolAdapter {\n const { kind, packageRoot, getExtensionContext, contextRunner } = options;\n return {\n kind: kind as ToolAdapter[\"kind\"],\n async invoke(\n spec: ToolSpec,\n args: unknown,\n execCtx: ExecContext,\n ): Promise<{ result: unknown; raw?: unknown }> {\n const meta = spec._meta as {\n sourcePath?: string;\n exportName?: string;\n defaultArgs?: Record<string, unknown>;\n } | undefined;\n const sourcePath = meta?.sourcePath;\n const exportName = meta?.exportName;\n if (!sourcePath || !exportName) {\n throw new Error(`Extension tool ${spec.name} missing _meta.sourcePath or _meta.exportName`);\n }\n const defaultArgs = meta?.defaultArgs ?? {};\n const mergedArgs =\n Object.keys(defaultArgs).length === 0\n ? (args as Record<string, unknown>)\n : { ...defaultArgs, ...(args as Record<string, unknown>) };\n const modulePath = path.join(packageRoot, `${sourcePath}.js`);\n const mod = await import(pathToFileURL(modulePath).href);\n const handler = mod[exportName];\n if (typeof handler !== \"function\") {\n throw new Error(\n `Extension tool ${spec.name}: export \"${exportName}\" from ${sourcePath} is not a function`,\n );\n }\n const ctx = getExtensionContext(execCtx, spec);\n const output = await contextRunner.runWith(ctx, () => handler(mergedArgs));\n return { result: output.result, raw: { evidence: output.evidence } };\n },\n };\n}\n","/**\n * Load per-tool default args/config from <base>.tool.yaml (framework-defined format).\n *\n * Supported YAML format:\n * tool:\n * list:\n * - name: fetchText\n * timeoutMs: 5000\n * maxBytes: 1048576\n * (find item where name === tool base name, use rest as defaultArgs)\n */\nimport { readFileSync, existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport yaml from \"js-yaml\";\n\n/**\n * Load tool.yaml for a given tool. Path: packageRoot / dirname(sourcePath) / basename(sourcePath).tool.yaml\n * Returns default args (and config) for the tool, or undefined if file missing or no matching entry.\n */\nexport function loadToolYaml(\n packageRoot: string,\n sourcePath: string,\n): Record<string, unknown> | undefined {\n const dir = path.dirname(sourcePath);\n const base = path.basename(sourcePath);\n const yamlPath = path.join(packageRoot, dir, `${base}.tool.yaml`);\n if (!existsSync(yamlPath)) return undefined;\n try {\n const raw = readFileSync(yamlPath, \"utf-8\");\n const data = yaml.load(raw) as unknown;\n if (data == null || typeof data !== \"object\" || Array.isArray(data)) return undefined;\n const obj = data as Record<string, unknown>;\n const list = obj?.tool as Record<string, unknown> | undefined;\n const arr = list?.list;\n if (!Array.isArray(arr)) return undefined;\n const item = arr.find(\n (e: unknown) => e != null && typeof e === \"object\" && (e as Record<string, unknown>).name === base,\n ) as Record<string, unknown> | undefined;\n if (!item || typeof item !== \"object\") return undefined;\n const { name: _n, ...rest } = item;\n if (Object.keys(rest).length === 0) return undefined;\n return rest;\n } catch {\n return undefined;\n }\n}\n","/**\n * Generic manifest-based registration for extensions.\n * Reads a pre-built JSON manifest (extension produces it at build time; agent-tool does not scan @tool).\n * Registers ToolSpecs with the registry. When packageRoot is provided, loads <base>.tool.yaml per tool and sets defaultArgs in _meta.\n */\nimport { readFileSync, existsSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { createToolSpec } from \"../../core/types/ToolSpec.js\";\nimport type { ToolSpec, HitlSideEffect } from \"../../core/types/ToolSpec.js\";\nimport type { ToolRegistry } from \"../../core/registry/ToolRegistry.js\";\nimport { loadToolYaml } from \"./loadToolYaml.js\";\n\n/** Manifest entry shape (convention: extension build emits this, e.g. from @tool scan). */\nexport interface ExtensionManifestEntry {\n coreName: string;\n description: string;\n inputSchema: object;\n outputSchema: object;\n sourcePath: string;\n exportName: string;\n sideEffect: HitlSideEffect;\n}\n\n/** Loaded manifest: entries + optional kind from manifest file. */\nexport interface LoadedExtensionManifest {\n kind?: string;\n entries: ExtensionManifestEntry[];\n}\n\nexport interface RegisterFromManifestOptions {\n /** Path to manifest JSON (or directory containing core-tools-manifest.json). */\n manifestPathOrDir: string;\n /** Tool kind; if omitted, uses manifest.kind or \"extension\". */\n kind?: string;\n /** Filter: only register these tool names. */\n only?: string[];\n /** Filter: only register tools whose name starts with one of these prefixes. */\n namePrefixes?: string[];\n /** Extension package root (e.g. dist); when set, loads <base>.tool.yaml per tool and sets defaultArgs in _meta. */\n packageRoot?: string;\n}\n\n/**\n * Load manifest from path. Supports array or { kind?, tools: ExtensionManifestEntry[] }.\n * Returns entries + optional kind so framework can use dynamic kind from manifest.\n */\nexport function loadExtensionManifest(manifestPathOrDir: string): LoadedExtensionManifest {\n const p = path.resolve(manifestPathOrDir);\n let manifestPath: string;\n if (existsSync(p) && statSync(p).isFile()) {\n manifestPath = p;\n } else {\n const inDir = path.join(p, \"core-tools-manifest.json\");\n const inDist = path.join(p, \"dist\", \"core-tools-manifest.json\");\n manifestPath = existsSync(inDir) ? inDir : inDist;\n }\n const raw = readFileSync(manifestPath, \"utf-8\");\n const parsed = JSON.parse(raw) as ExtensionManifestEntry[] | { kind?: string; tools: ExtensionManifestEntry[] };\n if (Array.isArray(parsed)) {\n return { entries: parsed };\n }\n return { kind: parsed.kind, entries: parsed.tools ?? [] };\n}\n\n/**\n * Register tools from a manifest with the registry. Returns the list of registered specs.\n * Extension packages call this from their register (or equivalent) with their package root.\n */\nexport function registerToolsFromManifest(\n registry: ToolRegistry,\n options: RegisterFromManifestOptions,\n): ToolSpec[] {\n const { manifestPathOrDir, kind: kindOpt, only, namePrefixes, packageRoot } = options;\n const loaded = loadExtensionManifest(manifestPathOrDir);\n const kind = (kindOpt ?? loaded.kind ?? \"extension\") as ToolSpec[\"kind\"];\n const entries = loaded.entries;\n const onlySet = only?.length ? new Set(only) : null;\n const registered: ToolSpec[] = [];\n\n for (const entry of entries) {\n let spec = createToolSpec({\n name: entry.coreName,\n kind,\n description: entry.description,\n inputSchema: entry.inputSchema,\n outputSchema: entry.outputSchema,\n capabilities: [],\n sideEffect: entry.sideEffect,\n });\n if (onlySet && !onlySet.has(spec.name)) continue;\n if (namePrefixes?.length && !namePrefixes.some((prefix) => spec.name.startsWith(prefix))) {\n continue;\n }\n const defaultArgs =\n packageRoot != null ? loadToolYaml(packageRoot, entry.sourcePath) : undefined;\n spec = {\n ...spec,\n _meta: {\n ...spec._meta,\n sourcePath: entry.sourcePath,\n exportName: entry.exportName,\n ...(defaultArgs != null && Object.keys(defaultArgs).length > 0 && { defaultArgs }),\n },\n } as ToolSpec;\n registry.register(spec);\n registered.push(spec);\n }\n return registered;\n}\n","/**\n * Resolve extension package root for dynamic import (dist when built, else dir).\n * Accepts import.meta.url (file:) or a directory path (e.g. __dirname).\n */\nimport path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\n\nexport function resolveExtensionPackageRoot(metaUrlOrPath: string): string {\n const dir = metaUrlOrPath.startsWith(\"file:\")\n ? path.dirname(fileURLToPath(metaUrlOrPath))\n : path.resolve(metaUrlOrPath);\n const dist = path.join(dir, \"dist\");\n return existsSync(dist) ? dist : dir;\n}\n","/**\n * One-shot: load pre-built manifest from package, register all specs, create adapter.\n * Framework does NOT scan source for @tool; it reads manifest (e.g. core-tools-manifest.json)\n * produced by the extension's build. Extension passes packagePath, config, getContextRunner.\n */\nimport type { ToolAdapter } from \"../../core/types/ToolSpec.js\";\nimport type { ToolRegistry } from \"../../core/registry/ToolRegistry.js\";\nimport type { ExecContext } from \"../../core/types/ToolIntent.js\";\nimport type { ContextRunner } from \"./contextRunner.js\";\nimport { createDynamicImportAdapter } from \"./dynamicImportAdapter.js\";\nimport type { ExtensionToolResult } from \"./dynamicImportAdapter.js\";\nimport { registerToolsFromManifest, loadExtensionManifest } from \"./registerFromManifest.js\";\nimport { resolveExtensionPackageRoot } from \"./resolvePackageRoot.js\";\n\nexport interface RegisterExtensionOptions<TContext> {\n /** Package root (e.g. __dirname of extension's entry). Manifest is read from here. */\n packagePath: string;\n /** Tool kind; if omitted, uses manifest.kind or \"extension\". */\n kind?: string;\n /** Optional default config; merged with each tool's tool.yaml (spec._meta.defaultArgs). Context config = { ...config, ...toolDefaultArgs }. */\n config?: unknown;\n /** Returns the context runner (extension's createContextRunner()). */\n getContextRunner: () => ContextRunner<TContext>;\n /** Filter: only register these tool names. */\n only?: string[];\n /** Filter: only register tools whose name starts with one of these prefixes. */\n namePrefixes?: string[];\n}\n\n/**\n * Load manifest from package (pre-built JSON; no @tool scanning). Register all specs, create and return adapter.\n */\nexport function registerExtension<TContext extends { execCtx: ExecContext; config: unknown }>(\n registry: ToolRegistry,\n options: RegisterExtensionOptions<TContext>,\n): ToolAdapter {\n const { packagePath, kind: kindOpt, config, getContextRunner, only, namePrefixes } = options;\n const packageRoot = resolveExtensionPackageRoot(packagePath);\n const contextRunner = getContextRunner();\n const loaded = loadExtensionManifest(packagePath);\n const kind = kindOpt ?? loaded.kind ?? \"extension\";\n\n registerToolsFromManifest(registry, {\n manifestPathOrDir: packagePath,\n kind,\n only,\n namePrefixes,\n packageRoot,\n });\n\n const adapter = createDynamicImportAdapter<TContext>({\n kind,\n packageRoot,\n getExtensionContext: (execCtx: ExecContext, spec: import(\"../../core/types/ToolSpec.js\").ToolSpec) =>\n ({\n execCtx,\n config: (config !== undefined\n ? { ...(config as Record<string, unknown>), ...((spec._meta as { defaultArgs?: Record<string, unknown> } | undefined)?.defaultArgs ?? {}) }\n : ((spec._meta as { defaultArgs?: Record<string, unknown> } | undefined)?.defaultArgs ?? {})) as TContext[\"config\"],\n }) as TContext,\n contextRunner: {\n runWith(ctx: TContext, fn: () => Promise<ExtensionToolResult>) {\n return contextRunner.runWith(ctx, fn) as Promise<ExtensionToolResult>;\n },\n },\n });\n return adapter;\n}\n","/**\n * One-shot extension bootstrap: context runner + register + getContext/runWith.\n * Config can be extension-level (buildConfig) or per-tool only (defaultConfig in opts, merged with tool.yaml).\n */\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ToolAdapter } from \"../../core/types/ToolSpec.js\";\nimport type { ToolRegistry } from \"../../core/registry/ToolRegistry.js\";\nimport { createContextRunner } from \"./contextRunner.js\";\nimport { registerExtension } from \"./registerExtension.js\";\nimport type { ExtensionToolContext } from \"./types.js\";\n\n/** Pass import.meta so the framework derives packagePath (extension entry does not need path/fileURLToPath). */\nexport interface ImportMetaLike {\n url: string;\n}\n\n/** Options when config is built from userConfig (buildConfig). */\nexport interface CreateExtensionOptionsWithBuild<TConfig, TUserConfig> {\n packagePath?: string;\n importMeta?: ImportMetaLike;\n kind?: string;\n buildConfig: (userConfig: TUserConfig) => TConfig;\n}\n\n/** Options when config is per-tool only (each tool's tool.yaml). */\nexport interface CreateExtensionOptionsDefaultOnly {\n packagePath?: string;\n importMeta?: ImportMetaLike;\n kind?: string;\n}\n\n/** Register opts when using per-tool config only: filter tools by name. */\nexport interface RegisterOptionsDefaultOnly {\n only?: string[];\n namePrefixes?: string[];\n}\n\nexport type CreateExtensionOptions<TConfig, TUserConfig> =\n | CreateExtensionOptionsWithBuild<TConfig, TUserConfig>\n | (CreateExtensionOptionsDefaultOnly & { buildConfig?: never });\n\nexport interface CreateExtensionResult<TConfig, TUserConfig> {\n register(\n registry: ToolRegistry,\n userConfigOrOpts: TUserConfig,\n options?: { only?: string[]; namePrefixes?: string[] },\n ): ToolAdapter;\n getContext(): ExtensionToolContext<TConfig>;\n runWith<T>(ctx: ExtensionToolContext<TConfig>, fn: () => Promise<T>): Promise<T>;\n}\n\n/**\n * Create an extension. With buildConfig: register(registry, userConfig, opts?).\n * Without buildConfig: register(registry, opts?) where opts = { only?, namePrefixes? }; config comes only from each tool's tool.yaml.\n */\nfunction resolvePackagePath(options: { packagePath?: string; importMeta?: ImportMetaLike }): string {\n if (options.packagePath != null && options.packagePath !== \"\") return options.packagePath;\n if (options.importMeta?.url) return path.dirname(fileURLToPath(options.importMeta.url));\n throw new Error(\"createExtension: provide packagePath or importMeta\");\n}\n\nexport function createExtension<TConfig = Record<string, unknown>, TUserConfig = RegisterOptionsDefaultOnly>(\n options: CreateExtensionOptions<TConfig, TUserConfig>,\n): CreateExtensionResult<TConfig, TUserConfig> {\n const packagePath = resolvePackagePath(options);\n const kind = options.kind;\n const buildConfig = \"buildConfig\" in options ? options.buildConfig : undefined;\n type Ctx = ExtensionToolContext<TConfig>;\n const contextRunner = createContextRunner<Ctx>();\n\n return {\n register(registry, userConfigOrOpts, opts) {\n const config = buildConfig\n ? (buildConfig as (u: TUserConfig) => TConfig)(userConfigOrOpts as TUserConfig)\n : undefined;\n return registerExtension(registry, {\n packagePath,\n kind,\n config,\n getContextRunner: () => contextRunner,\n only: opts?.only ?? (userConfigOrOpts as RegisterOptionsDefaultOnly | undefined)?.only,\n namePrefixes: opts?.namePrefixes ?? (userConfigOrOpts as RegisterOptionsDefaultOnly | undefined)?.namePrefixes,\n });\n },\n getContext(): ExtensionToolContext<TConfig> {\n return contextRunner.getContext() as ExtensionToolContext<TConfig>;\n },\n runWith<T>(ctx: ExtensionToolContext<TConfig>, fn: () => Promise<T>): Promise<T> {\n return contextRunner.runWith(ctx, fn) as Promise<T>;\n },\n };\n}\n","/**\n * Build step: scan project for @tool, emit extension manifest (core-tools-manifest.json) and copy *.tool.yaml.\n * Extensions run this at build time; agent-tool reads the manifest when the extension's register is called.\n */\nimport { writeFileSync, mkdirSync, existsSync, readdirSync, copyFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { scanForTools } from \"../../tools/function/scanner.js\";\nimport type { ExtensionManifestEntry } from \"./registerFromManifest.js\";\nimport type { HitlSideEffect } from \"../../core/types/ToolSpec.js\";\n\nexport interface GenerateExtensionManifestOptions {\n /** Project root (default: process.cwd()). */\n projectRoot?: string;\n /** Output directory for manifest and copied tool.yaml (default: projectRoot/dist). */\n outDir?: string;\n /** Manifest kind (default: \"core\"). */\n kind?: string;\n /** Include globs for TS files (default: all .ts). */\n include?: string[];\n /** Path to tsconfig (default: projectRoot/tsconfig.json). */\n tsconfigPath?: string;\n /** Subdirs to copy *.tool.yaml from (default: all dirs under projectRoot that contain .tool.yaml). */\n copyToolYamlDirs?: string[];\n}\n\n/**\n * Scan project for @tool, write core-tools-manifest.json and copy *.tool.yaml to outDir.\n * Returns the written manifest path and number of tools.\n */\nexport function generateExtensionManifest(\n projectRoot: string = process.cwd(),\n options: GenerateExtensionManifestOptions = {},\n): { manifestPath: string; toolsCount: number; toolYamlCopied: number } {\n const root = path.resolve(projectRoot);\n const outDir = path.resolve(options.outDir ?? path.join(root, \"dist\"));\n const kind = options.kind ?? \"core\";\n\n const { specs, errors } = scanForTools({\n projectPath: root,\n include: options.include ?? [\"**/*.ts\"],\n tsconfigPath: options.tsconfigPath,\n });\n\n if (errors.length > 0) {\n console.warn(\"generateExtensionManifest: scan errors\", errors);\n }\n\n const entries: ExtensionManifestEntry[] = specs.map((spec) => {\n const sourcePathNoExt = (spec.sourcePath ?? \"\").replace(/\\.(ts|tsx)$/i, \"\");\n const coreName = `${kind}/${sourcePathNoExt.replace(/\\//g, \".\")}`;\n const sideEffect: HitlSideEffect =\n (spec._meta?.hitl?.sideEffect as HitlSideEffect) ?? \"none\";\n return {\n coreName,\n description: spec.description ?? sourcePathNoExt,\n inputSchema: spec.inputSchema ?? { type: \"object\", additionalProperties: true },\n outputSchema: spec.outputSchema ?? { type: \"object\", additionalProperties: true },\n sourcePath: sourcePathNoExt,\n exportName: spec.exportName ?? \"\",\n sideEffect,\n };\n });\n\n if (!existsSync(outDir)) mkdirSync(outDir, { recursive: true });\n const manifestPath = path.join(outDir, \"core-tools-manifest.json\");\n writeFileSync(\n manifestPath,\n JSON.stringify({ kind, tools: entries }, null, 2),\n \"utf-8\",\n );\n\n let toolYamlCopied = 0;\n const copyDirs = options.copyToolYamlDirs;\n if (copyDirs?.length) {\n for (const d of copyDirs) {\n const srcDir = path.join(root, d);\n const destDir = path.join(outDir, d);\n if (!existsSync(srcDir)) continue;\n try {\n for (const e of readdirSync(srcDir, { withFileTypes: true })) {\n if (e.isFile() && e.name.endsWith(\".tool.yaml\")) {\n if (!existsSync(destDir)) mkdirSync(destDir, { recursive: true });\n copyFileSync(path.join(srcDir, e.name), path.join(destDir, e.name));\n toolYamlCopied++;\n }\n }\n } catch {\n // ignore\n }\n }\n }\n\n return { manifestPath, toolsCount: entries.length, toolYamlCopied };\n}\n","/**\n * Convert \"groups\" + \"only\" options and a group→prefix map into only/namePrefixes for registerToolsFromManifest.\n * Extensions define their own group names and prefixes (e.g. fs -> \"core/fs.\").\n */\nexport interface GroupPrefixOptions {\n /** Only register tools in these groups (e.g. [\"fs\", \"http\"]). */\n groups?: string[];\n /** Only register these tool names. Takes precedence over groups. */\n only?: string[];\n /** Map group name -> name prefix (e.g. { fs: \"core/fs.\", http: \"core/http.\" }). */\n groupPrefixMap: Record<string, string>;\n}\n\nexport interface ResolvedOnlyNamePrefixes {\n only?: string[];\n namePrefixes?: string[];\n}\n\n/**\n * Resolve groups/only + groupPrefixMap to only and namePrefixes for registerToolsFromManifest.\n */\nexport function getGroupNamePrefixes(options: GroupPrefixOptions): ResolvedOnlyNamePrefixes {\n const { groups, only, groupPrefixMap } = options;\n const onlySet = only?.length ? new Set(only) : null;\n const namePrefixes =\n !onlySet && groups?.length ? groups.map((g) => groupPrefixMap[g]).filter(Boolean) : undefined;\n return {\n ...(onlySet ? { only: Array.from(onlySet) } : {}),\n ...(namePrefixes?.length ? { namePrefixes } : {}),\n };\n}\n","/**\n * ToolAdapter for MCP tools: holds SDK Client reference, invoke() calls client.callTool.\n * Framework-level support so scripts use registerMCPToolsFromConfig instead of inline MCP logic.\n */\n\nimport type { ToolAdapter, ToolSpec } from \"../../core/types/ToolSpec.js\";\nimport type { ExecContext } from \"../../core/types/ToolIntent.js\";\nimport { MCP_KIND } from \"./types.js\";\n\n/** SDK Client type (avoid hard typing on @modelcontextprotocol/sdk in this file for optional dep). */\nexport interface MCPClientLike {\n callTool(params: { name: string; arguments: Record<string, unknown> }): Promise<CallToolResult>;\n}\n\nexport interface CallToolResult {\n content?: Array<{ type: string; text?: string }>;\n toolResult?: unknown;\n}\n\nfunction textFromCallToolResult(result: CallToolResult): string {\n if (result.content?.length) {\n const parts = result.content\n .filter((c) => c.type === \"text\" && c.text != null)\n .map((c) => c.text);\n if (parts.length) return parts.join(\"\\n\");\n }\n if (result.toolResult !== undefined) return JSON.stringify(result.toolResult);\n return JSON.stringify(result);\n}\n\n/**\n * Adapter that invokes MCP tools via the SDK Client (callTool).\n * Register with runtime after connecting and listing tools; specs must have kind MCP_KIND.\n */\nexport class MCPClientAdapter implements ToolAdapter {\n readonly kind = MCP_KIND;\n\n constructor(private readonly client: MCPClientLike) {}\n\n async invoke(\n spec: ToolSpec,\n args: unknown,\n _ctx: ExecContext\n ): Promise<{ result: unknown; raw?: unknown }> {\n const params = args != null && typeof args === \"object\" && !Array.isArray(args)\n ? (args as Record<string, unknown>)\n : {};\n const result = await this.client.callTool({ name: spec.name, arguments: params });\n const text = textFromCallToolResult(result);\n let resultValue: unknown = text;\n try {\n resultValue = JSON.parse(text) as unknown;\n } catch {\n // keep as string\n }\n return { result: resultValue, raw: result };\n }\n}\n","/**\n * Connect to an MCP server via stdio using MCPConnectionInfo.\n * Framework-level: uses @modelcontextprotocol/sdk Client + StdioClientTransport.\n */\n\nimport type { MCPConnectionInfo } from \"./MCPProcessManager.js\";\nimport type { ToolSpec } from \"../../core/types/ToolSpec.js\";\nimport { DEFAULT_INPUT_SCHEMA, DEFAULT_OUTPUT_SCHEMA } from \"../../core/types/ToolSpec.js\";\nimport { MCP_KIND } from \"./types.js\";\n\nexport interface MCPConnectResult {\n /** SDK Client; use listTools() and callTool(). */\n client: MCPClientLike;\n /** Transport; call close() when done. */\n transport: MCPTransportLike;\n}\n\nexport interface MCPClientLike {\n connect(transport: MCPTransportLike): Promise<void>;\n listTools(params?: unknown): Promise<{ tools: MCPToolDef[] }>;\n callTool(params: { name: string; arguments: Record<string, unknown> }): Promise<CallToolResult>;\n}\n\nexport interface MCPTransportLike {\n close(): Promise<void>;\n}\n\nexport interface MCPToolDef {\n name: string;\n description?: string;\n inputSchema?: object;\n}\n\nexport interface CallToolResult {\n content?: Array<{ type: string; text?: string }>;\n toolResult?: unknown;\n}\n\n/**\n * Connect to MCP server via stdio. Only stdio is supported; url/SSE not implemented here.\n * Requires @modelcontextprotocol/sdk. Returns client and transport; caller must call transport.close() when done.\n */\nexport async function connectMCP(connectionInfo: MCPConnectionInfo): Promise<MCPConnectResult> {\n if (connectionInfo.type !== \"stdio\" || !connectionInfo.command) {\n throw new Error(\n `MCP stdio requires connectionInfo.type \"stdio\" and command; got type=${connectionInfo.type}`\n );\n }\n\n const { Client } = await import(\"@modelcontextprotocol/sdk/client\");\n const { StdioClientTransport } = await import(\n \"@modelcontextprotocol/sdk/client/stdio.js\"\n );\n\n const serverParams = {\n command: connectionInfo.command,\n args: connectionInfo.args ?? [],\n env: connectionInfo.env,\n cwd: connectionInfo.cwd,\n };\n const transport = new StdioClientTransport(serverParams);\n const client = new Client({ name: \"agent-tool\", version: \"1.0.0\" });\n await client.connect(transport);\n return {\n client: client as unknown as MCPClientLike,\n transport: transport as unknown as MCPTransportLike,\n };\n}\n\n/**\n * Convert MCP listTools() result to ToolSpec[] (kind MCP_KIND) for registry.\n */\nexport function mcpToolsToSpecs(tools: MCPToolDef[]): ToolSpec[] {\n return tools.map((t) => ({\n name: t.name,\n version: \"1.0.0\",\n kind: MCP_KIND,\n description: t.description ?? `MCP tool: ${t.name}`,\n inputSchema: t.inputSchema ?? DEFAULT_INPUT_SCHEMA,\n outputSchema: DEFAULT_OUTPUT_SCHEMA,\n capabilities: [],\n }));\n}\n","import type { MCPServerConfig } from \"../discoveryFactory.js\";\n\n/**\n * Connection info for an MCP server.\n */\nexport interface MCPConnectionInfo {\n /** Transport type: \"url\" for SSE/HTTP, \"stdio\" for command-based */\n type: \"url\" | \"stdio\";\n /** SSE/HTTP URL (when type=\"url\") */\n url?: string;\n /** Command to spawn (when type=\"stdio\") */\n command?: string;\n /** Command arguments (when type=\"stdio\") */\n args?: string[];\n /** Environment variables (when type=\"stdio\") */\n env?: Record<string, string>;\n /** Working directory when spawning (when type=\"stdio\") */\n cwd?: string;\n}\n\n/**\n * Manages MCP server connection information extracted from directory discovery.\n */\nexport class MCPProcessManager {\n private readonly connections = new Map<string, MCPConnectionInfo>();\n\n getConnectionInfo(toolName: string, config: MCPServerConfig): MCPConnectionInfo {\n const cached = this.connections.get(toolName);\n if (cached) return cached;\n const info: MCPConnectionInfo = config.url\n ? { type: \"url\", url: config.url }\n : {\n type: \"stdio\",\n command: config.command!,\n args: config.args,\n env: config.env,\n cwd: config.cwd,\n };\n this.connections.set(toolName, info);\n return info;\n }\n\n remove(toolName: string): boolean {\n return this.connections.delete(toolName);\n }\n\n getToolNames(): string[] {\n return [...this.connections.keys()];\n }\n\n dispose(): void {\n this.connections.clear();\n }\n}\n","/**\n * High-level API: load mcp.json, connect to MCP server, register tools with runtime.\n * Framework-level so scripts call registerMCPToolsFromConfig() instead of inline MCP logic.\n */\n\nimport { basename, dirname, join } from \"node:path\";\nimport type { PTCRuntime } from \"../../core/runtime/PTCRuntime.js\";\nimport type { ToolRegistry } from \"../../core/registry/ToolRegistry.js\";\nimport { MCP_KIND } from \"./types.js\";\nimport { loadMCPTool } from \"./MCPLoader.js\";\nimport { MCPProcessManager } from \"./MCPProcessManager.js\";\nimport { connectMCP, mcpToolsToSpecs } from \"./connectMCP.js\";\nimport { MCPClientAdapter } from \"./MCPClientAdapter.js\";\n\nexport interface RegisterMCPToolsOptions {\n /** Path to mcp.json (or dir containing it). Default: process.env.MCP_CONFIG_PATH or \"mcp.json\" in cwd. */\n configPath?: string;\n /** Tool name for getConnectionInfo (default \"mcp\"). */\n toolName?: string;\n}\n\nexport interface RegisterMCPToolsResult {\n /** Transport; caller must call transport.close() when done. */\n transport: { close(): Promise<void> };\n}\n\n/**\n * Load mcp config (from configPath or MCP_CONFIG_PATH), connect via stdio, list tools,\n * register ToolSpec[] with registry and MCPClientAdapter with runtime. Returns transport for cleanup.\n */\nexport async function registerMCPToolsFromConfig(\n runtime: PTCRuntime,\n registry: ToolRegistry,\n options: RegisterMCPToolsOptions = {}\n): Promise<RegisterMCPToolsResult> {\n const configPath = options.configPath ?? process.env.MCP_CONFIG_PATH ?? join(process.cwd(), \"mcp.json\");\n const dirPath = dirname(configPath);\n const entryPoint = basename(configPath);\n const toolName = options.toolName ?? MCP_KIND;\n\n const loaded = await loadMCPTool(dirPath, { kind: MCP_KIND, name: toolName, entryPoint });\n if (!loaded.mcpConfig) {\n throw new Error(\"mcp.json must have command or url\");\n }\n const manager = new MCPProcessManager();\n const connectionInfo = manager.getConnectionInfo(toolName, loaded.mcpConfig);\n\n const { client, transport } = await connectMCP(connectionInfo);\n const { tools } = await client.listTools();\n const specs = mcpToolsToSpecs(tools);\n registry.bulkRegister(specs);\n runtime.registerAdapter(new MCPClientAdapter(client));\n\n return { transport };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../src/tools/function/scanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,YAAY,CAAC;AAE/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAOxF,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,UAAU,CAmGb;
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../src/tools/function/scanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,YAAY,CAAC;AAE/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAOxF,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,UAAU,CAmGb;AA+JD,2DAA2D;AAC3D,wBAAgB,IAAI,CAClB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAa9B"}
|
package/dist/utils/cli/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
4
|
+
var chunk5CDN24FP_cjs = require('../../chunk-5CDN24FP.cjs');
|
|
5
|
+
var chunkB5CAENK6_cjs = require('../../chunk-B5CAENK6.cjs');
|
|
6
|
+
var chunkAOEZBP6L_cjs = require('../../chunk-AOEZBP6L.cjs');
|
|
7
7
|
require('../../chunk-TOSPHMYU.cjs');
|
|
8
8
|
var chunk4KTWJQ32_cjs = require('../../chunk-4KTWJQ32.cjs');
|
|
9
9
|
require('../../chunk-DYDNPIV2.cjs');
|
|
@@ -24,10 +24,10 @@ async function getRuntimeWithTools(pathOpt, verbose = false) {
|
|
|
24
24
|
const stepLog = verbose ? (msg) => process.stderr.write(`[agent-tool] ${msg}
|
|
25
25
|
`) : void 0;
|
|
26
26
|
if (stepLog) stepLog(`Loading tool config from ${searchDir}`);
|
|
27
|
-
const config =
|
|
27
|
+
const config = chunkAOEZBP6L_cjs.findAndLoadToolConfig(searchDir);
|
|
28
28
|
let sandboxRoot = cwd;
|
|
29
29
|
if (config.sandboxedPath && typeof config.sandboxedPath === "string" && config.configPath) {
|
|
30
|
-
sandboxRoot =
|
|
30
|
+
sandboxRoot = chunkAOEZBP6L_cjs.resolveSandboxedPath(config.configPath, config.sandboxedPath);
|
|
31
31
|
}
|
|
32
32
|
if (stepLog) {
|
|
33
33
|
if (config.configPath) {
|
|
@@ -38,7 +38,7 @@ async function getRuntimeWithTools(pathOpt, verbose = false) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
const coreConfig = { sandboxRoot, allowedHosts: [] };
|
|
41
|
-
const result = await
|
|
41
|
+
const result = await chunkAOEZBP6L_cjs.createRuntimeFromConfig({
|
|
42
42
|
coreTools: coreConfig,
|
|
43
43
|
configFilePath: config.configPath,
|
|
44
44
|
stepLog
|
|
@@ -165,7 +165,7 @@ For agent run (ReAct + agent.yaml): npx @easynet/agent-orchestra run "task" -c a
|
|
|
165
165
|
}
|
|
166
166
|
async function cmdInit(pathOpt) {
|
|
167
167
|
try {
|
|
168
|
-
const { targetPath, filesCreated } = await
|
|
168
|
+
const { targetPath, filesCreated } = await chunk5CDN24FP_cjs.initProject({ targetPath: pathOpt || void 0 });
|
|
169
169
|
process.stdout.write(`Initialized project at ${targetPath}
|
|
170
170
|
Created: ${filesCreated.join(", ")}
|
|
171
171
|
Next: npm install && npm run build
|
|
@@ -179,7 +179,7 @@ Next: npm install && npm run build
|
|
|
179
179
|
}
|
|
180
180
|
async function cmdBuild(pathOpt, outDir, include, includeN8n) {
|
|
181
181
|
try {
|
|
182
|
-
const result = await
|
|
182
|
+
const result = await chunk5CDN24FP_cjs.buildMcpPackage({
|
|
183
183
|
projectPath: pathOpt || void 0,
|
|
184
184
|
outDir: outDir || void 0,
|
|
185
185
|
include: include.length > 0 ? include : void 0,
|
|
@@ -200,7 +200,7 @@ mcp.json: ${result.mcpJsonPath}
|
|
|
200
200
|
}
|
|
201
201
|
async function cmdServe(pathOpt) {
|
|
202
202
|
try {
|
|
203
|
-
const { process: child } = await
|
|
203
|
+
const { process: child } = await chunk5CDN24FP_cjs.runMcpServer({ path: pathOpt || void 0 });
|
|
204
204
|
child.stdin?.pipe(process.stdin);
|
|
205
205
|
child.stdout?.pipe(process.stdout);
|
|
206
206
|
process.stdin?.unref();
|
|
@@ -218,7 +218,7 @@ var LS_DESC_MAX = 72;
|
|
|
218
218
|
function formatLsOutput(specs) {
|
|
219
219
|
const rows = specs.map((spec) => {
|
|
220
220
|
const { name } = parseToolName(spec.name);
|
|
221
|
-
const scope =
|
|
221
|
+
const scope = chunkAOEZBP6L_cjs.getDisplayScope(spec.name, spec.kind, spec.version);
|
|
222
222
|
const desc = (spec.description ?? "").replace(/\n/g, " ").trim().slice(0, LS_DESC_MAX);
|
|
223
223
|
return { scope, name, description: desc || "(no description)" };
|
|
224
224
|
});
|
|
@@ -245,7 +245,7 @@ function formatLsOutput(specs) {
|
|
|
245
245
|
}
|
|
246
246
|
function formatDescribeOutput(spec) {
|
|
247
247
|
const { name: localName } = parseToolName(spec.name);
|
|
248
|
-
const scope =
|
|
248
|
+
const scope = chunkAOEZBP6L_cjs.getDisplayScope(spec.name, spec.kind, spec.version);
|
|
249
249
|
const sections = [];
|
|
250
250
|
sections.push("\u250C\u2500 Tool");
|
|
251
251
|
sections.push(`\u2502 name: ${spec.name}`);
|
|
@@ -281,7 +281,7 @@ async function cmdLs(pathOpt, verbose = false) {
|
|
|
281
281
|
process.stdout.write("No tools registered.\n");
|
|
282
282
|
const cwd = process.cwd();
|
|
283
283
|
const searchDir = path__default.default.resolve(cwd, pathOpt ?? ".");
|
|
284
|
-
const config =
|
|
284
|
+
const config = chunkAOEZBP6L_cjs.findAndLoadToolConfig(searchDir);
|
|
285
285
|
const hasNpmTools = Array.isArray(config.tools) && config.tools.some((t) => typeof t === "string" && t.startsWith("npm:"));
|
|
286
286
|
if (hasNpmTools) {
|
|
287
287
|
process.stdout.write("Tip: Install builtin tools in this directory: npm init -y && npm install @easynet/agent-tool-buildin\n");
|
|
@@ -304,7 +304,7 @@ async function cmdDescribe(toolName, pathOpt, verbose = false) {
|
|
|
304
304
|
}
|
|
305
305
|
try {
|
|
306
306
|
const { registry } = await getRuntimeWithTools(pathOpt, verbose);
|
|
307
|
-
const registryName =
|
|
307
|
+
const registryName = chunkAOEZBP6L_cjs.resolveToolDescriptor(toolName.trim());
|
|
308
308
|
const spec = registry.get(registryName);
|
|
309
309
|
if (!spec) {
|
|
310
310
|
process.stderr.write(`Tool not found: ${toolName}
|
|
@@ -353,7 +353,7 @@ async function cmdRun(toolName, toolArgsJson, pathOpt, verbose = false) {
|
|
|
353
353
|
}
|
|
354
354
|
try {
|
|
355
355
|
const { runtime, registry } = await getRuntimeWithTools(pathOpt, verbose);
|
|
356
|
-
const registryName =
|
|
356
|
+
const registryName = chunkAOEZBP6L_cjs.resolveToolDescriptor(toolName.trim());
|
|
357
357
|
if (!registry.get(registryName)) {
|
|
358
358
|
process.stderr.write(`Tool not found: ${toolName}
|
|
359
359
|
`);
|
|
@@ -381,10 +381,10 @@ async function cmdStartMcp(pathOpt, verbose = false, stdio = false, port = 3e3,
|
|
|
381
381
|
try {
|
|
382
382
|
const { runtime } = await getRuntimeWithTools(pathOpt, verbose);
|
|
383
383
|
if (stdio) {
|
|
384
|
-
await
|
|
384
|
+
await chunkB5CAENK6_cjs.runMCPServerOverStdio(runtime);
|
|
385
385
|
return 0;
|
|
386
386
|
}
|
|
387
|
-
const streamable = await
|
|
387
|
+
const streamable = await chunkB5CAENK6_cjs.createMCPServerStreamableHttp(runtime, { port, host, path: "/mcp" });
|
|
388
388
|
const { url, port: actualPort } = await streamable.listen(port, host);
|
|
389
389
|
process.stdout.write(`MCP Streamable HTTP: ${url}
|
|
390
390
|
`);
|
|
@@ -400,7 +400,7 @@ async function cmdStartMcp(pathOpt, verbose = false, stdio = false, port = 3e3,
|
|
|
400
400
|
async function cmdStartHttp(port, host, pathOpt, verbose = false) {
|
|
401
401
|
try {
|
|
402
402
|
const { runtime } = await getRuntimeWithTools(pathOpt, verbose);
|
|
403
|
-
const http = await
|
|
403
|
+
const http = await chunkB5CAENK6_cjs.createHttpService(runtime);
|
|
404
404
|
const { port: actualPort, host: actualHost } = await http.listen({ port, host });
|
|
405
405
|
const base = `http://${actualHost}:${actualPort}`;
|
|
406
406
|
process.stdout.write(`API: ${base}/invoke (POST), ${base}/tools (GET)
|
package/dist/utils/cli/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { initProject, buildMcpPackage, runMcpServer } from '../../chunk-
|
|
3
|
-
import { runMCPServerOverStdio, createMCPServerStreamableHttp, createHttpService } from '../../chunk-
|
|
4
|
-
import { findAndLoadToolConfig, resolveToolDescriptor, resolveSandboxedPath, createRuntimeFromConfig, getDisplayScope } from '../../chunk-
|
|
2
|
+
import { initProject, buildMcpPackage, runMcpServer } from '../../chunk-P5YQNWQT.js';
|
|
3
|
+
import { runMCPServerOverStdio, createMCPServerStreamableHttp, createHttpService } from '../../chunk-JEP26OIY.js';
|
|
4
|
+
import { findAndLoadToolConfig, resolveToolDescriptor, resolveSandboxedPath, createRuntimeFromConfig, getDisplayScope } from '../../chunk-SO32CIHJ.js';
|
|
5
5
|
import '../../chunk-ZRHPGW7W.js';
|
|
6
6
|
import { enrichSpecWithCanonicalSchema } from '../../chunk-3MUOBLNB.js';
|
|
7
7
|
import '../../chunk-KDB3MY2H.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@easynet/agent-tool",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.25",
|
|
4
4
|
"description": "MCP build: init → build → run. Turn your project (@tool, SKILL, n8n) into a standalone MCP npm server (no framework embedding, no package conflict).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|