@agentforge/skills 0.18.3 → 0.18.5
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/index.cjs +7 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -30
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -850,29 +850,6 @@ function escapeXml(str) {
|
|
|
850
850
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
851
851
|
}
|
|
852
852
|
|
|
853
|
-
// src/registry-query-api.ts
|
|
854
|
-
function getSkill(skills, name) {
|
|
855
|
-
return skills.get(name);
|
|
856
|
-
}
|
|
857
|
-
function getAllSkills(skills) {
|
|
858
|
-
return Array.from(skills.values());
|
|
859
|
-
}
|
|
860
|
-
function hasSkill(skills, name) {
|
|
861
|
-
return skills.has(name);
|
|
862
|
-
}
|
|
863
|
-
function getSkillCount(skills) {
|
|
864
|
-
return skills.size;
|
|
865
|
-
}
|
|
866
|
-
function getSkillNames(skills) {
|
|
867
|
-
return Array.from(skills.keys());
|
|
868
|
-
}
|
|
869
|
-
function getScanErrors(scanErrors) {
|
|
870
|
-
return scanErrors;
|
|
871
|
-
}
|
|
872
|
-
function getAllowedTools(skills, name) {
|
|
873
|
-
return skills.get(name)?.metadata.allowedTools;
|
|
874
|
-
}
|
|
875
|
-
|
|
876
853
|
// src/registry.ts
|
|
877
854
|
var SkillRegistry = class {
|
|
878
855
|
skills = /* @__PURE__ */ new Map();
|
|
@@ -890,28 +867,28 @@ var SkillRegistry = class {
|
|
|
890
867
|
});
|
|
891
868
|
}
|
|
892
869
|
get(name) {
|
|
893
|
-
return
|
|
870
|
+
return this.skills.get(name);
|
|
894
871
|
}
|
|
895
872
|
getAll() {
|
|
896
|
-
return
|
|
873
|
+
return Array.from(this.skills.values());
|
|
897
874
|
}
|
|
898
875
|
has(name) {
|
|
899
|
-
return
|
|
876
|
+
return this.skills.has(name);
|
|
900
877
|
}
|
|
901
878
|
size() {
|
|
902
|
-
return
|
|
879
|
+
return this.skills.size;
|
|
903
880
|
}
|
|
904
881
|
getNames() {
|
|
905
|
-
return
|
|
882
|
+
return Array.from(this.skills.keys());
|
|
906
883
|
}
|
|
907
884
|
getScanErrors() {
|
|
908
|
-
return
|
|
885
|
+
return this.scanErrors;
|
|
909
886
|
}
|
|
910
887
|
getAllowUntrustedScripts() {
|
|
911
888
|
return this.config.allowUntrustedScripts ?? false;
|
|
912
889
|
}
|
|
913
890
|
getAllowedTools(name) {
|
|
914
|
-
return
|
|
891
|
+
return this.skills.get(name)?.metadata.allowedTools;
|
|
915
892
|
}
|
|
916
893
|
generatePrompt(options) {
|
|
917
894
|
return generateSkillPrompt(this.config, this.getAll(), this.size(), options);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/parser.ts","../src/scanner.ts","../src/activation-content.ts","../src/activation-shared.ts","../src/trust.ts","../src/agent-skill-access.ts","../src/activation-schemas.ts","../src/activation-activate-tool.ts","../src/activation-resource-tool.ts","../src/activation-path.ts","../src/activation.ts","../src/registry-discovery.ts","../src/registry-events.ts","../src/registry-prompt.ts","../src/registry-query-api.ts","../src/registry.ts"],"names":["TrustPolicyReason","SkillRegistryEvent","matter","createLogger","LogLevel","resolve","homedir","existsSync","readdirSync","statSync","readFileSync","basename","isAbsolute","relative","realpathSync","z","ToolBuilder","ToolCategory","logger","resolvePath"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Skill System Types\n *\n * Core type definitions for the AgentForge Agent Skills system.\n * These types align with the Agent Skills specification (https://agentskills.io/specification).\n */\n\n// ─── Trust Policy Types ──────────────────────────────────────────────────\n\n/**\n * Trust level for a skill root directory.\n *\n * - `workspace` — Skills from the project workspace (highest trust, scripts allowed)\n * - `trusted` — Explicitly trusted skill roots (scripts allowed)\n * - `untrusted` — Untrusted roots like community packs (scripts blocked by default)\n */\nexport type TrustLevel = 'workspace' | 'trusted' | 'untrusted';\n\n/**\n * Configuration for a skill root with an explicit trust level.\n *\n * @example\n * ```ts\n * const roots: SkillRootConfig[] = [\n * { path: '.agentskills', trust: 'workspace' },\n * { path: '~/.agentskills', trust: 'trusted' },\n * { path: '/shared/community-skills', trust: 'untrusted' },\n * ];\n * ```\n */\nexport interface SkillRootConfig {\n /** Directory path to scan for skills */\n path: string;\n /** Trust level assigned to all skills discovered from this root */\n trust: TrustLevel;\n}\n\n/**\n * Policy decision returned by trust enforcement checks.\n */\nexport interface TrustPolicyDecision {\n /** Whether the action is allowed */\n allowed: boolean;\n /** Machine-readable reason code for auditing */\n reason: TrustPolicyReason;\n /** Human-readable explanation */\n message: string;\n}\n\n/**\n * Reason codes for trust policy decisions.\n *\n * Used for structured logging and auditing of guardrail behavior.\n */\nexport enum TrustPolicyReason {\n /** Resource is not a script — no trust check needed */\n NOT_SCRIPT = 'not-script',\n /** Skill root has workspace trust — scripts allowed */\n WORKSPACE_TRUST = 'workspace-trust',\n /** Skill root has explicit trusted status — scripts allowed */\n TRUSTED_ROOT = 'trusted-root',\n /** Skill body activation allowed because the root is workspace-owned */\n WORKSPACE_SKILL_ACTIVATION = 'workspace-skill-activation',\n /** Skill body activation allowed because the root is explicitly trusted */\n TRUSTED_SKILL_ACTIVATION = 'trusted-skill-activation',\n /** Full skill-body activation denied for an untrusted root */\n UNTRUSTED_SKILL_ACTIVATION_DENIED = 'untrusted-skill-activation-denied',\n /** Skill root is untrusted — scripts denied by default */\n UNTRUSTED_SCRIPT_DENIED = 'untrusted-script-denied',\n /** Untrusted script access was explicitly allowed via config override */\n UNTRUSTED_SCRIPT_ALLOWED = 'untrusted-script-allowed-override',\n /** Trust level is unknown — treated as untrusted for security */\n UNKNOWN_TRUST_LEVEL = 'unknown-trust-level',\n}\n\n/**\n * Parsed metadata from a SKILL.md frontmatter block.\n *\n * Required fields: `name`, `description`.\n * All other fields are optional per the Agent Skills spec.\n */\nexport interface SkillMetadata {\n /** Skill name (1-64 chars, lowercase alphanumeric + hyphens, must match parent dir name) */\n name: string;\n /** Human-readable description (1-1024 chars) */\n description: string;\n /** SPDX license identifier */\n license?: string;\n /** List of compatible agent frameworks / tool hosts */\n compatibility?: string[];\n /** Arbitrary key-value metadata (author, version, etc.) */\n metadata?: Record<string, unknown>;\n /** Tools that this skill is allowed to use */\n allowedTools?: string[];\n}\n\n/**\n * A fully resolved skill entry in the registry.\n *\n * Contains parsed metadata plus internal tracking fields\n * that are not part of the SKILL.md frontmatter.\n */\nexport interface Skill {\n /** Parsed frontmatter metadata */\n metadata: SkillMetadata;\n /** Absolute path to the skill directory */\n skillPath: string;\n /** Which configured skill root this was discovered from */\n rootPath: string;\n /** Trust level assigned to this skill (inherited from root config) */\n trustLevel: TrustLevel;\n}\n\n/**\n * Configuration for the SkillRegistry.\n */\nexport interface SkillRegistryConfig {\n /**\n * Array of directory paths to scan for skills.\n *\n * Each entry can be a plain string (defaults to `'untrusted'` trust level)\n * or a `SkillRootConfig` object with an explicit trust level.\n *\n * Paths may be absolute or relative (resolved against `cwd`).\n * The `~` prefix is expanded to `$HOME`.\n *\n * @example\n * ```ts\n * // Simple string roots (default to 'untrusted')\n * skillRoots: ['.agentskills', '~/.agentskills']\n *\n * // Trust-aware roots\n * skillRoots: [\n * { path: '.agentskills', trust: 'workspace' },\n * { path: '~/.agentskills', trust: 'trusted' },\n * { path: '/shared/community', trust: 'untrusted' },\n * ]\n * ```\n */\n skillRoots: Array<string | SkillRootConfig>;\n\n /**\n * Feature flag to enable Agent Skills in system prompts.\n *\n * When `false` (default), `generatePrompt()` returns an empty string\n * so agents operate with unmodified system prompts.\n *\n * @default false\n */\n enabled?: boolean;\n\n /**\n * Maximum number of skills to include in generated prompts.\n *\n * Caps prompt token usage when many skills are discovered.\n * Skills are included in discovery order (first root first).\n * When undefined, all discovered skills are included.\n */\n maxDiscoveredSkills?: number;\n\n /**\n * Allow script resources from untrusted roots.\n *\n * When `true`, scripts from `scripts/` directories in untrusted\n * skill roots are returned instead of being denied. This disables\n * the default-deny policy for untrusted scripts.\n *\n * **Security warning:** Only enable when you have reviewed all\n * skill packs from untrusted roots.\n *\n * @default false\n */\n allowUntrustedScripts?: boolean;\n}\n\n/**\n * Options for `SkillRegistry.generatePrompt()`.\n */\nexport interface SkillPromptOptions {\n /**\n * Subset of skill names to include in the generated prompt.\n *\n * When provided, only skills matching these names appear in the\n * `<available_skills>` XML block. This enables creating focused\n * agents with different skill sets from the same registry.\n *\n * When omitted or empty, all discovered skills are included.\n *\n * @example ['code-review', 'testing-strategy']\n */\n skills?: string[];\n}\n\n/**\n * Events emitted by the SkillRegistry during discovery and usage.\n */\nexport enum SkillRegistryEvent {\n /** Emitted when a valid skill is discovered during scanning */\n SKILL_DISCOVERED = 'skill:discovered',\n /** Emitted when a skill parse or validation issue is encountered */\n SKILL_WARNING = 'skill:warning',\n /** Emitted when a skill is activated (full body loaded) */\n SKILL_ACTIVATED = 'skill:activated',\n /** Emitted when a skill resource file is loaded */\n SKILL_RESOURCE_LOADED = 'skill:resource-loaded',\n /** Emitted when a trust policy denies access to a resource */\n TRUST_POLICY_DENIED = 'trust:policy-denied',\n /** Emitted when a trust policy allows access (for auditing) */\n TRUST_POLICY_ALLOWED = 'trust:policy-allowed',\n}\n\n/**\n * Event handler type for skill registry events.\n */\nexport type SkillEventHandler = (data: unknown) => void;\n\n/**\n * Result of parsing a single SKILL.md file.\n */\nexport interface SkillParseResult {\n /** Whether parsing and validation succeeded */\n success: boolean;\n /** Parsed metadata (present when success is true) */\n metadata?: SkillMetadata;\n /** The raw markdown body below the frontmatter (present when success is true) */\n body?: string;\n /** Error description (present when success is false) */\n error?: string;\n}\n\n/**\n * Validation error detail.\n */\nexport interface SkillValidationError {\n /** Which field failed validation */\n field: string;\n /** Human-readable error message */\n message: string;\n}\n","/**\n * SKILL.md Frontmatter Parser\n *\n * Parses YAML frontmatter from SKILL.md files and validates\n * against the Agent Skills specification constraints.\n *\n * @see https://agentskills.io/specification\n */\n\nimport matter from 'gray-matter';\nimport type { SkillMetadata, SkillParseResult, SkillValidationError } from './types.js';\n\n/**\n * Skill name validation constraints (per spec).\n *\n * - 1-64 characters\n * - Lowercase alphanumeric and hyphens only\n * - No leading, trailing, or consecutive hyphens\n */\nconst SKILL_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\nconst SKILL_NAME_MAX_LENGTH = 64;\nconst SKILL_DESCRIPTION_MAX_LENGTH = 1024;\n\n/**\n * Validate the `name` field per the Agent Skills spec.\n *\n * @param name - The name value from frontmatter\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillName(name: unknown): SkillValidationError[] {\n const errors: SkillValidationError[] = [];\n\n if (name === undefined || name === null) {\n errors.push({ field: 'name', message: 'name is required' });\n return errors;\n }\n\n if (typeof name !== 'string') {\n errors.push({ field: 'name', message: 'name must be a string' });\n return errors;\n }\n\n if (name.length === 0) {\n errors.push({ field: 'name', message: 'name must not be empty' });\n return errors;\n }\n\n if (name.length > SKILL_NAME_MAX_LENGTH) {\n errors.push({\n field: 'name',\n message: `name must be at most ${SKILL_NAME_MAX_LENGTH} characters (got ${name.length})`,\n });\n return errors;\n }\n\n if (!SKILL_NAME_PATTERN.test(name)) {\n errors.push({\n field: 'name',\n message: 'name must be lowercase alphanumeric with hyphens, no leading/trailing/consecutive hyphens',\n });\n }\n\n if (name.includes('--')) {\n errors.push({\n field: 'name',\n message: 'name must not contain consecutive hyphens',\n });\n }\n\n return errors;\n}\n\n/**\n * Validate the `description` field per the Agent Skills spec.\n *\n * @param description - The description value from frontmatter\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillDescription(description: unknown): SkillValidationError[] {\n const errors: SkillValidationError[] = [];\n\n if (description === undefined || description === null) {\n errors.push({ field: 'description', message: 'description is required' });\n return errors;\n }\n\n if (typeof description !== 'string') {\n errors.push({ field: 'description', message: 'description must be a string' });\n return errors;\n }\n\n if (description.trim().length === 0) {\n errors.push({ field: 'description', message: 'description must not be empty' });\n return errors;\n }\n\n if (description.length > SKILL_DESCRIPTION_MAX_LENGTH) {\n errors.push({\n field: 'description',\n message: `description must be at most ${SKILL_DESCRIPTION_MAX_LENGTH} characters (got ${description.length})`,\n });\n }\n\n return errors;\n}\n\n/**\n * Validate that the skill name matches its parent directory name (per spec).\n *\n * @param name - The name from frontmatter\n * @param dirName - The parent directory name\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillNameMatchesDir(name: string, dirName: string): SkillValidationError[] {\n if (name !== dirName) {\n return [{\n field: 'name',\n message: `name \"${name}\" must match parent directory name \"${dirName}\"`,\n }];\n }\n return [];\n}\n\n/**\n * Parse and validate a SKILL.md file's raw content.\n *\n * Extracts YAML frontmatter using gray-matter, then validates\n * required and optional fields against spec constraints.\n *\n * @param content - Raw file content of the SKILL.md\n * @param dirName - Parent directory name for name-match validation\n * @returns Parse result with metadata or error\n */\nexport function parseSkillContent(content: string, dirName: string): SkillParseResult {\n let parsed: matter.GrayMatterFile<string>;\n\n try {\n parsed = matter(content);\n } catch (err) {\n return {\n success: false,\n error: `Failed to parse frontmatter: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n const data = parsed.data;\n\n // Validate required fields\n const errors: SkillValidationError[] = [\n ...validateSkillName(data.name),\n ...validateSkillDescription(data.description),\n ];\n\n // If name is valid, validate it matches directory name\n if (typeof data.name === 'string' && data.name.length > 0 && SKILL_NAME_PATTERN.test(data.name)) {\n errors.push(...validateSkillNameMatchesDir(data.name, dirName));\n }\n\n if (errors.length > 0) {\n return {\n success: false,\n error: errors.map((e) => `${e.field}: ${e.message}`).join('; '),\n };\n }\n\n // Build metadata from validated fields\n const metadata: SkillMetadata = {\n name: data.name as string,\n description: data.description as string,\n };\n\n // Optional fields\n if (data.license !== undefined) {\n metadata.license = String(data.license);\n }\n\n if (Array.isArray(data.compatibility)) {\n metadata.compatibility = data.compatibility.map(String);\n }\n\n if (data.metadata !== undefined && typeof data.metadata === 'object' && data.metadata !== null) {\n metadata.metadata = data.metadata as Record<string, unknown>;\n }\n\n if (Array.isArray(data['allowed-tools'])) {\n metadata.allowedTools = data['allowed-tools'].map(String);\n }\n\n return {\n success: true,\n metadata,\n body: parsed.content,\n };\n}\n","/**\n * Skill Directory Scanner\n *\n * Scans configured skill roots for directories containing valid SKILL.md files.\n * Returns a list of candidate skill paths for the parser to process.\n */\n\nimport { existsSync, readdirSync, statSync, readFileSync } from 'node:fs';\nimport { resolve, basename } from 'node:path';\nimport { homedir } from 'node:os';\nimport { createLogger, LogLevel } from '@agentforge/core';\n\nconst logger = createLogger('agentforge:skills:scanner', { level: LogLevel.INFO });\n\n/**\n * Discovered skill candidate — a directory containing a SKILL.md file.\n */\nexport interface SkillCandidate {\n /** Absolute path to the skill directory */\n skillPath: string;\n /** The parent directory name (expected to match the skill name) */\n dirName: string;\n /** Raw content of the SKILL.md file */\n content: string;\n /** Which configured root this came from */\n rootPath: string;\n}\n\n/**\n * Expand `~` prefix to the user's home directory.\n */\nexport function expandHome(p: string): string {\n if (p.startsWith('~/') || p === '~') {\n return resolve(homedir(), p.slice(2));\n }\n return p;\n}\n\n/**\n * Scan a single skill root for directories containing SKILL.md.\n *\n * @param rootPath - The root directory to scan (may not exist)\n * @returns Array of valid skill candidates found under this root\n */\nexport function scanSkillRoot(rootPath: string): SkillCandidate[] {\n const resolvedRoot = resolve(expandHome(rootPath));\n const candidates: SkillCandidate[] = [];\n\n if (!existsSync(resolvedRoot)) {\n logger.debug('Skill root does not exist, skipping', { rootPath: resolvedRoot });\n return candidates;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(resolvedRoot);\n } catch (err) {\n logger.warn('Failed to read skill root directory', {\n rootPath: resolvedRoot,\n error: err instanceof Error ? err.message : String(err),\n });\n return candidates;\n }\n\n for (const entry of entries) {\n const entryPath = resolve(resolvedRoot, entry);\n\n // Only process directories\n let stat;\n try {\n stat = statSync(entryPath);\n } catch {\n continue;\n }\n if (!stat.isDirectory()) {\n continue;\n }\n\n // Check for SKILL.md inside the directory\n const skillMdPath = resolve(entryPath, 'SKILL.md');\n if (!existsSync(skillMdPath)) {\n continue;\n }\n\n // Read the SKILL.md content\n try {\n const content = readFileSync(skillMdPath, 'utf-8');\n candidates.push({\n skillPath: entryPath,\n dirName: basename(entryPath),\n content,\n rootPath: resolvedRoot,\n });\n } catch (err) {\n logger.warn('Failed to read SKILL.md', {\n path: skillMdPath,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n logger.debug('Scanned skill root', {\n rootPath: resolvedRoot,\n candidatesFound: candidates.length,\n });\n\n return candidates;\n}\n\n/**\n * Scan multiple skill roots for directories containing SKILL.md.\n *\n * @param skillRoots - Array of root paths to scan\n * @returns Array of all skill candidates found across all roots\n */\nexport function scanAllSkillRoots(skillRoots: string[]): SkillCandidate[] {\n const allCandidates: SkillCandidate[] = [];\n\n for (const root of skillRoots) {\n const candidates = scanSkillRoot(root);\n allCandidates.push(...candidates);\n }\n\n logger.info('Skill discovery complete', {\n rootsScanned: skillRoots.length,\n totalCandidates: allCandidates.length,\n });\n\n return allCandidates;\n}\n","import matter from 'gray-matter';\n\n/**\n * Extract the body content below YAML frontmatter from a SKILL.md file.\n *\n * Delegates to `gray-matter` for consistent frontmatter handling across\n * the codebase (matches `parseSkillContent()` in parser.ts).\n *\n * @param content - The full SKILL.md file content\n * @returns The body content below the frontmatter\n */\nexport function extractBody(content: string): string {\n return matter(content).content.trim();\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\n\nexport const activationLogger = createLogger('agentforge:skills:activation', {\n level: LogLevel.INFO,\n});\n\nexport function formatMissingSkillMessage(name: string, availableNames: string[]): string {\n const suggestion = availableNames.length > 0\n ? ` Available skills: ${availableNames.join(', ')}`\n : ' No skills are currently registered.';\n\n return `Skill \"${name}\" not found.${suggestion}`;\n}\n","/**\n * Skill Trust Policy Engine\n *\n * Enforces trust-level-based access control for skill resources.\n * Scripts from untrusted roots are denied by default unless explicitly allowed.\n *\n * Trust levels:\n * - `workspace` — Project-local skills, highest trust. Scripts always allowed.\n * - `trusted` — Explicitly trusted roots. Scripts allowed.\n * - `untrusted` — Community or third-party skills. Scripts denied by default.\n *\n * @see https://agentskills.io/specification\n */\n\nimport type { TrustLevel, TrustPolicyDecision, SkillRootConfig } from './types.js';\nimport { TrustPolicyReason } from './types.js';\n\n// ─── Constants ───────────────────────────────────────────────────────────\n\n/**\n * Resource path prefix that requires trust enforcement.\n *\n * Only resources under `scripts/` are subject to trust policy checks.\n * Other directories (references/, assets/, etc.) are always accessible.\n */\nconst SCRIPT_PATH_PREFIX = 'scripts/';\nconst SCRIPT_PATH_EXACT = 'scripts';\n\n// ─── Helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Normalize a skill root config entry.\n *\n * String entries default to `'untrusted'` trust level for safe defaults.\n *\n * @param root - A string path or SkillRootConfig object\n * @returns Normalized SkillRootConfig with explicit trust level\n */\nexport function normalizeRootConfig(root: string | SkillRootConfig): SkillRootConfig {\n if (typeof root === 'string') {\n return { path: root, trust: 'untrusted' };\n }\n return root;\n}\n\n/**\n * Check whether a resource path refers to a script.\n *\n * A resource is considered a script if its relative path starts with\n * `scripts/` or is exactly `scripts`, after normalizing path separators,\n * stripping leading \"./\" segments, and ignoring case.\n *\n * @param resourcePath - Relative path within the skill directory\n * @returns True if the resource is in the scripts/ directory\n */\nexport function isScriptResource(resourcePath: string): boolean {\n // Normalize to forward slashes and trim for consistent checking\n let normalized = resourcePath.trim().replace(/\\\\/g, '/');\n\n // Collapse repeated separators (e.g., \"scripts//setup.sh\" → \"scripts/setup.sh\")\n normalized = normalized.replace(/\\/+/g, '/');\n\n // Strip leading \"./\" segments (e.g., \"./scripts/setup.sh\" → \"scripts/setup.sh\")\n while (normalized.startsWith('./')) {\n normalized = normalized.slice(2);\n }\n\n // Case-insensitive comparison to handle case-insensitive file systems\n const lower = normalized.toLowerCase();\n\n return lower === SCRIPT_PATH_EXACT\n || lower.startsWith(SCRIPT_PATH_PREFIX);\n}\n\n// ─── Policy Engine ───────────────────────────────────────────────────────\n\n/**\n * Evaluate the trust policy for a resource access request.\n *\n * Non-script resources are allowed regardless of trust level, except for\n * SKILL.md, which is protected by the activation policy.\n * Script resources require `workspace` or `trusted` trust, or the\n * `allowUntrustedScripts` override to be enabled.\n *\n * @param resourcePath - Relative path to the resource within the skill directory\n * @param trustLevel - Trust level of the skill's root directory\n * @param allowUntrustedScripts - Override flag to permit untrusted scripts\n * @returns Policy decision with allow/deny, reason code, and message\n */\nexport function evaluateTrustPolicy(\n resourcePath: string,\n trustLevel: TrustLevel,\n allowUntrustedScripts: boolean = false,\n): TrustPolicyDecision {\n // Non-script resources — SKILL.md is checked separately by the resource tool.\n if (!isScriptResource(resourcePath)) {\n return {\n allowed: true,\n reason: TrustPolicyReason.NOT_SCRIPT,\n message: 'Resource is not a script — no trust check required',\n };\n }\n\n // Script resources — check trust level\n switch (trustLevel) {\n case 'workspace':\n return {\n allowed: true,\n reason: TrustPolicyReason.WORKSPACE_TRUST,\n message: 'Script allowed — skill root has workspace trust',\n };\n\n case 'trusted':\n return {\n allowed: true,\n reason: TrustPolicyReason.TRUSTED_ROOT,\n message: 'Script allowed — skill root is explicitly trusted',\n };\n\n case 'untrusted':\n if (allowUntrustedScripts) {\n return {\n allowed: true,\n reason: TrustPolicyReason.UNTRUSTED_SCRIPT_ALLOWED,\n message: 'Script from untrusted root allowed via allowUntrustedScripts override',\n };\n }\n return {\n allowed: false,\n reason: TrustPolicyReason.UNTRUSTED_SCRIPT_DENIED,\n message: `Script access denied — skill root is untrusted. ` +\n `Scripts from untrusted roots are blocked by default for security. ` +\n `To allow, set 'allowUntrustedScripts: true' in SkillRegistryConfig or ` +\n `promote the skill root to 'trusted' or 'workspace' trust level.`,\n };\n\n default:\n return {\n allowed: false,\n reason: TrustPolicyReason.UNKNOWN_TRUST_LEVEL,\n message: `Script access denied — trust level \"${trustLevel}\" is unknown and is treated as untrusted for security.`,\n };\n }\n}\n\n/**\n * Evaluate whether the full SKILL.md body can be exposed through activation.\n *\n * Untrusted roots stay discoverable, but their full instruction bodies are\n * blocked until the operator explicitly promotes that root to `trusted` or\n * `workspace`.\n */\nexport function evaluateSkillActivationPolicy(trustLevel: TrustLevel): TrustPolicyDecision {\n switch (trustLevel) {\n case 'workspace':\n return {\n allowed: true,\n reason: TrustPolicyReason.WORKSPACE_SKILL_ACTIVATION,\n message: 'Skill activation allowed — skill root has workspace trust',\n };\n\n case 'trusted':\n return {\n allowed: true,\n reason: TrustPolicyReason.TRUSTED_SKILL_ACTIVATION,\n message: 'Skill activation allowed — skill root is explicitly trusted',\n };\n\n case 'untrusted':\n return {\n allowed: false,\n reason: TrustPolicyReason.UNTRUSTED_SKILL_ACTIVATION_DENIED,\n message: `Skill activation blocked — skill root is untrusted. ` +\n `Untrusted skills remain discoverable, but their full SKILL.md bodies are blocked by default. ` +\n `Promote the skill root to 'trusted' or 'workspace' trust level after review to allow activation.`,\n };\n\n default:\n return {\n allowed: false,\n reason: TrustPolicyReason.UNKNOWN_TRUST_LEVEL,\n message: `Skill activation blocked — trust level \"${trustLevel}\" is unknown and is treated as untrusted for security.`,\n };\n }\n}\n","import { readFileSync, realpathSync } from 'node:fs';\nimport { isAbsolute, relative, resolve } from 'node:path';\nimport type { SkillRegistry } from './registry.js';\nimport { SkillRegistryEvent, TrustPolicyReason } from './types.js';\nimport { extractBody } from './activation-content.js';\nimport { activationLogger } from './activation-shared.js';\nimport { evaluateSkillActivationPolicy, evaluateTrustPolicy } from './trust.js';\n\nconst PATH_TRAVERSAL_MESSAGE =\n 'Path traversal is not allowed — resource paths must stay within the skill directory';\nconst SYMLINK_ESCAPE_MESSAGE = 'Symlink target escapes the skill directory — access denied';\n\ntype CanonicalResourcePathResult =\n | {\n kind: 'success';\n resolvedPath: string;\n canonicalPath: string;\n canonicalRelativePath: string;\n }\n | { kind: 'access-denied'; message: string }\n | { kind: 'resource-not-found'; resolvedPath: string; error: string }\n | { kind: 'target-read-failure'; resolvedPath: string; error: string }\n | { kind: 'read-failure'; error: string };\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction formatResourceReadError(error: unknown, resolvedPath: string): string {\n const message = formatError(error);\n const detailIndex = message.indexOf(', ');\n const prefix = detailIndex === -1 ? message : message.slice(0, detailIndex);\n return `${prefix}, open '${resolvedPath}'`;\n}\n\nfunction resolveCanonicalResourcePath(\n skillPath: string,\n resourcePath: string\n): CanonicalResourcePathResult {\n if (isAbsolute(resourcePath)) {\n return { kind: 'access-denied', message: 'Absolute resource paths are not allowed' };\n }\n\n if (resourcePath.split(/[/\\\\]/).some((segment) => segment === '..')) {\n return { kind: 'access-denied', message: PATH_TRAVERSAL_MESSAGE };\n }\n\n const resolvedSkillPath = resolve(skillPath);\n const resolvedPath = resolve(resolvedSkillPath, resourcePath);\n const lexicalRelativePath = relative(resolvedSkillPath, resolvedPath);\n if (\n lexicalRelativePath.startsWith('..') ||\n isAbsolute(lexicalRelativePath) ||\n resolve(resolvedSkillPath, lexicalRelativePath) !== resolvedPath\n ) {\n return { kind: 'access-denied', message: PATH_TRAVERSAL_MESSAGE };\n }\n\n let canonicalSkillPath: string;\n try {\n canonicalSkillPath = realpathSync(resolvedSkillPath);\n } catch (error) {\n return { kind: 'read-failure', error: formatResourceReadError(error, resolvedPath) };\n }\n\n let canonicalPath: string;\n try {\n canonicalPath = realpathSync(resolvedPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return {\n kind: 'resource-not-found',\n resolvedPath,\n error: formatResourceReadError(error, resolvedPath),\n };\n }\n return {\n kind: 'target-read-failure',\n resolvedPath,\n error: formatResourceReadError(error, resolvedPath),\n };\n }\n\n const canonicalRelativePath = relative(canonicalSkillPath, canonicalPath);\n if (canonicalRelativePath.startsWith('..') || isAbsolute(canonicalRelativePath)) {\n return { kind: 'access-denied', message: SYMLINK_ESCAPE_MESSAGE };\n }\n\n return { kind: 'success', resolvedPath, canonicalPath, canonicalRelativePath };\n}\n\nexport type SkillActivationResult =\n | { kind: 'success'; body: string }\n | { kind: 'skill-not-found'; name: string; availableNames: string[] }\n | { kind: 'access-denied'; reason: TrustPolicyReason; message: string }\n | { kind: 'read-failure'; name: string; error: string };\n\nexport type SkillResourceResult =\n | { kind: 'success'; content: string }\n | { kind: 'skill-not-found'; name: string; availableNames: string[] }\n | { kind: 'access-denied'; message: string; reason?: TrustPolicyReason }\n | { kind: 'resource-not-found'; name: string; resourcePath: string; error: string }\n | { kind: 'read-failure'; name: string; resourcePath: string; error: string };\n\n/** Package-internal owner of Agent Skill lookup, policy, reads, and audit signals. */\nexport class AgentSkillAccess {\n constructor(private readonly registry: SkillRegistry) {}\n\n async readResource(name: string, resourcePath: string): Promise<SkillResourceResult> {\n const skill = this.registry.get(name);\n if (!skill) {\n const availableNames = this.registry.getNames();\n activationLogger.warn('Skill resource load failed — skill not found', {\n name,\n resourcePath,\n });\n return { kind: 'skill-not-found', name, availableNames };\n }\n\n const pathResult = resolveCanonicalResourcePath(skill.skillPath, resourcePath);\n if (pathResult.kind === 'access-denied') {\n activationLogger.warn('Skill resource load blocked — path traversal', {\n name,\n resourcePath,\n error: pathResult.message,\n });\n return pathResult;\n }\n if (pathResult.kind === 'read-failure') {\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: pathResult.error,\n });\n return { ...pathResult, name, resourcePath };\n }\n\n const skillInstructionsPath = resolve(skill.skillPath, 'SKILL.md');\n let isSkillInstructions =\n pathResult.resolvedPath.toLowerCase() === skillInstructionsPath.toLowerCase();\n if (!isSkillInstructions && pathResult.kind === 'success') {\n try {\n isSkillInstructions =\n pathResult.canonicalPath.toLowerCase() ===\n realpathSync(skillInstructionsPath).toLowerCase();\n } catch {\n // The resource read below reports missing or unreadable paths.\n }\n }\n if (isSkillInstructions) {\n const activationDecision = evaluateSkillActivationPolicy(skill.trustLevel);\n if (!activationDecision.allowed) {\n activationLogger.warn('Skill resource load blocked — skill instructions trust policy', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: activationDecision.reason,\n message: activationDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath: 'SKILL.md',\n trustLevel: skill.trustLevel,\n reason: activationDecision.reason,\n message: activationDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: activationDecision.reason,\n message: activationDecision.message,\n };\n }\n }\n\n const policyDecision = evaluateTrustPolicy(\n pathResult.kind === 'success' ? pathResult.canonicalRelativePath : resourcePath,\n skill.trustLevel,\n this.registry.getAllowUntrustedScripts()\n );\n if (!policyDecision.allowed) {\n activationLogger.warn('Skill resource load blocked — trust policy', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: policyDecision.reason,\n message: policyDecision.message,\n };\n }\n\n if (policyDecision.reason !== TrustPolicyReason.NOT_SCRIPT) {\n activationLogger.info('Skill resource trust policy — allowed', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_ALLOWED, {\n name: skill.metadata.name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n });\n }\n\n if (pathResult.kind === 'resource-not-found' || pathResult.kind === 'target-read-failure') {\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: pathResult.error,\n });\n return {\n kind: pathResult.kind === 'resource-not-found' ? 'resource-not-found' : 'read-failure',\n name,\n resourcePath,\n error: pathResult.error,\n };\n }\n\n let content: string;\n try {\n content = readFileSync(pathResult.canonicalPath, 'utf-8');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: message,\n });\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { kind: 'resource-not-found', name, resourcePath, error: message };\n }\n return { kind: 'read-failure', name, resourcePath, error: message };\n }\n\n activationLogger.info('Skill resource loaded', {\n name: skill.metadata.name,\n resourcePath,\n resolvedPath: pathResult.resolvedPath,\n contentLength: content.length,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.SKILL_RESOURCE_LOADED, {\n name: skill.metadata.name,\n resourcePath,\n resolvedPath: pathResult.resolvedPath,\n contentLength: content.length,\n });\n\n return { kind: 'success', content };\n }\n\n async activate(name: string): Promise<SkillActivationResult> {\n const skill = this.registry.get(name);\n if (!skill) {\n const availableNames = this.registry.getNames();\n activationLogger.warn('Skill activation failed — not found', {\n name,\n availableCount: availableNames.length,\n });\n return { kind: 'skill-not-found', name, availableNames };\n }\n\n const policyDecision = evaluateSkillActivationPolicy(skill.trustLevel);\n if (!policyDecision.allowed) {\n activationLogger.warn('Skill activation blocked — trust policy', {\n name,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath: 'SKILL.md',\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: policyDecision.reason,\n message: policyDecision.message,\n };\n }\n\n let body: string;\n try {\n const content = readFileSync(resolve(skill.skillPath, 'SKILL.md'), 'utf-8');\n body = extractBody(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n activationLogger.error('Skill activation failed — read error', {\n name,\n skillPath: skill.skillPath,\n error: message,\n });\n return { kind: 'read-failure', name, error: message };\n }\n\n activationLogger.info('Skill activated', {\n name: skill.metadata.name,\n skillPath: skill.skillPath,\n bodyLength: body.length,\n trustLevel: skill.trustLevel,\n activationReason: policyDecision.reason,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.SKILL_ACTIVATED, {\n name: skill.metadata.name,\n skillPath: skill.skillPath,\n bodyLength: body.length,\n trustLevel: skill.trustLevel,\n });\n\n return { kind: 'success', body };\n }\n}\n","import { z } from 'zod';\n\nexport const activateSkillSchema = z.object({\n name: z.string().describe('The name of the skill to activate (e.g., \"code-review\")'),\n});\n\nexport const readSkillResourceSchema = z.object({\n name: z.string().describe('The name of the skill that owns the resource'),\n path: z.string().describe('Relative path to the resource file within the skill directory (e.g., \"references/GUIDE.md\", \"scripts/setup.sh\")'),\n});\n","import { ToolBuilder, ToolCategory } from '@agentforge/core';\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { AgentSkillAccess } from './agent-skill-access.js';\nimport { activateSkillSchema } from './activation-schemas.js';\nimport { formatMissingSkillMessage } from './activation-shared.js';\n\n/**\n * Create the `activate-skill` tool bound to a registry instance.\n *\n * Resolves the skill by name, reads the full SKILL.md file, and returns\n * the body content (below frontmatter).\n *\n * @param registry - The SkillRegistry to resolve skills from\n * @returns An AgentForge Tool\n */\nexport function createActivateSkillTool(\n registry: SkillRegistry,\n): Tool<z.infer<typeof activateSkillSchema>, string> {\n const access = new AgentSkillAccess(registry);\n\n return new ToolBuilder<z.infer<typeof activateSkillSchema>, string>()\n .name('activate-skill')\n .description(\n 'Activate an Agent Skill by name, loading its full instructions for trusted roots. ' +\n 'Returns the complete SKILL.md body content for workspace or explicitly trusted skills. ' +\n 'Use this when you see a relevant skill in <available_skills> or <untrusted_skills>; ' +\n 'activation is blocked for untrusted roots until they are promoted.',\n )\n .category(ToolCategory.SKILLS)\n .tags(['skill', 'activation', 'agent-skills'])\n .schema(activateSkillSchema)\n .implement(async ({ name }) => {\n const result = await access.activate(name);\n\n switch (result.kind) {\n case 'success':\n return result.body;\n case 'skill-not-found':\n return formatMissingSkillMessage(result.name, result.availableNames);\n case 'access-denied':\n return result.message;\n case 'read-failure':\n return `Failed to read skill \"${result.name}\" instructions: ${result.error}`;\n }\n })\n .build();\n}\n","import { ToolBuilder, ToolCategory } from '@agentforge/core';\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { AgentSkillAccess } from './agent-skill-access.js';\nimport { readSkillResourceSchema } from './activation-schemas.js';\nimport { formatMissingSkillMessage } from './activation-shared.js';\n\n/**\n * Create the `read-skill-resource` tool bound to a registry instance.\n *\n * Resolves the skill by name, validates the resource path (blocking\n * traversal), and returns the file content.\n *\n * @param registry - The SkillRegistry to resolve skills from\n * @returns An AgentForge Tool\n */\nexport function createReadSkillResourceTool(\n registry: SkillRegistry\n): Tool<z.infer<typeof readSkillResourceSchema>, string> {\n const access = new AgentSkillAccess(registry);\n\n return new ToolBuilder<z.infer<typeof readSkillResourceSchema>, string>()\n .name('read-skill-resource')\n .description(\n 'Read a resource file from an activated Agent Skill. ' +\n 'Returns the content of a file within the skill directory (e.g., references/, scripts/, assets/). ' +\n 'The path must be relative to the skill root and cannot traverse outside it. ' +\n 'SKILL.md is only readable from workspace or trusted roots.'\n )\n .category(ToolCategory.SKILLS)\n .tags(['skill', 'resource', 'agent-skills'])\n .schema(readSkillResourceSchema)\n .implement(async ({ name, path: resourcePath }) => {\n const result = await access.readResource(name, resourcePath);\n\n switch (result.kind) {\n case 'success':\n return result.content;\n case 'skill-not-found':\n return formatMissingSkillMessage(result.name, result.availableNames);\n case 'access-denied':\n return result.message;\n case 'resource-not-found':\n case 'read-failure':\n return `Failed to read resource \"${result.resourcePath}\" from skill \"${result.name}\": ${result.error}`;\n }\n })\n .build();\n}\n","import { isAbsolute, relative, resolve } from 'node:path';\nimport { realpathSync } from 'node:fs';\n\n/**\n * Resolve a resource path within a skill root, blocking path traversal.\n *\n * @param skillPath - Absolute path to the skill directory\n * @param resourcePath - Relative path to the resource file\n * @returns A result containing either the resolved absolute path or an error message\n * @deprecated Use the `read-skill-resource` Tool from\n * `SkillRegistry.toActivationTools()` for Agent Skill resource access. This\n * compatibility helper is planned for removal in the next major release.\n */\nexport function resolveResourcePath(\n skillPath: string,\n resourcePath: string,\n): { success: true; resolvedPath: string } | { success: false; error: string } {\n if (isAbsolute(resourcePath)) {\n return { success: false, error: 'Absolute resource paths are not allowed' };\n }\n\n const segments = resourcePath.split(/[/\\\\]/);\n if (segments.some((seg) => seg === '..')) {\n return { success: false, error: 'Path traversal is not allowed — resource paths must stay within the skill directory' };\n }\n\n const resolvedPath = resolve(skillPath, resourcePath);\n const resolvedSkillPath = resolve(skillPath);\n const rel = relative(resolvedSkillPath, resolvedPath);\n if (rel.startsWith('..') || resolve(resolvedSkillPath, rel) !== resolvedPath) {\n return { success: false, error: 'Path traversal is not allowed — resource paths must stay within the skill directory' };\n }\n\n try {\n const realSkillRoot = realpathSync(resolvedSkillPath);\n const realTarget = realpathSync(resolvedPath);\n const realRel = relative(realSkillRoot, realTarget);\n if (realRel.startsWith('..') || isAbsolute(realRel)) {\n return { success: false, error: 'Symlink target escapes the skill directory — access denied' };\n }\n } catch {\n // File doesn't exist yet (or can't be stat'd) — skip symlink check.\n // The caller will produce a clear error if the file is missing.\n }\n\n return { success: true, resolvedPath };\n}\n","/**\n * Agent Skill Access Tools\n *\n * Provides `activate-skill` and `read-skill-resource` tools built with\n * the AgentForge tool builder API. Skill activation makes trusted Agent\n * Skill instructions available; resource access loads supporting files.\n *\n * @see https://agentskills.io/specification\n *\n * @example\n * ```ts\n * const [activateSkill, readSkillResource] = createSkillActivationTools(registry);\n * // activateSkill — load full SKILL.md body\n * // readSkillResource — load a resource file from a skill\n *\n * // Or use the convenience method:\n * const [activateSkill, readSkillResource] = registry.toActivationTools();\n * ```\n */\n\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { createActivateSkillTool } from './activation-activate-tool.js';\nimport { createReadSkillResourceTool } from './activation-resource-tool.js';\nimport type { activateSkillSchema, readSkillResourceSchema } from './activation-schemas.js';\n\nexport { createActivateSkillTool } from './activation-activate-tool.js';\nexport { resolveResourcePath } from './activation-path.js';\nexport { createReadSkillResourceTool } from './activation-resource-tool.js';\n\n/**\n * Create both skill activation tools bound to a registry instance.\n *\n * @param registry - The SkillRegistry to bind tools to\n * @returns Array of both tools [activate-skill, read-skill-resource]\n */\nexport function createSkillActivationTools(\n registry: SkillRegistry,\n): [Tool<z.infer<typeof activateSkillSchema>, string>, Tool<z.infer<typeof readSkillResourceSchema>, string>] {\n return [\n createActivateSkillTool(registry),\n createReadSkillResourceTool(registry),\n ];\n}\n","import { resolve as resolvePath } from 'node:path';\nimport { createLogger, LogLevel } from '@agentforge/core';\nimport { parseSkillContent } from './parser.js';\nimport { scanAllSkillRoots, expandHome } from './scanner.js';\nimport { normalizeRootConfig } from './trust.js';\nimport type { Skill, SkillRegistryConfig, TrustLevel } from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport type { RegistryEmit, ScanError } from './registry-internal.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function discoverSkills(\n config: Pick<SkillRegistryConfig, 'skillRoots'>,\n skills: Map<string, Skill>,\n rootTrustMap: Map<string, TrustLevel>,\n emit: RegistryEmit,\n): ScanError[] {\n skills.clear();\n rootTrustMap.clear();\n const scanErrors: ScanError[] = [];\n\n const normalizedRoots = config.skillRoots.map(normalizeRootConfig);\n const plainPaths = normalizedRoots.map((root) => root.path);\n\n for (const root of normalizedRoots) {\n const resolvedPath = resolvePath(expandHome(root.path));\n rootTrustMap.set(resolvedPath, root.trust);\n }\n\n const candidates = scanAllSkillRoots(plainPaths);\n\n let successCount = 0;\n let warningCount = 0;\n\n for (const candidate of candidates) {\n const result = parseSkillContent(candidate.content, candidate.dirName);\n\n if (!result.success) {\n warningCount++;\n recordScanError(scanErrors, candidate.skillPath, result.error || 'Unknown parse error');\n emit(SkillRegistryEvent.SKILL_WARNING, {\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n error: result.error,\n });\n logger.warn('Skipping invalid skill', {\n skillPath: candidate.skillPath,\n ...(result.error ? { error: result.error } : {}),\n });\n continue;\n }\n\n const skill: Skill = {\n metadata: result.metadata!,\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n trustLevel: rootTrustMap.get(candidate.rootPath) ?? 'untrusted',\n };\n\n if (skills.has(skill.metadata.name)) {\n warningCount++;\n const existing = skills.get(skill.metadata.name)!;\n const warningMessage =\n `Duplicate skill name \"${skill.metadata.name}\" from \"${candidate.rootPath}\" — ` +\n `keeping version from \"${existing.rootPath}\" (first root takes precedence)`;\n\n recordScanError(scanErrors, candidate.skillPath, warningMessage);\n emit(SkillRegistryEvent.SKILL_WARNING, {\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n duplicateOf: existing.skillPath,\n error: warningMessage,\n });\n logger.warn('Duplicate skill name, keeping first', {\n name: skill.metadata.name,\n kept: existing.skillPath,\n skipped: candidate.skillPath,\n });\n continue;\n }\n\n skills.set(skill.metadata.name, skill);\n successCount++;\n emit(SkillRegistryEvent.SKILL_DISCOVERED, skill);\n logger.debug('Skill discovered', {\n name: skill.metadata.name,\n description: skill.metadata.description.slice(0, 80),\n skillPath: skill.skillPath,\n });\n }\n\n logger.info('Skill registry populated', {\n rootsScanned: config.skillRoots.length,\n skillsDiscovered: successCount,\n warnings: warningCount,\n });\n\n return scanErrors;\n}\n\nfunction recordScanError(scanErrors: ScanError[], path: string, error: string): void {\n scanErrors.push({ path, error });\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\nimport type { SkillEventHandler } from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport type { RegistryEventHandlers } from './registry-internal.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function addRegistryEventHandler(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n handler: SkillEventHandler,\n): void {\n if (!eventHandlers.has(event)) {\n eventHandlers.set(event, new Set());\n }\n\n eventHandlers.get(event)!.add(handler);\n}\n\nexport function removeRegistryEventHandler(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n handler: SkillEventHandler,\n): void {\n const handlers = eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n }\n}\n\nexport function emitRegistryEvent(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n data: unknown,\n): void {\n const handlers = eventHandlers.get(event);\n if (!handlers) {\n return;\n }\n\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n logger.error('Skill event handler error', {\n event,\n error: error instanceof Error ? error.message : String(error),\n ...(error instanceof Error && error.stack ? { stack: error.stack } : {}),\n });\n }\n });\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\nimport type { Skill, SkillPromptOptions, SkillRegistryConfig } from './types.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function generateSkillPrompt(\n config: SkillRegistryConfig,\n allSkills: Skill[],\n totalDiscovered: number,\n options?: SkillPromptOptions,\n): string {\n if (!config.enabled) {\n logger.debug('Skill prompt generation skipped (disabled)', {\n enabled: config.enabled ?? false,\n });\n return '';\n }\n\n let skills = allSkills;\n\n if (options?.skills && options.skills.length > 0) {\n const requested = new Set(options.skills);\n skills = skills.filter((skill) => requested.has(skill.metadata.name));\n }\n\n let trustedSkills = skills.filter(\n (skill) => skill.trustLevel === 'workspace' || skill.trustLevel === 'trusted',\n );\n let untrustedSkills = skills.filter(\n (skill) => skill.trustLevel !== 'workspace' && skill.trustLevel !== 'trusted',\n );\n\n if (config.maxDiscoveredSkills !== undefined && config.maxDiscoveredSkills >= 0) {\n const trustedLimit = Math.min(config.maxDiscoveredSkills, trustedSkills.length);\n trustedSkills = trustedSkills.slice(0, trustedLimit);\n untrustedSkills = untrustedSkills.slice(0, config.maxDiscoveredSkills - trustedLimit);\n skills = [...trustedSkills, ...untrustedSkills];\n }\n\n if (trustedSkills.length === 0 && untrustedSkills.length === 0) {\n logger.debug('Skill prompt generation produced empty result', {\n totalDiscovered,\n filterApplied: !!(options?.skills && options.skills.length > 0),\n ...(config.maxDiscoveredSkills !== undefined\n ? { maxCap: config.maxDiscoveredSkills }\n : {}),\n });\n return '';\n }\n\n const sections: string[] = [];\n\n if (trustedSkills.length > 0) {\n sections.push(`<available_skills>\\n${trustedSkills.map(renderTrustedSkillEntry).join('\\n')}\\n</available_skills>`);\n }\n\n if (untrustedSkills.length > 0) {\n sections.push(renderUntrustedSkillsSection(untrustedSkills));\n }\n\n const xml = sections.join('\\n');\n const estimatedTokens = Math.ceil(xml.length / 4);\n\n logger.info('Skill prompt generated', {\n skillCount: skills.length,\n trustedSkillCount: trustedSkills.length,\n untrustedSkillCount: untrustedSkills.length,\n totalDiscovered,\n filterApplied: !!(options?.skills && options.skills.length > 0),\n ...(config.maxDiscoveredSkills !== undefined ? { maxCap: config.maxDiscoveredSkills } : {}),\n estimatedTokens,\n xmlLength: xml.length,\n });\n\n return xml;\n}\n\nfunction renderTrustedSkillEntry(skill: Skill): string {\n return [\n ' <skill>',\n ` <name>${escapeXml(skill.metadata.name)}</name>`,\n ` <description>${escapeXml(skill.metadata.description)}</description>`,\n ` <location>${escapeXml(skill.skillPath)}</location>`,\n ` <trust>${escapeXml(skill.trustLevel)}</trust>`,\n ' </skill>',\n ].join('\\n');\n}\n\nfunction renderUntrustedSkillsSection(skills: Skill[]): string {\n return [\n '<untrusted_skills>',\n ' <trust_notice>Untrusted skills are discoverable, but their full SKILL.md bodies stay blocked until the root is promoted to trusted or workspace status.</trust_notice>',\n ...skills.map(renderUntrustedSkillEntry),\n '</untrusted_skills>',\n ].join('\\n');\n}\n\nfunction renderUntrustedSkillEntry(skill: Skill): string {\n return [\n ' <skill>',\n ` <name>${escapeXml(skill.metadata.name)}</name>`,\n ` <description>${escapeXml(skill.metadata.description)}</description>`,\n ` <location>${escapeXml(skill.skillPath)}</location>`,\n ` <trust>${escapeXml(skill.trustLevel)}</trust>`,\n ' <activation_policy>requires-trusted-root</activation_policy>',\n ' </skill>',\n ].join('\\n');\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n","import type { Skill } from './types.js';\nimport type { ScanError } from './registry-internal.js';\n\nexport function getSkill(skills: Map<string, Skill>, name: string): Skill | undefined {\n return skills.get(name);\n}\n\nexport function getAllSkills(skills: Map<string, Skill>): Skill[] {\n return Array.from(skills.values());\n}\n\nexport function hasSkill(skills: Map<string, Skill>, name: string): boolean {\n return skills.has(name);\n}\n\nexport function getSkillCount(skills: Map<string, Skill>): number {\n return skills.size;\n}\n\nexport function getSkillNames(skills: Map<string, Skill>): string[] {\n return Array.from(skills.keys());\n}\n\nexport function getScanErrors(scanErrors: ScanError[]): ReadonlyArray<ScanError> {\n return scanErrors;\n}\n\nexport function getAllowedTools(skills: Map<string, Skill>, name: string): string[] | undefined {\n return skills.get(name)?.metadata.allowedTools;\n}\n","import type {\n Skill,\n SkillEventHandler,\n SkillPromptOptions,\n SkillRegistryConfig,\n TrustLevel,\n} from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport { createSkillActivationTools } from './activation.js';\nimport { discoverSkills } from './registry-discovery.js';\nimport {\n addRegistryEventHandler,\n emitRegistryEvent,\n removeRegistryEventHandler,\n} from './registry-events.js';\nimport type { RegistryEventHandlers } from './registry-internal.js';\nimport { generateSkillPrompt } from './registry-prompt.js';\nimport {\n getAllSkills,\n getAllowedTools,\n getScanErrors,\n getSkill,\n getSkillCount,\n getSkillNames,\n hasSkill,\n} from './registry-query-api.js';\n\nexport class SkillRegistry {\n private skills: Map<string, Skill> = new Map();\n private eventHandlers: RegistryEventHandlers = new Map();\n private readonly config: SkillRegistryConfig;\n private scanErrors: Array<{ path: string; error: string }> = [];\n private rootTrustMap: Map<string, TrustLevel> = new Map();\n\n constructor(config: SkillRegistryConfig) {\n this.config = config;\n this.discover();\n }\n\n discover(): void {\n this.scanErrors = discoverSkills(this.config, this.skills, this.rootTrustMap, (event, data) => {\n this.emit(event, data);\n });\n }\n\n get(name: string): Skill | undefined {\n return getSkill(this.skills, name);\n }\n\n getAll(): Skill[] {\n return getAllSkills(this.skills);\n }\n\n has(name: string): boolean {\n return hasSkill(this.skills, name);\n }\n\n size(): number {\n return getSkillCount(this.skills);\n }\n\n getNames(): string[] {\n return getSkillNames(this.skills);\n }\n\n getScanErrors(): ReadonlyArray<{ path: string; error: string }> {\n return getScanErrors(this.scanErrors);\n }\n\n getAllowUntrustedScripts(): boolean {\n return this.config.allowUntrustedScripts ?? false;\n }\n\n getAllowedTools(name: string): string[] | undefined {\n return getAllowedTools(this.skills, name);\n }\n\n generatePrompt(options?: SkillPromptOptions): string {\n return generateSkillPrompt(this.config, this.getAll(), this.size(), options);\n }\n\n on(event: SkillRegistryEvent, handler: SkillEventHandler): void {\n addRegistryEventHandler(this.eventHandlers, event, handler);\n }\n\n off(event: SkillRegistryEvent, handler: SkillEventHandler): void {\n removeRegistryEventHandler(this.eventHandlers, event, handler);\n }\n\n emitEvent(event: SkillRegistryEvent, data: unknown): void {\n this.emit(event, data);\n }\n\n toActivationTools(): ReturnType<typeof createSkillActivationTools> {\n return createSkillActivationTools(this);\n }\n\n private emit(event: SkillRegistryEvent, data: unknown): void {\n emitRegistryEvent(this.eventHandlers, event, data);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/parser.ts","../src/scanner.ts","../src/activation-content.ts","../src/activation-shared.ts","../src/trust.ts","../src/agent-skill-access.ts","../src/activation-schemas.ts","../src/activation-activate-tool.ts","../src/activation-resource-tool.ts","../src/activation-path.ts","../src/activation.ts","../src/registry-discovery.ts","../src/registry-events.ts","../src/registry-prompt.ts","../src/registry.ts"],"names":["TrustPolicyReason","SkillRegistryEvent","matter","createLogger","LogLevel","resolve","homedir","existsSync","readdirSync","statSync","readFileSync","basename","isAbsolute","relative","realpathSync","z","ToolBuilder","ToolCategory","logger","resolvePath"],"mappings":";;;;;;;;;;;;;;AAsDO,IAAK,iBAAA,qBAAAA,kBAAAA,KAAL;AAEL,EAAAA,mBAAA,YAAA,CAAA,GAAa,YAAA;AAEb,EAAAA,mBAAA,iBAAA,CAAA,GAAkB,iBAAA;AAElB,EAAAA,mBAAA,cAAA,CAAA,GAAe,cAAA;AAEf,EAAAA,mBAAA,4BAAA,CAAA,GAA6B,4BAAA;AAE7B,EAAAA,mBAAA,0BAAA,CAAA,GAA2B,0BAAA;AAE3B,EAAAA,mBAAA,mCAAA,CAAA,GAAoC,mCAAA;AAEpC,EAAAA,mBAAA,yBAAA,CAAA,GAA0B,yBAAA;AAE1B,EAAAA,mBAAA,0BAAA,CAAA,GAA2B,mCAAA;AAE3B,EAAAA,mBAAA,qBAAA,CAAA,GAAsB,qBAAA;AAlBZ,EAAA,OAAAA,kBAAAA;AAAA,CAAA,EAAA,iBAAA,IAAA,EAAA;AA8IL,IAAK,kBAAA,qBAAAC,mBAAAA,KAAL;AAEL,EAAAA,oBAAA,kBAAA,CAAA,GAAmB,kBAAA;AAEnB,EAAAA,oBAAA,eAAA,CAAA,GAAgB,eAAA;AAEhB,EAAAA,oBAAA,iBAAA,CAAA,GAAkB,iBAAA;AAElB,EAAAA,oBAAA,uBAAA,CAAA,GAAwB,uBAAA;AAExB,EAAAA,oBAAA,qBAAA,CAAA,GAAsB,qBAAA;AAEtB,EAAAA,oBAAA,sBAAA,CAAA,GAAuB,sBAAA;AAZb,EAAA,OAAAA,mBAAAA;AAAA,CAAA,EAAA,kBAAA,IAAA,EAAA;ACjLZ,IAAM,kBAAA,GAAqB,mCAAA;AAC3B,IAAM,qBAAA,GAAwB,EAAA;AAC9B,IAAM,4BAAA,GAA+B,IAAA;AAQ9B,SAAS,kBAAkB,IAAA,EAAuC;AACvE,EAAA,MAAM,SAAiC,EAAC;AAExC,EAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,IAAA,EAAM;AACvC,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,oBAAoB,CAAA;AAC1D,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,yBAAyB,CAAA;AAC/D,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,0BAA0B,CAAA;AAChE,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,qBAAA,EAAuB;AACvC,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,MAAA;AAAA,MACP,OAAA,EAAS,CAAA,qBAAA,EAAwB,qBAAqB,CAAA,iBAAA,EAAoB,KAAK,MAAM,CAAA,CAAA;AAAA,KACtF,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAA,EAAG;AAClC,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,MAAA;AAAA,MACP,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG;AACvB,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,MAAA;AAAA,MACP,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,MAAA;AACT;AAQO,SAAS,yBAAyB,WAAA,EAA8C;AACrF,EAAA,MAAM,SAAiC,EAAC;AAExC,EAAA,IAAI,WAAA,KAAgB,MAAA,IAAa,WAAA,KAAgB,IAAA,EAAM;AACrD,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,aAAA,EAAe,OAAA,EAAS,2BAA2B,CAAA;AACxE,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,gBAAgB,QAAA,EAAU;AACnC,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,aAAA,EAAe,OAAA,EAAS,gCAAgC,CAAA;AAC7E,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAA,CAAY,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA,EAAG;AACnC,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,aAAA,EAAe,OAAA,EAAS,iCAAiC,CAAA;AAC9E,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAA,CAAY,SAAS,4BAAA,EAA8B;AACrD,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,aAAA;AAAA,MACP,OAAA,EAAS,CAAA,4BAAA,EAA+B,4BAA4B,CAAA,iBAAA,EAAoB,YAAY,MAAM,CAAA,CAAA;AAAA,KAC3G,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,MAAA;AACT;AASO,SAAS,2BAAA,CAA4B,MAAc,OAAA,EAAyC;AACjG,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,OAAO,CAAC;AAAA,MACN,KAAA,EAAO,MAAA;AAAA,MACP,OAAA,EAAS,CAAA,MAAA,EAAS,IAAI,CAAA,oCAAA,EAAuC,OAAO,CAAA,CAAA;AAAA,KACrE,CAAA;AAAA,EACH;AACA,EAAA,OAAO,EAAC;AACV;AAYO,SAAS,iBAAA,CAAkB,SAAiB,OAAA,EAAmC;AACpF,EAAA,IAAI,MAAA;AAEJ,EAAA,IAAI;AACF,IAAA,MAAA,GAASC,wBAAO,OAAO,CAAA;AAAA,EACzB,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,gCAAgC,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,KACzF;AAAA,EACF;AAEA,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AAGpB,EAAA,MAAM,MAAA,GAAiC;AAAA,IACrC,GAAG,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA;AAAA,IAC9B,GAAG,wBAAA,CAAyB,IAAA,CAAK,WAAW;AAAA,GAC9C;AAGA,EAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,IAAY,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAA,IAAK,kBAAA,CAAmB,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,EAAG;AAC/F,IAAA,MAAA,CAAO,KAAK,GAAG,2BAAA,CAA4B,IAAA,CAAK,IAAA,EAAM,OAAO,CAAC,CAAA;AAAA,EAChE;AAEA,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,MAAA,CAAO,GAAA,CAAI,CAAC,MAAM,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI;AAAA,KAChE;AAAA,EACF;AAGA,EAAA,MAAM,QAAA,GAA0B;AAAA,IAC9B,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,aAAa,IAAA,CAAK;AAAA,GACpB;AAGA,EAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAW;AAC9B,IAAA,QAAA,CAAS,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,EACxC;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,aAAa,CAAA,EAAG;AACrC,IAAA,QAAA,CAAS,aAAA,GAAgB,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,MAAM,CAAA;AAAA,EACxD;AAEA,EAAA,IAAI,IAAA,CAAK,aAAa,MAAA,IAAa,OAAO,KAAK,QAAA,KAAa,QAAA,IAAY,IAAA,CAAK,QAAA,KAAa,IAAA,EAAM;AAC9F,IAAA,QAAA,CAAS,WAAW,IAAA,CAAK,QAAA;AAAA,EAC3B;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,eAAe,CAAC,CAAA,EAAG;AACxC,IAAA,QAAA,CAAS,YAAA,GAAe,IAAA,CAAK,eAAe,CAAA,CAAE,IAAI,MAAM,CAAA;AAAA,EAC1D;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,IAAA;AAAA,IACT,QAAA;AAAA,IACA,MAAM,MAAA,CAAO;AAAA,GACf;AACF;ACrLA,IAAM,SAASC,iBAAA,CAAa,2BAAA,EAA6B,EAAE,KAAA,EAAOC,aAAA,CAAS,MAAM,CAAA;AAmB1E,SAAS,WAAW,CAAA,EAAmB;AAC5C,EAAA,IAAI,CAAA,CAAE,UAAA,CAAW,IAAI,CAAA,IAAK,MAAM,GAAA,EAAK;AACnC,IAAA,OAAOC,aAAQC,UAAA,EAAQ,EAAG,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,CAAA;AACT;AAQO,SAAS,cAAc,QAAA,EAAoC;AAChE,EAAA,MAAM,YAAA,GAAeD,YAAA,CAAQ,UAAA,CAAW,QAAQ,CAAC,CAAA;AACjD,EAAA,MAAM,aAA+B,EAAC;AAEtC,EAAA,IAAI,CAACE,aAAA,CAAW,YAAY,CAAA,EAAG;AAC7B,IAAA,MAAA,CAAO,KAAA,CAAM,qCAAA,EAAuC,EAAE,QAAA,EAAU,cAAc,CAAA;AAC9E,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAUC,eAAY,YAAY,CAAA;AAAA,EACpC,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,CAAO,KAAK,qCAAA,EAAuC;AAAA,MACjD,QAAA,EAAU,YAAA;AAAA,MACV,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,KACvD,CAAA;AACD,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,SAAA,GAAYH,YAAA,CAAQ,YAAA,EAAc,KAAK,CAAA;AAG7C,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,IAAA,GAAOI,YAAS,SAAS,CAAA;AAAA,IAC3B,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,IAAA,CAAK,WAAA,EAAY,EAAG;AACvB,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,WAAA,GAAcJ,YAAA,CAAQ,SAAA,EAAW,UAAU,CAAA;AACjD,IAAA,IAAI,CAACE,aAAA,CAAW,WAAW,CAAA,EAAG;AAC5B,MAAA;AAAA,IACF;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAUG,eAAA,CAAa,WAAA,EAAa,OAAO,CAAA;AACjD,MAAA,UAAA,CAAW,IAAA,CAAK;AAAA,QACd,SAAA,EAAW,SAAA;AAAA,QACX,OAAA,EAASC,cAAS,SAAS,CAAA;AAAA,QAC3B,OAAA;AAAA,QACA,QAAA,EAAU;AAAA,OACX,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,MAAA,CAAO,KAAK,yBAAA,EAA2B;AAAA,QACrC,IAAA,EAAM,WAAA;AAAA,QACN,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,OACvD,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,MAAA,CAAO,MAAM,oBAAA,EAAsB;AAAA,IACjC,QAAA,EAAU,YAAA;AAAA,IACV,iBAAiB,UAAA,CAAW;AAAA,GAC7B,CAAA;AAED,EAAA,OAAO,UAAA;AACT;AAQO,SAAS,kBAAkB,UAAA,EAAwC;AACxE,EAAA,MAAM,gBAAkC,EAAC;AAEzC,EAAA,KAAA,MAAW,QAAQ,UAAA,EAAY;AAC7B,IAAA,MAAM,UAAA,GAAa,cAAc,IAAI,CAAA;AACrC,IAAA,aAAA,CAAc,IAAA,CAAK,GAAG,UAAU,CAAA;AAAA,EAClC;AAEA,EAAA,MAAA,CAAO,KAAK,0BAAA,EAA4B;AAAA,IACtC,cAAc,UAAA,CAAW,MAAA;AAAA,IACzB,iBAAiB,aAAA,CAAc;AAAA,GAChC,CAAA;AAED,EAAA,OAAO,aAAA;AACT;ACtHO,SAAS,YAAY,OAAA,EAAyB;AACnD,EAAA,OAAOT,uBAAAA,CAAO,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAK;AACtC;ACXO,IAAM,gBAAA,GAAmBC,kBAAa,8BAAA,EAAgC;AAAA,EAC3E,OAAOC,aAAAA,CAAS;AAClB,CAAC,CAAA;AAEM,SAAS,yBAAA,CAA0B,MAAc,cAAA,EAAkC;AACxF,EAAA,MAAM,UAAA,GAAa,eAAe,MAAA,GAAS,CAAA,GACvC,sBAAsB,cAAA,CAAe,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GAC/C,sCAAA;AAEJ,EAAA,OAAO,CAAA,OAAA,EAAU,IAAI,CAAA,YAAA,EAAe,UAAU,CAAA,CAAA;AAChD;;;ACaA,IAAM,kBAAA,GAAqB,UAAA;AAC3B,IAAM,iBAAA,GAAoB,SAAA;AAYnB,SAAS,oBAAoB,IAAA,EAAiD;AACnF,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,WAAA,EAAY;AAAA,EAC1C;AACA,EAAA,OAAO,IAAA;AACT;AAYO,SAAS,iBAAiB,YAAA,EAA+B;AAE9D,EAAA,IAAI,aAAa,YAAA,CAAa,IAAA,EAAK,CAAE,OAAA,CAAQ,OAAO,GAAG,CAAA;AAGvD,EAAA,UAAA,GAAa,UAAA,CAAW,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA;AAG3C,EAAA,OAAO,UAAA,CAAW,UAAA,CAAW,IAAI,CAAA,EAAG;AAClC,IAAA,UAAA,GAAa,UAAA,CAAW,MAAM,CAAC,CAAA;AAAA,EACjC;AAGA,EAAA,MAAM,KAAA,GAAQ,WAAW,WAAA,EAAY;AAErC,EAAA,OAAO,KAAA,KAAU,iBAAA,IACZ,KAAA,CAAM,UAAA,CAAW,kBAAkB,CAAA;AAC1C;AAiBO,SAAS,mBAAA,CACd,YAAA,EACA,UAAA,EACA,qBAAA,GAAiC,KAAA,EACZ;AAErB,EAAA,IAAI,CAAC,gBAAA,CAAiB,YAAY,CAAA,EAAG;AACnC,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,MAAA,EAAA,YAAA;AAAA,MACA,OAAA,EAAS;AAAA,KACX;AAAA,EACF;AAGA,EAAA,QAAQ,UAAA;AAAY,IAClB,KAAK,WAAA;AACH,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA,EAAA,iBAAA;AAAA,QACA,OAAA,EAAS;AAAA,OACX;AAAA,IAEF,KAAK,SAAA;AACH,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA,EAAA,cAAA;AAAA,QACA,OAAA,EAAS;AAAA,OACX;AAAA,IAEF,KAAK,WAAA;AACH,MAAA,IAAI,qBAAA,EAAuB;AACzB,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,MAAA,EAAA,mCAAA;AAAA,UACA,OAAA,EAAS;AAAA,SACX;AAAA,MACF;AACA,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,MAAA,EAAA,yBAAA;AAAA,QACA,OAAA,EAAS,CAAA,4PAAA;AAAA,OAIX;AAAA,IAEF;AACE,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,MAAA,EAAA,qBAAA;AAAA,QACA,OAAA,EAAS,4CAAuC,UAAU,CAAA,sDAAA;AAAA,OAC5D;AAAA;AAEN;AASO,SAAS,8BAA8B,UAAA,EAA6C;AACzF,EAAA,QAAQ,UAAA;AAAY,IAClB,KAAK,WAAA;AACH,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA,EAAA,4BAAA;AAAA,QACA,OAAA,EAAS;AAAA,OACX;AAAA,IAEF,KAAK,SAAA;AACH,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA,EAAA,0BAAA;AAAA,QACA,OAAA,EAAS;AAAA,OACX;AAAA,IAEF,KAAK,WAAA;AACH,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,MAAA,EAAA,mCAAA;AAAA,QACA,OAAA,EAAS,CAAA,sPAAA;AAAA,OAGX;AAAA,IAEF;AACE,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,MAAA,EAAA,qBAAA;AAAA,QACA,OAAA,EAAS,gDAA2C,UAAU,CAAA,sDAAA;AAAA,OAChE;AAAA;AAEN;;;AChLA,IAAM,sBAAA,GACJ,0FAAA;AACF,IAAM,sBAAA,GAAyB,iEAAA;AAc/B,SAAS,YAAY,KAAA,EAAwB;AAC3C,EAAA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC9D;AAEA,SAAS,uBAAA,CAAwB,OAAgB,YAAA,EAA8B;AAC7E,EAAA,MAAM,OAAA,GAAU,YAAY,KAAK,CAAA;AACjC,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AACxC,EAAA,MAAM,SAAS,WAAA,KAAgB,EAAA,GAAK,UAAU,OAAA,CAAQ,KAAA,CAAM,GAAG,WAAW,CAAA;AAC1E,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,QAAA,EAAW,YAAY,CAAA,CAAA,CAAA;AACzC;AAEA,SAAS,4BAAA,CACP,WACA,YAAA,EAC6B;AAC7B,EAAA,IAAIQ,eAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,OAAO,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,yCAAA,EAA0C;AAAA,EACrF;AAEA,EAAA,IAAI,YAAA,CAAa,MAAM,OAAO,CAAA,CAAE,KAAK,CAAC,OAAA,KAAY,OAAA,KAAY,IAAI,CAAA,EAAG;AACnE,IAAA,OAAO,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,sBAAA,EAAuB;AAAA,EAClE;AAEA,EAAA,MAAM,iBAAA,GAAoBP,aAAQ,SAAS,CAAA;AAC3C,EAAA,MAAM,YAAA,GAAeA,YAAAA,CAAQ,iBAAA,EAAmB,YAAY,CAAA;AAC5D,EAAA,MAAM,mBAAA,GAAsBQ,aAAA,CAAS,iBAAA,EAAmB,YAAY,CAAA;AACpE,EAAA,IACE,mBAAA,CAAoB,UAAA,CAAW,IAAI,CAAA,IACnCD,eAAA,CAAW,mBAAmB,CAAA,IAC9BP,YAAAA,CAAQ,iBAAA,EAAmB,mBAAmB,CAAA,KAAM,YAAA,EACpD;AACA,IAAA,OAAO,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,sBAAA,EAAuB;AAAA,EAClE;AAEA,EAAA,IAAI,kBAAA;AACJ,EAAA,IAAI;AACF,IAAA,kBAAA,GAAqBS,gBAAa,iBAAiB,CAAA;AAAA,EACrD,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,EAAE,IAAA,EAAM,cAAA,EAAgB,OAAO,uBAAA,CAAwB,KAAA,EAAO,YAAY,CAAA,EAAE;AAAA,EACrF;AAEA,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI;AACF,IAAA,aAAA,GAAgBA,gBAAa,YAAY,CAAA;AAAA,EAC3C,SAAS,KAAA,EAAO;AACd,IAAA,IAAK,KAAA,CAAgC,SAAS,QAAA,EAAU;AACtD,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,oBAAA;AAAA,QACN,YAAA;AAAA,QACA,KAAA,EAAO,uBAAA,CAAwB,KAAA,EAAO,YAAY;AAAA,OACpD;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,qBAAA;AAAA,MACN,YAAA;AAAA,MACA,KAAA,EAAO,uBAAA,CAAwB,KAAA,EAAO,YAAY;AAAA,KACpD;AAAA,EACF;AAEA,EAAA,MAAM,qBAAA,GAAwBD,aAAA,CAAS,kBAAA,EAAoB,aAAa,CAAA;AACxE,EAAA,IAAI,sBAAsB,UAAA,CAAW,IAAI,CAAA,IAAKD,eAAA,CAAW,qBAAqB,CAAA,EAAG;AAC/E,IAAA,OAAO,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,sBAAA,EAAuB;AAAA,EAClE;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,YAAA,EAAc,eAAe,qBAAA,EAAsB;AAC/E;AAgBO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,QAAA,EAAyB;AAAzB,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAAA,EAA0B;AAAA,EAEvD,MAAM,YAAA,CAAa,IAAA,EAAc,YAAA,EAAoD;AACnF,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AACpC,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,QAAA,CAAS,QAAA,EAAS;AAC9C,MAAA,gBAAA,CAAiB,KAAK,mDAAA,EAAgD;AAAA,QACpE,IAAA;AAAA,QACA;AAAA,OACD,CAAA;AACD,MAAA,OAAO,EAAE,IAAA,EAAM,iBAAA,EAAmB,IAAA,EAAM,cAAA,EAAe;AAAA,IACzD;AAEA,IAAA,MAAM,UAAA,GAAa,4BAAA,CAA6B,KAAA,CAAM,SAAA,EAAW,YAAY,CAAA;AAC7E,IAAA,IAAI,UAAA,CAAW,SAAS,eAAA,EAAiB;AACvC,MAAA,gBAAA,CAAiB,KAAK,mDAAA,EAAgD;AAAA,QACpE,IAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAO,UAAA,CAAW;AAAA,OACnB,CAAA;AACD,MAAA,OAAO,UAAA;AAAA,IACT;AACA,IAAA,IAAI,UAAA,CAAW,SAAS,cAAA,EAAgB;AACtC,MAAA,gBAAA,CAAiB,KAAK,gEAAA,EAA6D;AAAA,QACjF,IAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAO,UAAA,CAAW;AAAA,OACnB,CAAA;AACD,MAAA,OAAO,EAAE,GAAG,UAAA,EAAY,IAAA,EAAM,YAAA,EAAa;AAAA,IAC7C;AAEA,IAAA,MAAM,qBAAA,GAAwBP,YAAAA,CAAQ,KAAA,CAAM,SAAA,EAAW,UAAU,CAAA;AACjE,IAAA,IAAI,sBACF,UAAA,CAAW,YAAA,CAAa,WAAA,EAAY,KAAM,sBAAsB,WAAA,EAAY;AAC9E,IAAA,IAAI,CAAC,mBAAA,IAAuB,UAAA,CAAW,IAAA,KAAS,SAAA,EAAW;AACzD,MAAA,IAAI;AACF,QAAA,mBAAA,GACE,WAAW,aAAA,CAAc,WAAA,OACzBS,eAAA,CAAa,qBAAqB,EAAE,WAAA,EAAY;AAAA,MACpD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA,IAAI,mBAAA,EAAqB;AACvB,MAAA,MAAM,kBAAA,GAAqB,6BAAA,CAA8B,KAAA,CAAM,UAAU,CAAA;AACzE,MAAA,IAAI,CAAC,mBAAmB,OAAA,EAAS;AAC/B,QAAA,gBAAA,CAAiB,KAAK,oEAAA,EAAiE;AAAA,UACrF,IAAA;AAAA,UACA,YAAA;AAAA,UACA,YAAY,KAAA,CAAM,UAAA;AAAA,UAClB,QAAQ,kBAAA,CAAmB,MAAA;AAAA,UAC3B,SAAS,kBAAA,CAAmB;AAAA,SAC7B,CAAA;AAED,QAAA,IAAA,CAAK,SAAS,SAAA,CAAA,qBAAA,4BAAkD;AAAA,UAC9D,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,UACrB,YAAA,EAAc,UAAA;AAAA,UACd,YAAY,KAAA,CAAM,UAAA;AAAA,UAClB,QAAQ,kBAAA,CAAmB,MAAA;AAAA,UAC3B,SAAS,kBAAA,CAAmB;AAAA,SAC7B,CAAA;AAED,QAAA,OAAO;AAAA,UACL,IAAA,EAAM,eAAA;AAAA,UACN,QAAQ,kBAAA,CAAmB,MAAA;AAAA,UAC3B,SAAS,kBAAA,CAAmB;AAAA,SAC9B;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,cAAA,GAAiB,mBAAA;AAAA,MACrB,UAAA,CAAW,IAAA,KAAS,SAAA,GAAY,UAAA,CAAW,qBAAA,GAAwB,YAAA;AAAA,MACnE,KAAA,CAAM,UAAA;AAAA,MACN,IAAA,CAAK,SAAS,wBAAA;AAAyB,KACzC;AACA,IAAA,IAAI,CAAC,eAAe,OAAA,EAAS;AAC3B,MAAA,gBAAA,CAAiB,KAAK,iDAAA,EAA8C;AAAA,QAClE,IAAA;AAAA,QACA,YAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OACzB,CAAA;AAED,MAAA,IAAA,CAAK,SAAS,SAAA,CAAA,qBAAA,4BAAkD;AAAA,QAC9D,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,QACrB,YAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OACzB,CAAA;AAED,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,eAAA;AAAA,QACN,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OAC1B;AAAA,IACF;AAEA,IAAA,IAAI,eAAe,MAAA,KAAA,YAAA,mBAAyC;AAC1D,MAAA,gBAAA,CAAiB,KAAK,4CAAA,EAAyC;AAAA,QAC7D,IAAA;AAAA,QACA,YAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe;AAAA,OACxB,CAAA;AAED,MAAA,IAAA,CAAK,SAAS,SAAA,CAAA,sBAAA,6BAAmD;AAAA,QAC/D,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,QACrB,YAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe;AAAA,OACxB,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,UAAA,CAAW,IAAA,KAAS,oBAAA,IAAwB,UAAA,CAAW,SAAS,qBAAA,EAAuB;AACzF,MAAA,gBAAA,CAAiB,KAAK,gEAAA,EAA6D;AAAA,QACjF,IAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAO,UAAA,CAAW;AAAA,OACnB,CAAA;AACD,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,UAAA,CAAW,IAAA,KAAS,oBAAA,GAAuB,oBAAA,GAAuB,cAAA;AAAA,QACxE,IAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAO,UAAA,CAAW;AAAA,OACpB;AAAA,IACF;AAEA,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAUJ,eAAAA,CAAa,UAAA,CAAW,aAAA,EAAe,OAAO,CAAA;AAAA,IAC1D,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,MAAA,gBAAA,CAAiB,KAAK,gEAAA,EAA6D;AAAA,QACjF,IAAA;AAAA,QACA,YAAA;AAAA,QACA,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,IAAK,KAAA,CAAgC,SAAS,QAAA,EAAU;AACtD,QAAA,OAAO,EAAE,IAAA,EAAM,oBAAA,EAAsB,IAAA,EAAM,YAAA,EAAc,OAAO,OAAA,EAAQ;AAAA,MAC1E;AACA,MAAA,OAAO,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAM,YAAA,EAAc,OAAO,OAAA,EAAQ;AAAA,IACpE;AAEA,IAAA,gBAAA,CAAiB,KAAK,uBAAA,EAAyB;AAAA,MAC7C,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,MACrB,YAAA;AAAA,MACA,cAAc,UAAA,CAAW,YAAA;AAAA,MACzB,eAAe,OAAA,CAAQ;AAAA,KACxB,CAAA;AAED,IAAA,IAAA,CAAK,SAAS,SAAA,CAAA,uBAAA,8BAAoD;AAAA,MAChE,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,MACrB,YAAA;AAAA,MACA,cAAc,UAAA,CAAW,YAAA;AAAA,MACzB,eAAe,OAAA,CAAQ;AAAA,KACxB,CAAA;AAED,IAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,OAAA,EAAQ;AAAA,EACpC;AAAA,EAEA,MAAM,SAAS,IAAA,EAA8C;AAC3D,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AACpC,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,QAAA,CAAS,QAAA,EAAS;AAC9C,MAAA,gBAAA,CAAiB,KAAK,0CAAA,EAAuC;AAAA,QAC3D,IAAA;AAAA,QACA,gBAAgB,cAAA,CAAe;AAAA,OAChC,CAAA;AACD,MAAA,OAAO,EAAE,IAAA,EAAM,iBAAA,EAAmB,IAAA,EAAM,cAAA,EAAe;AAAA,IACzD;AAEA,IAAA,MAAM,cAAA,GAAiB,6BAAA,CAA8B,KAAA,CAAM,UAAU,CAAA;AACrE,IAAA,IAAI,CAAC,eAAe,OAAA,EAAS;AAC3B,MAAA,gBAAA,CAAiB,KAAK,8CAAA,EAA2C;AAAA,QAC/D,IAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OACzB,CAAA;AAED,MAAA,IAAA,CAAK,SAAS,SAAA,CAAA,qBAAA,4BAAkD;AAAA,QAC9D,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,QACrB,YAAA,EAAc,UAAA;AAAA,QACd,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OACzB,CAAA;AAED,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,eAAA;AAAA,QACN,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OAC1B;AAAA,IACF;AAEA,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,UAAUA,eAAAA,CAAaL,YAAAA,CAAQ,MAAM,SAAA,EAAW,UAAU,GAAG,OAAO,CAAA;AAC1E,MAAA,IAAA,GAAO,YAAY,OAAO,CAAA;AAAA,IAC5B,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,MAAA,gBAAA,CAAiB,MAAM,2CAAA,EAAwC;AAAA,QAC7D,IAAA;AAAA,QACA,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,OAAO,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAM,OAAO,OAAA,EAAQ;AAAA,IACtD;AAEA,IAAA,gBAAA,CAAiB,KAAK,iBAAA,EAAmB;AAAA,MACvC,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,MACrB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,YAAY,IAAA,CAAK,MAAA;AAAA,MACjB,YAAY,KAAA,CAAM,UAAA;AAAA,MAClB,kBAAkB,cAAA,CAAe;AAAA,KAClC,CAAA;AAED,IAAA,IAAA,CAAK,SAAS,SAAA,CAAA,iBAAA,wBAA8C;AAAA,MAC1D,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,MACrB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,YAAY,IAAA,CAAK,MAAA;AAAA,MACjB,YAAY,KAAA,CAAM;AAAA,KACnB,CAAA;AAED,IAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAK;AAAA,EACjC;AACF,CAAA;AC5UO,IAAM,mBAAA,GAAsBU,MAAE,MAAA,CAAO;AAAA,EAC1C,IAAA,EAAMA,KAAA,CAAE,MAAA,EAAO,CAAE,SAAS,yDAAyD;AACrF,CAAC,CAAA;AAEM,IAAM,uBAAA,GAA0BA,MAAE,MAAA,CAAO;AAAA,EAC9C,IAAA,EAAMA,KAAA,CAAE,MAAA,EAAO,CAAE,SAAS,8CAA8C,CAAA;AAAA,EACxE,IAAA,EAAMA,KAAA,CAAE,MAAA,EAAO,CAAE,SAAS,iHAAiH;AAC7I,CAAC,CAAA;;;ACQM,SAAS,wBACd,QAAA,EACmD;AACnD,EAAA,MAAM,MAAA,GAAS,IAAI,gBAAA,CAAiB,QAAQ,CAAA;AAE5C,EAAA,OAAO,IAAIC,gBAAA,EAAyD,CACjE,IAAA,CAAK,gBAAgB,CAAA,CACrB,WAAA;AAAA,IACC;AAAA,IAKD,QAAA,CAASC,iBAAA,CAAa,MAAM,CAAA,CAC5B,IAAA,CAAK,CAAC,OAAA,EAAS,YAAA,EAAc,cAAc,CAAC,CAAA,CAC5C,OAAO,mBAAmB,CAAA,CAC1B,UAAU,OAAO,EAAE,MAAK,KAAM;AAC7B,IAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA;AAEzC,IAAA,QAAQ,OAAO,IAAA;AAAM,MACnB,KAAK,SAAA;AACH,QAAA,OAAO,MAAA,CAAO,IAAA;AAAA,MAChB,KAAK,iBAAA;AACH,QAAA,OAAO,yBAAA,CAA0B,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,cAAc,CAAA;AAAA,MACrE,KAAK,eAAA;AACH,QAAA,OAAO,MAAA,CAAO,OAAA;AAAA,MAChB,KAAK,cAAA;AACH,QAAA,OAAO,CAAA,sBAAA,EAAyB,MAAA,CAAO,IAAI,CAAA,gBAAA,EAAmB,OAAO,KAAK,CAAA,CAAA;AAAA;AAC9E,EACF,CAAC,EACA,KAAA,EAAM;AACX;AC/BO,SAAS,4BACd,QAAA,EACuD;AACvD,EAAA,MAAM,MAAA,GAAS,IAAI,gBAAA,CAAiB,QAAQ,CAAA;AAE5C,EAAA,OAAO,IAAID,gBAAAA,EAA6D,CACrE,IAAA,CAAK,qBAAqB,CAAA,CAC1B,WAAA;AAAA,IACC;AAAA,GAIF,CACC,SAASC,iBAAAA,CAAa,MAAM,EAC5B,IAAA,CAAK,CAAC,SAAS,UAAA,EAAY,cAAc,CAAC,CAAA,CAC1C,MAAA,CAAO,uBAAuB,CAAA,CAC9B,SAAA,CAAU,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,YAAA,EAAa,KAAM;AACjD,IAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,YAAA,CAAa,MAAM,YAAY,CAAA;AAE3D,IAAA,QAAQ,OAAO,IAAA;AAAM,MACnB,KAAK,SAAA;AACH,QAAA,OAAO,MAAA,CAAO,OAAA;AAAA,MAChB,KAAK,iBAAA;AACH,QAAA,OAAO,yBAAA,CAA0B,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,cAAc,CAAA;AAAA,MACrE,KAAK,eAAA;AACH,QAAA,OAAO,MAAA,CAAO,OAAA;AAAA,MAChB,KAAK,oBAAA;AAAA,MACL,KAAK,cAAA;AACH,QAAA,OAAO,CAAA,yBAAA,EAA4B,OAAO,YAAY,CAAA,cAAA,EAAiB,OAAO,IAAI,CAAA,GAAA,EAAM,OAAO,KAAK,CAAA,CAAA;AAAA;AACxG,EACF,CAAC,EACA,KAAA,EAAM;AACX;ACpCO,SAAS,mBAAA,CACd,WACA,YAAA,EAC6E;AAC7E,EAAA,IAAIL,eAAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,yCAAA,EAA0C;AAAA,EAC5E;AAEA,EAAA,MAAM,QAAA,GAAW,YAAA,CAAa,KAAA,CAAM,OAAO,CAAA;AAC3C,EAAA,IAAI,SAAS,IAAA,CAAK,CAAC,GAAA,KAAQ,GAAA,KAAQ,IAAI,CAAA,EAAG;AACxC,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,0FAAA,EAAsF;AAAA,EACxH;AAEA,EAAA,MAAM,YAAA,GAAeP,YAAAA,CAAQ,SAAA,EAAW,YAAY,CAAA;AACpD,EAAA,MAAM,iBAAA,GAAoBA,aAAQ,SAAS,CAAA;AAC3C,EAAA,MAAM,GAAA,GAAMQ,aAAAA,CAAS,iBAAA,EAAmB,YAAY,CAAA;AACpD,EAAA,IAAI,GAAA,CAAI,WAAW,IAAI,CAAA,IAAKR,aAAQ,iBAAA,EAAmB,GAAG,MAAM,YAAA,EAAc;AAC5E,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,0FAAA,EAAsF;AAAA,EACxH;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,aAAA,GAAgBS,gBAAa,iBAAiB,CAAA;AACpD,IAAA,MAAM,UAAA,GAAaA,gBAAa,YAAY,CAAA;AAC5C,IAAA,MAAM,OAAA,GAAUD,aAAAA,CAAS,aAAA,EAAe,UAAU,CAAA;AAClD,IAAA,IAAI,QAAQ,UAAA,CAAW,IAAI,CAAA,IAAKD,eAAAA,CAAW,OAAO,CAAA,EAAG;AACnD,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,iEAAA,EAA6D;AAAA,IAC/F;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAGR;AAEA,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,YAAA,EAAa;AACvC;;;ACTO,SAAS,2BACd,QAAA,EAC4G;AAC5G,EAAA,OAAO;AAAA,IACL,wBAAwB,QAAQ,CAAA;AAAA,IAChC,4BAA4B,QAAQ;AAAA,GACtC;AACF;ACnCA,IAAMM,UAASf,iBAAAA,CAAa,4BAAA,EAA8B,EAAE,KAAA,EAAOC,aAAAA,CAAS,MAAM,CAAA;AAE3E,SAAS,cAAA,CACd,MAAA,EACA,MAAA,EACA,YAAA,EACA,IAAA,EACa;AACb,EAAA,MAAA,CAAO,KAAA,EAAM;AACb,EAAA,YAAA,CAAa,KAAA,EAAM;AACnB,EAAA,MAAM,aAA0B,EAAC;AAEjC,EAAA,MAAM,eAAA,GAAkB,MAAA,CAAO,UAAA,CAAW,GAAA,CAAI,mBAAmB,CAAA;AACjE,EAAA,MAAM,aAAa,eAAA,CAAgB,GAAA,CAAI,CAAC,IAAA,KAAS,KAAK,IAAI,CAAA;AAE1D,EAAA,KAAA,MAAW,QAAQ,eAAA,EAAiB;AAClC,IAAA,MAAM,YAAA,GAAee,YAAA,CAAY,UAAA,CAAW,IAAA,CAAK,IAAI,CAAC,CAAA;AACtD,IAAA,YAAA,CAAa,GAAA,CAAI,YAAA,EAAc,IAAA,CAAK,KAAK,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,UAAA,GAAa,kBAAkB,UAAU,CAAA;AAE/C,EAAA,IAAI,YAAA,GAAe,CAAA;AACnB,EAAA,IAAI,YAAA,GAAe,CAAA;AAEnB,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,MAAM,MAAA,GAAS,iBAAA,CAAkB,SAAA,CAAU,OAAA,EAAS,UAAU,OAAO,CAAA;AAErE,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,YAAA,EAAA;AACA,MAAA,eAAA,CAAgB,UAAA,EAAY,SAAA,CAAU,SAAA,EAAW,MAAA,CAAO,SAAS,qBAAqB,CAAA;AACtF,MAAA,IAAA,CAAA,eAAA,sBAAuC;AAAA,QACrC,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,UAAU,SAAA,CAAU,QAAA;AAAA,QACpB,OAAO,MAAA,CAAO;AAAA,OACf,CAAA;AACD,MAAAD,OAAAA,CAAO,KAAK,wBAAA,EAA0B;AAAA,QACpC,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,GAAI,OAAO,KAAA,GAAQ,EAAE,OAAO,MAAA,CAAO,KAAA,KAAU;AAAC,OAC/C,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAe;AAAA,MACnB,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,WAAW,SAAA,CAAU,SAAA;AAAA,MACrB,UAAU,SAAA,CAAU,QAAA;AAAA,MACpB,UAAA,EAAY,YAAA,CAAa,GAAA,CAAI,SAAA,CAAU,QAAQ,CAAA,IAAK;AAAA,KACtD;AAEA,IAAA,IAAI,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA,EAAG;AACnC,MAAA,YAAA,EAAA;AACA,MAAA,MAAM,QAAA,GAAW,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,SAAS,IAAI,CAAA;AAC/C,MAAA,MAAM,cAAA,GACJ,CAAA,sBAAA,EAAyB,KAAA,CAAM,QAAA,CAAS,IAAI,WAAW,SAAA,CAAU,QAAQ,CAAA,+BAAA,EAChD,QAAA,CAAS,QAAQ,CAAA,+BAAA,CAAA;AAE5C,MAAA,eAAA,CAAgB,UAAA,EAAY,SAAA,CAAU,SAAA,EAAW,cAAc,CAAA;AAC/D,MAAA,IAAA,CAAA,eAAA,sBAAuC;AAAA,QACrC,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,UAAU,SAAA,CAAU,QAAA;AAAA,QACpB,aAAa,QAAA,CAAS,SAAA;AAAA,QACtB,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAAA,OAAAA,CAAO,KAAK,qCAAA,EAAuC;AAAA,QACjD,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,QACrB,MAAM,QAAA,CAAS,SAAA;AAAA,QACf,SAAS,SAAA,CAAU;AAAA,OACpB,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,QAAA,CAAS,IAAA,EAAM,KAAK,CAAA;AACrC,IAAA,YAAA,EAAA;AACA,IAAA,IAAA,CAAA,kBAAA,yBAA0C,KAAK,CAAA;AAC/C,IAAAA,OAAAA,CAAO,MAAM,kBAAA,EAAoB;AAAA,MAC/B,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,MACrB,aAAa,KAAA,CAAM,QAAA,CAAS,WAAA,CAAY,KAAA,CAAM,GAAG,EAAE,CAAA;AAAA,MACnD,WAAW,KAAA,CAAM;AAAA,KAClB,CAAA;AAAA,EACH;AAEA,EAAAA,OAAAA,CAAO,KAAK,0BAAA,EAA4B;AAAA,IACtC,YAAA,EAAc,OAAO,UAAA,CAAW,MAAA;AAAA,IAChC,gBAAA,EAAkB,YAAA;AAAA,IAClB,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,OAAO,UAAA;AACT;AAEA,SAAS,eAAA,CAAgB,UAAA,EAAyB,IAAA,EAAc,KAAA,EAAqB;AACnF,EAAA,UAAA,CAAW,IAAA,CAAK,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA;AACjC;ACjGA,IAAMA,UAASf,iBAAAA,CAAa,4BAAA,EAA8B,EAAE,KAAA,EAAOC,aAAAA,CAAS,MAAM,CAAA;AAE3E,SAAS,uBAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACM;AACN,EAAA,IAAI,CAAC,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,EAAG;AAC7B,IAAA,aAAA,CAAc,GAAA,CAAI,KAAA,kBAAO,IAAI,GAAA,EAAK,CAAA;AAAA,EACpC;AAEA,EAAA,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,CAAG,GAAA,CAAI,OAAO,CAAA;AACvC;AAEO,SAAS,0BAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACM;AACN,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AACxC,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,QAAA,CAAS,OAAO,OAAO,CAAA;AAAA,EACzB;AACF;AAEO,SAAS,iBAAA,CACd,aAAA,EACA,KAAA,EACA,IAAA,EACM;AACN,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AACxC,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA;AAAA,EACF;AAEA,EAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC5B,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IACd,SAAS,KAAA,EAAO;AACd,MAAAc,OAAAA,CAAO,MAAM,2BAAA,EAA6B;AAAA,QACxC,KAAA;AAAA,QACA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAAA,QAC5D,GAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,KAAA,GAAQ,EAAE,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,GAAI;AAAC,OACvE,CAAA;AAAA,IACH;AAAA,EACF,CAAC,CAAA;AACH;AChDA,IAAMA,UAASf,iBAAAA,CAAa,4BAAA,EAA8B,EAAE,KAAA,EAAOC,aAAAA,CAAS,MAAM,CAAA;AAE3E,SAAS,mBAAA,CACd,MAAA,EACA,SAAA,EACA,eAAA,EACA,OAAA,EACQ;AACR,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAAc,OAAAA,CAAO,MAAM,4CAAA,EAA8C;AAAA,MACzD,OAAA,EAAS,OAAO,OAAA,IAAW;AAAA,KAC5B,CAAA;AACD,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,IAAI,MAAA,GAAS,SAAA;AAEb,EAAA,IAAI,OAAA,EAAS,MAAA,IAAU,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,EAAG;AAChD,IAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,OAAA,CAAQ,MAAM,CAAA;AACxC,IAAA,MAAA,GAAS,MAAA,CAAO,OAAO,CAAC,KAAA,KAAU,UAAU,GAAA,CAAI,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA;AAAA,EACtE;AAEA,EAAA,IAAI,gBAAgB,MAAA,CAAO,MAAA;AAAA,IACzB,CAAC,KAAA,KAAU,KAAA,CAAM,UAAA,KAAe,WAAA,IAAe,MAAM,UAAA,KAAe;AAAA,GACtE;AACA,EAAA,IAAI,kBAAkB,MAAA,CAAO,MAAA;AAAA,IAC3B,CAAC,KAAA,KAAU,KAAA,CAAM,UAAA,KAAe,WAAA,IAAe,MAAM,UAAA,KAAe;AAAA,GACtE;AAEA,EAAA,IAAI,MAAA,CAAO,mBAAA,KAAwB,MAAA,IAAa,MAAA,CAAO,uBAAuB,CAAA,EAAG;AAC/E,IAAA,MAAM,eAAe,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,mBAAA,EAAqB,cAAc,MAAM,CAAA;AAC9E,IAAA,aAAA,GAAgB,aAAA,CAAc,KAAA,CAAM,CAAA,EAAG,YAAY,CAAA;AACnD,IAAA,eAAA,GAAkB,eAAA,CAAgB,KAAA,CAAM,CAAA,EAAG,MAAA,CAAO,sBAAsB,YAAY,CAAA;AACpF,IAAA,MAAA,GAAS,CAAC,GAAG,aAAA,EAAe,GAAG,eAAe,CAAA;AAAA,EAChD;AAEA,EAAA,IAAI,aAAA,CAAc,MAAA,KAAW,CAAA,IAAK,eAAA,CAAgB,WAAW,CAAA,EAAG;AAC9D,IAAAA,OAAAA,CAAO,MAAM,+CAAA,EAAiD;AAAA,MAC5D,eAAA;AAAA,MACA,eAAe,CAAC,EAAE,SAAS,MAAA,IAAU,OAAA,CAAQ,OAAO,MAAA,GAAS,CAAA,CAAA;AAAA,MAC7D,GAAI,OAAO,mBAAA,KAAwB,MAAA,GAC/B,EAAE,MAAA,EAAQ,MAAA,CAAO,mBAAA,EAAoB,GACrC;AAAC,KACN,CAAA;AACD,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAqB,EAAC;AAE5B,EAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,IAAA,QAAA,CAAS,IAAA,CAAK,CAAA;AAAA,EAAuB,cAAc,GAAA,CAAI,uBAAuB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC;AAAA,mBAAA,CAAuB,CAAA;AAAA,EACnH;AAEA,EAAA,IAAI,eAAA,CAAgB,SAAS,CAAA,EAAG;AAC9B,IAAA,QAAA,CAAS,IAAA,CAAK,4BAAA,CAA6B,eAAe,CAAC,CAAA;AAAA,EAC7D;AAEA,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA;AAC9B,EAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,SAAS,CAAC,CAAA;AAEhD,EAAAA,OAAAA,CAAO,KAAK,wBAAA,EAA0B;AAAA,IACpC,YAAY,MAAA,CAAO,MAAA;AAAA,IACnB,mBAAmB,aAAA,CAAc,MAAA;AAAA,IACjC,qBAAqB,eAAA,CAAgB,MAAA;AAAA,IACrC,eAAA;AAAA,IACA,eAAe,CAAC,EAAE,SAAS,MAAA,IAAU,OAAA,CAAQ,OAAO,MAAA,GAAS,CAAA,CAAA;AAAA,IAC7D,GAAI,OAAO,mBAAA,KAAwB,MAAA,GAAY,EAAE,MAAA,EAAQ,MAAA,CAAO,mBAAA,EAAoB,GAAI,EAAC;AAAA,IACzF,eAAA;AAAA,IACA,WAAW,GAAA,CAAI;AAAA,GAChB,CAAA;AAED,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,wBAAwB,KAAA,EAAsB;AACrD,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,CAAA,UAAA,EAAa,SAAA,CAAU,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,OAAA,CAAA;AAAA,IAC3C,CAAA,iBAAA,EAAoB,SAAA,CAAU,KAAA,CAAM,QAAA,CAAS,WAAW,CAAC,CAAA,cAAA,CAAA;AAAA,IACzD,CAAA,cAAA,EAAiB,SAAA,CAAU,KAAA,CAAM,SAAS,CAAC,CAAA,WAAA,CAAA;AAAA,IAC3C,CAAA,WAAA,EAAc,SAAA,CAAU,KAAA,CAAM,UAAU,CAAC,CAAA,QAAA,CAAA;AAAA,IACzC;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;AAEA,SAAS,6BAA6B,MAAA,EAAyB;AAC7D,EAAA,OAAO;AAAA,IACL,oBAAA;AAAA,IACA,0KAAA;AAAA,IACA,GAAG,MAAA,CAAO,GAAA,CAAI,yBAAyB,CAAA;AAAA,IACvC;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;AAEA,SAAS,0BAA0B,KAAA,EAAsB;AACvD,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,CAAA,UAAA,EAAa,SAAA,CAAU,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,OAAA,CAAA;AAAA,IAC3C,CAAA,iBAAA,EAAoB,SAAA,CAAU,KAAA,CAAM,QAAA,CAAS,WAAW,CAAC,CAAA,cAAA,CAAA;AAAA,IACzD,CAAA,cAAA,EAAiB,SAAA,CAAU,KAAA,CAAM,SAAS,CAAC,CAAA,WAAA,CAAA;AAAA,IAC3C,CAAA,WAAA,EAAc,SAAA,CAAU,KAAA,CAAM,UAAU,CAAC,CAAA,QAAA,CAAA;AAAA,IACzC,kEAAA;AAAA,IACA;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;AAEA,SAAS,UAAU,GAAA,EAAqB;AACtC,EAAA,OAAO,IACJ,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA,CACrB,OAAA,CAAQ,MAAM,MAAM,CAAA,CACpB,QAAQ,IAAA,EAAM,MAAM,EACpB,OAAA,CAAQ,IAAA,EAAM,QAAQ,CAAA,CACtB,OAAA,CAAQ,MAAM,QAAQ,CAAA;AAC3B;;;AClGO,IAAM,gBAAN,MAAoB;AAAA,EACjB,MAAA,uBAAiC,GAAA,EAAI;AAAA,EACrC,aAAA,uBAA2C,GAAA,EAAI;AAAA,EACtC,MAAA;AAAA,EACT,aAAqD,EAAC;AAAA,EACtD,YAAA,uBAA4C,GAAA,EAAI;AAAA,EAExD,YAAY,MAAA,EAA6B;AACvC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,QAAA,EAAS;AAAA,EAChB;AAAA,EAEA,QAAA,GAAiB;AACf,IAAA,IAAA,CAAK,UAAA,GAAa,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,QAAQ,IAAA,CAAK,YAAA,EAAc,CAAC,KAAA,EAAO,IAAA,KAAS;AAC7F,MAAA,IAAA,CAAK,IAAA,CAAK,OAAO,IAAI,CAAA;AAAA,IACvB,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,IAAI,IAAA,EAAiC;AACnC,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AAAA,EAC7B;AAAA,EAEA,MAAA,GAAkB;AAChB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA;AAAA,EACxC;AAAA,EAEA,IAAI,IAAA,EAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AAAA,EAC7B;AAAA,EAEA,IAAA,GAAe;AACb,IAAA,OAAO,KAAK,MAAA,CAAO,IAAA;AAAA,EACrB;AAAA,EAEA,QAAA,GAAqB;AACnB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAAA,EACtC;AAAA,EAEA,aAAA,GAAgE;AAC9D,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AAAA,EAEA,wBAAA,GAAoC;AAClC,IAAA,OAAO,IAAA,CAAK,OAAO,qBAAA,IAAyB,KAAA;AAAA,EAC9C;AAAA,EAEA,gBAAgB,IAAA,EAAoC;AAClD,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,IAAI,GAAG,QAAA,CAAS,YAAA;AAAA,EACzC;AAAA,EAEA,eAAe,OAAA,EAAsC;AACnD,IAAA,OAAO,mBAAA,CAAoB,KAAK,MAAA,EAAQ,IAAA,CAAK,QAAO,EAAG,IAAA,CAAK,IAAA,EAAK,EAAG,OAAO,CAAA;AAAA,EAC7E;AAAA,EAEA,EAAA,CAAG,OAA2B,OAAA,EAAkC;AAC9D,IAAA,uBAAA,CAAwB,IAAA,CAAK,aAAA,EAAe,KAAA,EAAO,OAAO,CAAA;AAAA,EAC5D;AAAA,EAEA,GAAA,CAAI,OAA2B,OAAA,EAAkC;AAC/D,IAAA,0BAAA,CAA2B,IAAA,CAAK,aAAA,EAAe,KAAA,EAAO,OAAO,CAAA;AAAA,EAC/D;AAAA,EAEA,SAAA,CAAU,OAA2B,IAAA,EAAqB;AACxD,IAAA,IAAA,CAAK,IAAA,CAAK,OAAO,IAAI,CAAA;AAAA,EACvB;AAAA,EAEA,iBAAA,GAAmE;AACjE,IAAA,OAAO,2BAA2B,IAAI,CAAA;AAAA,EACxC;AAAA,EAEQ,IAAA,CAAK,OAA2B,IAAA,EAAqB;AAC3D,IAAA,iBAAA,CAAkB,IAAA,CAAK,aAAA,EAAe,KAAA,EAAO,IAAI,CAAA;AAAA,EACnD;AACF","file":"index.cjs","sourcesContent":["/**\n * Skill System Types\n *\n * Core type definitions for the AgentForge Agent Skills system.\n * These types align with the Agent Skills specification (https://agentskills.io/specification).\n */\n\n// ─── Trust Policy Types ──────────────────────────────────────────────────\n\n/**\n * Trust level for a skill root directory.\n *\n * - `workspace` — Skills from the project workspace (highest trust, scripts allowed)\n * - `trusted` — Explicitly trusted skill roots (scripts allowed)\n * - `untrusted` — Untrusted roots like community packs (scripts blocked by default)\n */\nexport type TrustLevel = 'workspace' | 'trusted' | 'untrusted';\n\n/**\n * Configuration for a skill root with an explicit trust level.\n *\n * @example\n * ```ts\n * const roots: SkillRootConfig[] = [\n * { path: '.agentskills', trust: 'workspace' },\n * { path: '~/.agentskills', trust: 'trusted' },\n * { path: '/shared/community-skills', trust: 'untrusted' },\n * ];\n * ```\n */\nexport interface SkillRootConfig {\n /** Directory path to scan for skills */\n path: string;\n /** Trust level assigned to all skills discovered from this root */\n trust: TrustLevel;\n}\n\n/**\n * Policy decision returned by trust enforcement checks.\n */\nexport interface TrustPolicyDecision {\n /** Whether the action is allowed */\n allowed: boolean;\n /** Machine-readable reason code for auditing */\n reason: TrustPolicyReason;\n /** Human-readable explanation */\n message: string;\n}\n\n/**\n * Reason codes for trust policy decisions.\n *\n * Used for structured logging and auditing of guardrail behavior.\n */\nexport enum TrustPolicyReason {\n /** Resource is not a script — no trust check needed */\n NOT_SCRIPT = 'not-script',\n /** Skill root has workspace trust — scripts allowed */\n WORKSPACE_TRUST = 'workspace-trust',\n /** Skill root has explicit trusted status — scripts allowed */\n TRUSTED_ROOT = 'trusted-root',\n /** Skill body activation allowed because the root is workspace-owned */\n WORKSPACE_SKILL_ACTIVATION = 'workspace-skill-activation',\n /** Skill body activation allowed because the root is explicitly trusted */\n TRUSTED_SKILL_ACTIVATION = 'trusted-skill-activation',\n /** Full skill-body activation denied for an untrusted root */\n UNTRUSTED_SKILL_ACTIVATION_DENIED = 'untrusted-skill-activation-denied',\n /** Skill root is untrusted — scripts denied by default */\n UNTRUSTED_SCRIPT_DENIED = 'untrusted-script-denied',\n /** Untrusted script access was explicitly allowed via config override */\n UNTRUSTED_SCRIPT_ALLOWED = 'untrusted-script-allowed-override',\n /** Trust level is unknown — treated as untrusted for security */\n UNKNOWN_TRUST_LEVEL = 'unknown-trust-level',\n}\n\n/**\n * Parsed metadata from a SKILL.md frontmatter block.\n *\n * Required fields: `name`, `description`.\n * All other fields are optional per the Agent Skills spec.\n */\nexport interface SkillMetadata {\n /** Skill name (1-64 chars, lowercase alphanumeric + hyphens, must match parent dir name) */\n name: string;\n /** Human-readable description (1-1024 chars) */\n description: string;\n /** SPDX license identifier */\n license?: string;\n /** List of compatible agent frameworks / tool hosts */\n compatibility?: string[];\n /** Arbitrary key-value metadata (author, version, etc.) */\n metadata?: Record<string, unknown>;\n /** Tools that this skill is allowed to use */\n allowedTools?: string[];\n}\n\n/**\n * A fully resolved skill entry in the registry.\n *\n * Contains parsed metadata plus internal tracking fields\n * that are not part of the SKILL.md frontmatter.\n */\nexport interface Skill {\n /** Parsed frontmatter metadata */\n metadata: SkillMetadata;\n /** Absolute path to the skill directory */\n skillPath: string;\n /** Which configured skill root this was discovered from */\n rootPath: string;\n /** Trust level assigned to this skill (inherited from root config) */\n trustLevel: TrustLevel;\n}\n\n/**\n * Configuration for the SkillRegistry.\n */\nexport interface SkillRegistryConfig {\n /**\n * Array of directory paths to scan for skills.\n *\n * Each entry can be a plain string (defaults to `'untrusted'` trust level)\n * or a `SkillRootConfig` object with an explicit trust level.\n *\n * Paths may be absolute or relative (resolved against `cwd`).\n * The `~` prefix is expanded to `$HOME`.\n *\n * @example\n * ```ts\n * // Simple string roots (default to 'untrusted')\n * skillRoots: ['.agentskills', '~/.agentskills']\n *\n * // Trust-aware roots\n * skillRoots: [\n * { path: '.agentskills', trust: 'workspace' },\n * { path: '~/.agentskills', trust: 'trusted' },\n * { path: '/shared/community', trust: 'untrusted' },\n * ]\n * ```\n */\n skillRoots: Array<string | SkillRootConfig>;\n\n /**\n * Feature flag to enable Agent Skills in system prompts.\n *\n * When `false` (default), `generatePrompt()` returns an empty string\n * so agents operate with unmodified system prompts.\n *\n * @default false\n */\n enabled?: boolean;\n\n /**\n * Maximum number of skills to include in generated prompts.\n *\n * Caps prompt token usage when many skills are discovered.\n * Skills are included in discovery order (first root first).\n * When undefined, all discovered skills are included.\n */\n maxDiscoveredSkills?: number;\n\n /**\n * Allow script resources from untrusted roots.\n *\n * When `true`, scripts from `scripts/` directories in untrusted\n * skill roots are returned instead of being denied. This disables\n * the default-deny policy for untrusted scripts.\n *\n * **Security warning:** Only enable when you have reviewed all\n * skill packs from untrusted roots.\n *\n * @default false\n */\n allowUntrustedScripts?: boolean;\n}\n\n/**\n * Options for `SkillRegistry.generatePrompt()`.\n */\nexport interface SkillPromptOptions {\n /**\n * Subset of skill names to include in the generated prompt.\n *\n * When provided, only skills matching these names appear in the\n * `<available_skills>` XML block. This enables creating focused\n * agents with different skill sets from the same registry.\n *\n * When omitted or empty, all discovered skills are included.\n *\n * @example ['code-review', 'testing-strategy']\n */\n skills?: string[];\n}\n\n/**\n * Events emitted by the SkillRegistry during discovery and usage.\n */\nexport enum SkillRegistryEvent {\n /** Emitted when a valid skill is discovered during scanning */\n SKILL_DISCOVERED = 'skill:discovered',\n /** Emitted when a skill parse or validation issue is encountered */\n SKILL_WARNING = 'skill:warning',\n /** Emitted when a skill is activated (full body loaded) */\n SKILL_ACTIVATED = 'skill:activated',\n /** Emitted when a skill resource file is loaded */\n SKILL_RESOURCE_LOADED = 'skill:resource-loaded',\n /** Emitted when a trust policy denies access to a resource */\n TRUST_POLICY_DENIED = 'trust:policy-denied',\n /** Emitted when a trust policy allows access (for auditing) */\n TRUST_POLICY_ALLOWED = 'trust:policy-allowed',\n}\n\n/**\n * Event handler type for skill registry events.\n */\nexport type SkillEventHandler = (data: unknown) => void;\n\n/**\n * Result of parsing a single SKILL.md file.\n */\nexport interface SkillParseResult {\n /** Whether parsing and validation succeeded */\n success: boolean;\n /** Parsed metadata (present when success is true) */\n metadata?: SkillMetadata;\n /** The raw markdown body below the frontmatter (present when success is true) */\n body?: string;\n /** Error description (present when success is false) */\n error?: string;\n}\n\n/**\n * Validation error detail.\n */\nexport interface SkillValidationError {\n /** Which field failed validation */\n field: string;\n /** Human-readable error message */\n message: string;\n}\n","/**\n * SKILL.md Frontmatter Parser\n *\n * Parses YAML frontmatter from SKILL.md files and validates\n * against the Agent Skills specification constraints.\n *\n * @see https://agentskills.io/specification\n */\n\nimport matter from 'gray-matter';\nimport type { SkillMetadata, SkillParseResult, SkillValidationError } from './types.js';\n\n/**\n * Skill name validation constraints (per spec).\n *\n * - 1-64 characters\n * - Lowercase alphanumeric and hyphens only\n * - No leading, trailing, or consecutive hyphens\n */\nconst SKILL_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\nconst SKILL_NAME_MAX_LENGTH = 64;\nconst SKILL_DESCRIPTION_MAX_LENGTH = 1024;\n\n/**\n * Validate the `name` field per the Agent Skills spec.\n *\n * @param name - The name value from frontmatter\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillName(name: unknown): SkillValidationError[] {\n const errors: SkillValidationError[] = [];\n\n if (name === undefined || name === null) {\n errors.push({ field: 'name', message: 'name is required' });\n return errors;\n }\n\n if (typeof name !== 'string') {\n errors.push({ field: 'name', message: 'name must be a string' });\n return errors;\n }\n\n if (name.length === 0) {\n errors.push({ field: 'name', message: 'name must not be empty' });\n return errors;\n }\n\n if (name.length > SKILL_NAME_MAX_LENGTH) {\n errors.push({\n field: 'name',\n message: `name must be at most ${SKILL_NAME_MAX_LENGTH} characters (got ${name.length})`,\n });\n return errors;\n }\n\n if (!SKILL_NAME_PATTERN.test(name)) {\n errors.push({\n field: 'name',\n message: 'name must be lowercase alphanumeric with hyphens, no leading/trailing/consecutive hyphens',\n });\n }\n\n if (name.includes('--')) {\n errors.push({\n field: 'name',\n message: 'name must not contain consecutive hyphens',\n });\n }\n\n return errors;\n}\n\n/**\n * Validate the `description` field per the Agent Skills spec.\n *\n * @param description - The description value from frontmatter\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillDescription(description: unknown): SkillValidationError[] {\n const errors: SkillValidationError[] = [];\n\n if (description === undefined || description === null) {\n errors.push({ field: 'description', message: 'description is required' });\n return errors;\n }\n\n if (typeof description !== 'string') {\n errors.push({ field: 'description', message: 'description must be a string' });\n return errors;\n }\n\n if (description.trim().length === 0) {\n errors.push({ field: 'description', message: 'description must not be empty' });\n return errors;\n }\n\n if (description.length > SKILL_DESCRIPTION_MAX_LENGTH) {\n errors.push({\n field: 'description',\n message: `description must be at most ${SKILL_DESCRIPTION_MAX_LENGTH} characters (got ${description.length})`,\n });\n }\n\n return errors;\n}\n\n/**\n * Validate that the skill name matches its parent directory name (per spec).\n *\n * @param name - The name from frontmatter\n * @param dirName - The parent directory name\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillNameMatchesDir(name: string, dirName: string): SkillValidationError[] {\n if (name !== dirName) {\n return [{\n field: 'name',\n message: `name \"${name}\" must match parent directory name \"${dirName}\"`,\n }];\n }\n return [];\n}\n\n/**\n * Parse and validate a SKILL.md file's raw content.\n *\n * Extracts YAML frontmatter using gray-matter, then validates\n * required and optional fields against spec constraints.\n *\n * @param content - Raw file content of the SKILL.md\n * @param dirName - Parent directory name for name-match validation\n * @returns Parse result with metadata or error\n */\nexport function parseSkillContent(content: string, dirName: string): SkillParseResult {\n let parsed: matter.GrayMatterFile<string>;\n\n try {\n parsed = matter(content);\n } catch (err) {\n return {\n success: false,\n error: `Failed to parse frontmatter: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n const data = parsed.data;\n\n // Validate required fields\n const errors: SkillValidationError[] = [\n ...validateSkillName(data.name),\n ...validateSkillDescription(data.description),\n ];\n\n // If name is valid, validate it matches directory name\n if (typeof data.name === 'string' && data.name.length > 0 && SKILL_NAME_PATTERN.test(data.name)) {\n errors.push(...validateSkillNameMatchesDir(data.name, dirName));\n }\n\n if (errors.length > 0) {\n return {\n success: false,\n error: errors.map((e) => `${e.field}: ${e.message}`).join('; '),\n };\n }\n\n // Build metadata from validated fields\n const metadata: SkillMetadata = {\n name: data.name as string,\n description: data.description as string,\n };\n\n // Optional fields\n if (data.license !== undefined) {\n metadata.license = String(data.license);\n }\n\n if (Array.isArray(data.compatibility)) {\n metadata.compatibility = data.compatibility.map(String);\n }\n\n if (data.metadata !== undefined && typeof data.metadata === 'object' && data.metadata !== null) {\n metadata.metadata = data.metadata as Record<string, unknown>;\n }\n\n if (Array.isArray(data['allowed-tools'])) {\n metadata.allowedTools = data['allowed-tools'].map(String);\n }\n\n return {\n success: true,\n metadata,\n body: parsed.content,\n };\n}\n","/**\n * Skill Directory Scanner\n *\n * Scans configured skill roots for directories containing valid SKILL.md files.\n * Returns a list of candidate skill paths for the parser to process.\n */\n\nimport { existsSync, readdirSync, statSync, readFileSync } from 'node:fs';\nimport { resolve, basename } from 'node:path';\nimport { homedir } from 'node:os';\nimport { createLogger, LogLevel } from '@agentforge/core';\n\nconst logger = createLogger('agentforge:skills:scanner', { level: LogLevel.INFO });\n\n/**\n * Discovered skill candidate — a directory containing a SKILL.md file.\n */\nexport interface SkillCandidate {\n /** Absolute path to the skill directory */\n skillPath: string;\n /** The parent directory name (expected to match the skill name) */\n dirName: string;\n /** Raw content of the SKILL.md file */\n content: string;\n /** Which configured root this came from */\n rootPath: string;\n}\n\n/**\n * Expand `~` prefix to the user's home directory.\n */\nexport function expandHome(p: string): string {\n if (p.startsWith('~/') || p === '~') {\n return resolve(homedir(), p.slice(2));\n }\n return p;\n}\n\n/**\n * Scan a single skill root for directories containing SKILL.md.\n *\n * @param rootPath - The root directory to scan (may not exist)\n * @returns Array of valid skill candidates found under this root\n */\nexport function scanSkillRoot(rootPath: string): SkillCandidate[] {\n const resolvedRoot = resolve(expandHome(rootPath));\n const candidates: SkillCandidate[] = [];\n\n if (!existsSync(resolvedRoot)) {\n logger.debug('Skill root does not exist, skipping', { rootPath: resolvedRoot });\n return candidates;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(resolvedRoot);\n } catch (err) {\n logger.warn('Failed to read skill root directory', {\n rootPath: resolvedRoot,\n error: err instanceof Error ? err.message : String(err),\n });\n return candidates;\n }\n\n for (const entry of entries) {\n const entryPath = resolve(resolvedRoot, entry);\n\n // Only process directories\n let stat;\n try {\n stat = statSync(entryPath);\n } catch {\n continue;\n }\n if (!stat.isDirectory()) {\n continue;\n }\n\n // Check for SKILL.md inside the directory\n const skillMdPath = resolve(entryPath, 'SKILL.md');\n if (!existsSync(skillMdPath)) {\n continue;\n }\n\n // Read the SKILL.md content\n try {\n const content = readFileSync(skillMdPath, 'utf-8');\n candidates.push({\n skillPath: entryPath,\n dirName: basename(entryPath),\n content,\n rootPath: resolvedRoot,\n });\n } catch (err) {\n logger.warn('Failed to read SKILL.md', {\n path: skillMdPath,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n logger.debug('Scanned skill root', {\n rootPath: resolvedRoot,\n candidatesFound: candidates.length,\n });\n\n return candidates;\n}\n\n/**\n * Scan multiple skill roots for directories containing SKILL.md.\n *\n * @param skillRoots - Array of root paths to scan\n * @returns Array of all skill candidates found across all roots\n */\nexport function scanAllSkillRoots(skillRoots: string[]): SkillCandidate[] {\n const allCandidates: SkillCandidate[] = [];\n\n for (const root of skillRoots) {\n const candidates = scanSkillRoot(root);\n allCandidates.push(...candidates);\n }\n\n logger.info('Skill discovery complete', {\n rootsScanned: skillRoots.length,\n totalCandidates: allCandidates.length,\n });\n\n return allCandidates;\n}\n","import matter from 'gray-matter';\n\n/**\n * Extract the body content below YAML frontmatter from a SKILL.md file.\n *\n * Delegates to `gray-matter` for consistent frontmatter handling across\n * the codebase (matches `parseSkillContent()` in parser.ts).\n *\n * @param content - The full SKILL.md file content\n * @returns The body content below the frontmatter\n */\nexport function extractBody(content: string): string {\n return matter(content).content.trim();\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\n\nexport const activationLogger = createLogger('agentforge:skills:activation', {\n level: LogLevel.INFO,\n});\n\nexport function formatMissingSkillMessage(name: string, availableNames: string[]): string {\n const suggestion = availableNames.length > 0\n ? ` Available skills: ${availableNames.join(', ')}`\n : ' No skills are currently registered.';\n\n return `Skill \"${name}\" not found.${suggestion}`;\n}\n","/**\n * Skill Trust Policy Engine\n *\n * Enforces trust-level-based access control for skill resources.\n * Scripts from untrusted roots are denied by default unless explicitly allowed.\n *\n * Trust levels:\n * - `workspace` — Project-local skills, highest trust. Scripts always allowed.\n * - `trusted` — Explicitly trusted roots. Scripts allowed.\n * - `untrusted` — Community or third-party skills. Scripts denied by default.\n *\n * @see https://agentskills.io/specification\n */\n\nimport type { TrustLevel, TrustPolicyDecision, SkillRootConfig } from './types.js';\nimport { TrustPolicyReason } from './types.js';\n\n// ─── Constants ───────────────────────────────────────────────────────────\n\n/**\n * Resource path prefix that requires trust enforcement.\n *\n * Only resources under `scripts/` are subject to trust policy checks.\n * Other directories (references/, assets/, etc.) are always accessible.\n */\nconst SCRIPT_PATH_PREFIX = 'scripts/';\nconst SCRIPT_PATH_EXACT = 'scripts';\n\n// ─── Helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Normalize a skill root config entry.\n *\n * String entries default to `'untrusted'` trust level for safe defaults.\n *\n * @param root - A string path or SkillRootConfig object\n * @returns Normalized SkillRootConfig with explicit trust level\n */\nexport function normalizeRootConfig(root: string | SkillRootConfig): SkillRootConfig {\n if (typeof root === 'string') {\n return { path: root, trust: 'untrusted' };\n }\n return root;\n}\n\n/**\n * Check whether a resource path refers to a script.\n *\n * A resource is considered a script if its relative path starts with\n * `scripts/` or is exactly `scripts`, after normalizing path separators,\n * stripping leading \"./\" segments, and ignoring case.\n *\n * @param resourcePath - Relative path within the skill directory\n * @returns True if the resource is in the scripts/ directory\n */\nexport function isScriptResource(resourcePath: string): boolean {\n // Normalize to forward slashes and trim for consistent checking\n let normalized = resourcePath.trim().replace(/\\\\/g, '/');\n\n // Collapse repeated separators (e.g., \"scripts//setup.sh\" → \"scripts/setup.sh\")\n normalized = normalized.replace(/\\/+/g, '/');\n\n // Strip leading \"./\" segments (e.g., \"./scripts/setup.sh\" → \"scripts/setup.sh\")\n while (normalized.startsWith('./')) {\n normalized = normalized.slice(2);\n }\n\n // Case-insensitive comparison to handle case-insensitive file systems\n const lower = normalized.toLowerCase();\n\n return lower === SCRIPT_PATH_EXACT\n || lower.startsWith(SCRIPT_PATH_PREFIX);\n}\n\n// ─── Policy Engine ───────────────────────────────────────────────────────\n\n/**\n * Evaluate the trust policy for a resource access request.\n *\n * Non-script resources are allowed regardless of trust level, except for\n * SKILL.md, which is protected by the activation policy.\n * Script resources require `workspace` or `trusted` trust, or the\n * `allowUntrustedScripts` override to be enabled.\n *\n * @param resourcePath - Relative path to the resource within the skill directory\n * @param trustLevel - Trust level of the skill's root directory\n * @param allowUntrustedScripts - Override flag to permit untrusted scripts\n * @returns Policy decision with allow/deny, reason code, and message\n */\nexport function evaluateTrustPolicy(\n resourcePath: string,\n trustLevel: TrustLevel,\n allowUntrustedScripts: boolean = false,\n): TrustPolicyDecision {\n // Non-script resources — SKILL.md is checked separately by the resource tool.\n if (!isScriptResource(resourcePath)) {\n return {\n allowed: true,\n reason: TrustPolicyReason.NOT_SCRIPT,\n message: 'Resource is not a script — no trust check required',\n };\n }\n\n // Script resources — check trust level\n switch (trustLevel) {\n case 'workspace':\n return {\n allowed: true,\n reason: TrustPolicyReason.WORKSPACE_TRUST,\n message: 'Script allowed — skill root has workspace trust',\n };\n\n case 'trusted':\n return {\n allowed: true,\n reason: TrustPolicyReason.TRUSTED_ROOT,\n message: 'Script allowed — skill root is explicitly trusted',\n };\n\n case 'untrusted':\n if (allowUntrustedScripts) {\n return {\n allowed: true,\n reason: TrustPolicyReason.UNTRUSTED_SCRIPT_ALLOWED,\n message: 'Script from untrusted root allowed via allowUntrustedScripts override',\n };\n }\n return {\n allowed: false,\n reason: TrustPolicyReason.UNTRUSTED_SCRIPT_DENIED,\n message: `Script access denied — skill root is untrusted. ` +\n `Scripts from untrusted roots are blocked by default for security. ` +\n `To allow, set 'allowUntrustedScripts: true' in SkillRegistryConfig or ` +\n `promote the skill root to 'trusted' or 'workspace' trust level.`,\n };\n\n default:\n return {\n allowed: false,\n reason: TrustPolicyReason.UNKNOWN_TRUST_LEVEL,\n message: `Script access denied — trust level \"${trustLevel}\" is unknown and is treated as untrusted for security.`,\n };\n }\n}\n\n/**\n * Evaluate whether the full SKILL.md body can be exposed through activation.\n *\n * Untrusted roots stay discoverable, but their full instruction bodies are\n * blocked until the operator explicitly promotes that root to `trusted` or\n * `workspace`.\n */\nexport function evaluateSkillActivationPolicy(trustLevel: TrustLevel): TrustPolicyDecision {\n switch (trustLevel) {\n case 'workspace':\n return {\n allowed: true,\n reason: TrustPolicyReason.WORKSPACE_SKILL_ACTIVATION,\n message: 'Skill activation allowed — skill root has workspace trust',\n };\n\n case 'trusted':\n return {\n allowed: true,\n reason: TrustPolicyReason.TRUSTED_SKILL_ACTIVATION,\n message: 'Skill activation allowed — skill root is explicitly trusted',\n };\n\n case 'untrusted':\n return {\n allowed: false,\n reason: TrustPolicyReason.UNTRUSTED_SKILL_ACTIVATION_DENIED,\n message: `Skill activation blocked — skill root is untrusted. ` +\n `Untrusted skills remain discoverable, but their full SKILL.md bodies are blocked by default. ` +\n `Promote the skill root to 'trusted' or 'workspace' trust level after review to allow activation.`,\n };\n\n default:\n return {\n allowed: false,\n reason: TrustPolicyReason.UNKNOWN_TRUST_LEVEL,\n message: `Skill activation blocked — trust level \"${trustLevel}\" is unknown and is treated as untrusted for security.`,\n };\n }\n}\n","import { readFileSync, realpathSync } from 'node:fs';\nimport { isAbsolute, relative, resolve } from 'node:path';\nimport type { SkillRegistry } from './registry.js';\nimport { SkillRegistryEvent, TrustPolicyReason } from './types.js';\nimport { extractBody } from './activation-content.js';\nimport { activationLogger } from './activation-shared.js';\nimport { evaluateSkillActivationPolicy, evaluateTrustPolicy } from './trust.js';\n\nconst PATH_TRAVERSAL_MESSAGE =\n 'Path traversal is not allowed — resource paths must stay within the skill directory';\nconst SYMLINK_ESCAPE_MESSAGE = 'Symlink target escapes the skill directory — access denied';\n\ntype CanonicalResourcePathResult =\n | {\n kind: 'success';\n resolvedPath: string;\n canonicalPath: string;\n canonicalRelativePath: string;\n }\n | { kind: 'access-denied'; message: string }\n | { kind: 'resource-not-found'; resolvedPath: string; error: string }\n | { kind: 'target-read-failure'; resolvedPath: string; error: string }\n | { kind: 'read-failure'; error: string };\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction formatResourceReadError(error: unknown, resolvedPath: string): string {\n const message = formatError(error);\n const detailIndex = message.indexOf(', ');\n const prefix = detailIndex === -1 ? message : message.slice(0, detailIndex);\n return `${prefix}, open '${resolvedPath}'`;\n}\n\nfunction resolveCanonicalResourcePath(\n skillPath: string,\n resourcePath: string\n): CanonicalResourcePathResult {\n if (isAbsolute(resourcePath)) {\n return { kind: 'access-denied', message: 'Absolute resource paths are not allowed' };\n }\n\n if (resourcePath.split(/[/\\\\]/).some((segment) => segment === '..')) {\n return { kind: 'access-denied', message: PATH_TRAVERSAL_MESSAGE };\n }\n\n const resolvedSkillPath = resolve(skillPath);\n const resolvedPath = resolve(resolvedSkillPath, resourcePath);\n const lexicalRelativePath = relative(resolvedSkillPath, resolvedPath);\n if (\n lexicalRelativePath.startsWith('..') ||\n isAbsolute(lexicalRelativePath) ||\n resolve(resolvedSkillPath, lexicalRelativePath) !== resolvedPath\n ) {\n return { kind: 'access-denied', message: PATH_TRAVERSAL_MESSAGE };\n }\n\n let canonicalSkillPath: string;\n try {\n canonicalSkillPath = realpathSync(resolvedSkillPath);\n } catch (error) {\n return { kind: 'read-failure', error: formatResourceReadError(error, resolvedPath) };\n }\n\n let canonicalPath: string;\n try {\n canonicalPath = realpathSync(resolvedPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return {\n kind: 'resource-not-found',\n resolvedPath,\n error: formatResourceReadError(error, resolvedPath),\n };\n }\n return {\n kind: 'target-read-failure',\n resolvedPath,\n error: formatResourceReadError(error, resolvedPath),\n };\n }\n\n const canonicalRelativePath = relative(canonicalSkillPath, canonicalPath);\n if (canonicalRelativePath.startsWith('..') || isAbsolute(canonicalRelativePath)) {\n return { kind: 'access-denied', message: SYMLINK_ESCAPE_MESSAGE };\n }\n\n return { kind: 'success', resolvedPath, canonicalPath, canonicalRelativePath };\n}\n\nexport type SkillActivationResult =\n | { kind: 'success'; body: string }\n | { kind: 'skill-not-found'; name: string; availableNames: string[] }\n | { kind: 'access-denied'; reason: TrustPolicyReason; message: string }\n | { kind: 'read-failure'; name: string; error: string };\n\nexport type SkillResourceResult =\n | { kind: 'success'; content: string }\n | { kind: 'skill-not-found'; name: string; availableNames: string[] }\n | { kind: 'access-denied'; message: string; reason?: TrustPolicyReason }\n | { kind: 'resource-not-found'; name: string; resourcePath: string; error: string }\n | { kind: 'read-failure'; name: string; resourcePath: string; error: string };\n\n/** Package-internal owner of Agent Skill lookup, policy, reads, and audit signals. */\nexport class AgentSkillAccess {\n constructor(private readonly registry: SkillRegistry) {}\n\n async readResource(name: string, resourcePath: string): Promise<SkillResourceResult> {\n const skill = this.registry.get(name);\n if (!skill) {\n const availableNames = this.registry.getNames();\n activationLogger.warn('Skill resource load failed — skill not found', {\n name,\n resourcePath,\n });\n return { kind: 'skill-not-found', name, availableNames };\n }\n\n const pathResult = resolveCanonicalResourcePath(skill.skillPath, resourcePath);\n if (pathResult.kind === 'access-denied') {\n activationLogger.warn('Skill resource load blocked — path traversal', {\n name,\n resourcePath,\n error: pathResult.message,\n });\n return pathResult;\n }\n if (pathResult.kind === 'read-failure') {\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: pathResult.error,\n });\n return { ...pathResult, name, resourcePath };\n }\n\n const skillInstructionsPath = resolve(skill.skillPath, 'SKILL.md');\n let isSkillInstructions =\n pathResult.resolvedPath.toLowerCase() === skillInstructionsPath.toLowerCase();\n if (!isSkillInstructions && pathResult.kind === 'success') {\n try {\n isSkillInstructions =\n pathResult.canonicalPath.toLowerCase() ===\n realpathSync(skillInstructionsPath).toLowerCase();\n } catch {\n // The resource read below reports missing or unreadable paths.\n }\n }\n if (isSkillInstructions) {\n const activationDecision = evaluateSkillActivationPolicy(skill.trustLevel);\n if (!activationDecision.allowed) {\n activationLogger.warn('Skill resource load blocked — skill instructions trust policy', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: activationDecision.reason,\n message: activationDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath: 'SKILL.md',\n trustLevel: skill.trustLevel,\n reason: activationDecision.reason,\n message: activationDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: activationDecision.reason,\n message: activationDecision.message,\n };\n }\n }\n\n const policyDecision = evaluateTrustPolicy(\n pathResult.kind === 'success' ? pathResult.canonicalRelativePath : resourcePath,\n skill.trustLevel,\n this.registry.getAllowUntrustedScripts()\n );\n if (!policyDecision.allowed) {\n activationLogger.warn('Skill resource load blocked — trust policy', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: policyDecision.reason,\n message: policyDecision.message,\n };\n }\n\n if (policyDecision.reason !== TrustPolicyReason.NOT_SCRIPT) {\n activationLogger.info('Skill resource trust policy — allowed', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_ALLOWED, {\n name: skill.metadata.name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n });\n }\n\n if (pathResult.kind === 'resource-not-found' || pathResult.kind === 'target-read-failure') {\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: pathResult.error,\n });\n return {\n kind: pathResult.kind === 'resource-not-found' ? 'resource-not-found' : 'read-failure',\n name,\n resourcePath,\n error: pathResult.error,\n };\n }\n\n let content: string;\n try {\n content = readFileSync(pathResult.canonicalPath, 'utf-8');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: message,\n });\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { kind: 'resource-not-found', name, resourcePath, error: message };\n }\n return { kind: 'read-failure', name, resourcePath, error: message };\n }\n\n activationLogger.info('Skill resource loaded', {\n name: skill.metadata.name,\n resourcePath,\n resolvedPath: pathResult.resolvedPath,\n contentLength: content.length,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.SKILL_RESOURCE_LOADED, {\n name: skill.metadata.name,\n resourcePath,\n resolvedPath: pathResult.resolvedPath,\n contentLength: content.length,\n });\n\n return { kind: 'success', content };\n }\n\n async activate(name: string): Promise<SkillActivationResult> {\n const skill = this.registry.get(name);\n if (!skill) {\n const availableNames = this.registry.getNames();\n activationLogger.warn('Skill activation failed — not found', {\n name,\n availableCount: availableNames.length,\n });\n return { kind: 'skill-not-found', name, availableNames };\n }\n\n const policyDecision = evaluateSkillActivationPolicy(skill.trustLevel);\n if (!policyDecision.allowed) {\n activationLogger.warn('Skill activation blocked — trust policy', {\n name,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath: 'SKILL.md',\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: policyDecision.reason,\n message: policyDecision.message,\n };\n }\n\n let body: string;\n try {\n const content = readFileSync(resolve(skill.skillPath, 'SKILL.md'), 'utf-8');\n body = extractBody(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n activationLogger.error('Skill activation failed — read error', {\n name,\n skillPath: skill.skillPath,\n error: message,\n });\n return { kind: 'read-failure', name, error: message };\n }\n\n activationLogger.info('Skill activated', {\n name: skill.metadata.name,\n skillPath: skill.skillPath,\n bodyLength: body.length,\n trustLevel: skill.trustLevel,\n activationReason: policyDecision.reason,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.SKILL_ACTIVATED, {\n name: skill.metadata.name,\n skillPath: skill.skillPath,\n bodyLength: body.length,\n trustLevel: skill.trustLevel,\n });\n\n return { kind: 'success', body };\n }\n}\n","import { z } from 'zod';\n\nexport const activateSkillSchema = z.object({\n name: z.string().describe('The name of the skill to activate (e.g., \"code-review\")'),\n});\n\nexport const readSkillResourceSchema = z.object({\n name: z.string().describe('The name of the skill that owns the resource'),\n path: z.string().describe('Relative path to the resource file within the skill directory (e.g., \"references/GUIDE.md\", \"scripts/setup.sh\")'),\n});\n","import { ToolBuilder, ToolCategory } from '@agentforge/core';\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { AgentSkillAccess } from './agent-skill-access.js';\nimport { activateSkillSchema } from './activation-schemas.js';\nimport { formatMissingSkillMessage } from './activation-shared.js';\n\n/**\n * Create the `activate-skill` tool bound to a registry instance.\n *\n * Resolves the skill by name, reads the full SKILL.md file, and returns\n * the body content (below frontmatter).\n *\n * @param registry - The SkillRegistry to resolve skills from\n * @returns An AgentForge Tool\n */\nexport function createActivateSkillTool(\n registry: SkillRegistry,\n): Tool<z.infer<typeof activateSkillSchema>, string> {\n const access = new AgentSkillAccess(registry);\n\n return new ToolBuilder<z.infer<typeof activateSkillSchema>, string>()\n .name('activate-skill')\n .description(\n 'Activate an Agent Skill by name, loading its full instructions for trusted roots. ' +\n 'Returns the complete SKILL.md body content for workspace or explicitly trusted skills. ' +\n 'Use this when you see a relevant skill in <available_skills> or <untrusted_skills>; ' +\n 'activation is blocked for untrusted roots until they are promoted.',\n )\n .category(ToolCategory.SKILLS)\n .tags(['skill', 'activation', 'agent-skills'])\n .schema(activateSkillSchema)\n .implement(async ({ name }) => {\n const result = await access.activate(name);\n\n switch (result.kind) {\n case 'success':\n return result.body;\n case 'skill-not-found':\n return formatMissingSkillMessage(result.name, result.availableNames);\n case 'access-denied':\n return result.message;\n case 'read-failure':\n return `Failed to read skill \"${result.name}\" instructions: ${result.error}`;\n }\n })\n .build();\n}\n","import { ToolBuilder, ToolCategory } from '@agentforge/core';\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { AgentSkillAccess } from './agent-skill-access.js';\nimport { readSkillResourceSchema } from './activation-schemas.js';\nimport { formatMissingSkillMessage } from './activation-shared.js';\n\n/**\n * Create the `read-skill-resource` tool bound to a registry instance.\n *\n * Resolves the skill by name, validates the resource path (blocking\n * traversal), and returns the file content.\n *\n * @param registry - The SkillRegistry to resolve skills from\n * @returns An AgentForge Tool\n */\nexport function createReadSkillResourceTool(\n registry: SkillRegistry\n): Tool<z.infer<typeof readSkillResourceSchema>, string> {\n const access = new AgentSkillAccess(registry);\n\n return new ToolBuilder<z.infer<typeof readSkillResourceSchema>, string>()\n .name('read-skill-resource')\n .description(\n 'Read a resource file from an activated Agent Skill. ' +\n 'Returns the content of a file within the skill directory (e.g., references/, scripts/, assets/). ' +\n 'The path must be relative to the skill root and cannot traverse outside it. ' +\n 'SKILL.md is only readable from workspace or trusted roots.'\n )\n .category(ToolCategory.SKILLS)\n .tags(['skill', 'resource', 'agent-skills'])\n .schema(readSkillResourceSchema)\n .implement(async ({ name, path: resourcePath }) => {\n const result = await access.readResource(name, resourcePath);\n\n switch (result.kind) {\n case 'success':\n return result.content;\n case 'skill-not-found':\n return formatMissingSkillMessage(result.name, result.availableNames);\n case 'access-denied':\n return result.message;\n case 'resource-not-found':\n case 'read-failure':\n return `Failed to read resource \"${result.resourcePath}\" from skill \"${result.name}\": ${result.error}`;\n }\n })\n .build();\n}\n","import { isAbsolute, relative, resolve } from 'node:path';\nimport { realpathSync } from 'node:fs';\n\n/**\n * Resolve a resource path within a skill root, blocking path traversal.\n *\n * @param skillPath - Absolute path to the skill directory\n * @param resourcePath - Relative path to the resource file\n * @returns A result containing either the resolved absolute path or an error message\n * @deprecated Use the `read-skill-resource` Tool from\n * `SkillRegistry.toActivationTools()` for Agent Skill resource access. This\n * compatibility helper is planned for removal in the next major release.\n */\nexport function resolveResourcePath(\n skillPath: string,\n resourcePath: string,\n): { success: true; resolvedPath: string } | { success: false; error: string } {\n if (isAbsolute(resourcePath)) {\n return { success: false, error: 'Absolute resource paths are not allowed' };\n }\n\n const segments = resourcePath.split(/[/\\\\]/);\n if (segments.some((seg) => seg === '..')) {\n return { success: false, error: 'Path traversal is not allowed — resource paths must stay within the skill directory' };\n }\n\n const resolvedPath = resolve(skillPath, resourcePath);\n const resolvedSkillPath = resolve(skillPath);\n const rel = relative(resolvedSkillPath, resolvedPath);\n if (rel.startsWith('..') || resolve(resolvedSkillPath, rel) !== resolvedPath) {\n return { success: false, error: 'Path traversal is not allowed — resource paths must stay within the skill directory' };\n }\n\n try {\n const realSkillRoot = realpathSync(resolvedSkillPath);\n const realTarget = realpathSync(resolvedPath);\n const realRel = relative(realSkillRoot, realTarget);\n if (realRel.startsWith('..') || isAbsolute(realRel)) {\n return { success: false, error: 'Symlink target escapes the skill directory — access denied' };\n }\n } catch {\n // File doesn't exist yet (or can't be stat'd) — skip symlink check.\n // The caller will produce a clear error if the file is missing.\n }\n\n return { success: true, resolvedPath };\n}\n","/**\n * Agent Skill Access Tools\n *\n * Provides `activate-skill` and `read-skill-resource` tools built with\n * the AgentForge tool builder API. Skill activation makes trusted Agent\n * Skill instructions available; resource access loads supporting files.\n *\n * @see https://agentskills.io/specification\n *\n * @example\n * ```ts\n * const [activateSkill, readSkillResource] = createSkillActivationTools(registry);\n * // activateSkill — load full SKILL.md body\n * // readSkillResource — load a resource file from a skill\n *\n * // Or use the convenience method:\n * const [activateSkill, readSkillResource] = registry.toActivationTools();\n * ```\n */\n\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { createActivateSkillTool } from './activation-activate-tool.js';\nimport { createReadSkillResourceTool } from './activation-resource-tool.js';\nimport type { activateSkillSchema, readSkillResourceSchema } from './activation-schemas.js';\n\nexport { createActivateSkillTool } from './activation-activate-tool.js';\nexport { resolveResourcePath } from './activation-path.js';\nexport { createReadSkillResourceTool } from './activation-resource-tool.js';\n\n/**\n * Create both skill activation tools bound to a registry instance.\n *\n * @param registry - The SkillRegistry to bind tools to\n * @returns Array of both tools [activate-skill, read-skill-resource]\n */\nexport function createSkillActivationTools(\n registry: SkillRegistry,\n): [Tool<z.infer<typeof activateSkillSchema>, string>, Tool<z.infer<typeof readSkillResourceSchema>, string>] {\n return [\n createActivateSkillTool(registry),\n createReadSkillResourceTool(registry),\n ];\n}\n","import { resolve as resolvePath } from 'node:path';\nimport { createLogger, LogLevel } from '@agentforge/core';\nimport { parseSkillContent } from './parser.js';\nimport { scanAllSkillRoots, expandHome } from './scanner.js';\nimport { normalizeRootConfig } from './trust.js';\nimport type { Skill, SkillRegistryConfig, TrustLevel } from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport type { RegistryEmit, ScanError } from './registry-internal.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function discoverSkills(\n config: Pick<SkillRegistryConfig, 'skillRoots'>,\n skills: Map<string, Skill>,\n rootTrustMap: Map<string, TrustLevel>,\n emit: RegistryEmit,\n): ScanError[] {\n skills.clear();\n rootTrustMap.clear();\n const scanErrors: ScanError[] = [];\n\n const normalizedRoots = config.skillRoots.map(normalizeRootConfig);\n const plainPaths = normalizedRoots.map((root) => root.path);\n\n for (const root of normalizedRoots) {\n const resolvedPath = resolvePath(expandHome(root.path));\n rootTrustMap.set(resolvedPath, root.trust);\n }\n\n const candidates = scanAllSkillRoots(plainPaths);\n\n let successCount = 0;\n let warningCount = 0;\n\n for (const candidate of candidates) {\n const result = parseSkillContent(candidate.content, candidate.dirName);\n\n if (!result.success) {\n warningCount++;\n recordScanError(scanErrors, candidate.skillPath, result.error || 'Unknown parse error');\n emit(SkillRegistryEvent.SKILL_WARNING, {\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n error: result.error,\n });\n logger.warn('Skipping invalid skill', {\n skillPath: candidate.skillPath,\n ...(result.error ? { error: result.error } : {}),\n });\n continue;\n }\n\n const skill: Skill = {\n metadata: result.metadata!,\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n trustLevel: rootTrustMap.get(candidate.rootPath) ?? 'untrusted',\n };\n\n if (skills.has(skill.metadata.name)) {\n warningCount++;\n const existing = skills.get(skill.metadata.name)!;\n const warningMessage =\n `Duplicate skill name \"${skill.metadata.name}\" from \"${candidate.rootPath}\" — ` +\n `keeping version from \"${existing.rootPath}\" (first root takes precedence)`;\n\n recordScanError(scanErrors, candidate.skillPath, warningMessage);\n emit(SkillRegistryEvent.SKILL_WARNING, {\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n duplicateOf: existing.skillPath,\n error: warningMessage,\n });\n logger.warn('Duplicate skill name, keeping first', {\n name: skill.metadata.name,\n kept: existing.skillPath,\n skipped: candidate.skillPath,\n });\n continue;\n }\n\n skills.set(skill.metadata.name, skill);\n successCount++;\n emit(SkillRegistryEvent.SKILL_DISCOVERED, skill);\n logger.debug('Skill discovered', {\n name: skill.metadata.name,\n description: skill.metadata.description.slice(0, 80),\n skillPath: skill.skillPath,\n });\n }\n\n logger.info('Skill registry populated', {\n rootsScanned: config.skillRoots.length,\n skillsDiscovered: successCount,\n warnings: warningCount,\n });\n\n return scanErrors;\n}\n\nfunction recordScanError(scanErrors: ScanError[], path: string, error: string): void {\n scanErrors.push({ path, error });\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\nimport type { SkillEventHandler } from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport type { RegistryEventHandlers } from './registry-internal.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function addRegistryEventHandler(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n handler: SkillEventHandler,\n): void {\n if (!eventHandlers.has(event)) {\n eventHandlers.set(event, new Set());\n }\n\n eventHandlers.get(event)!.add(handler);\n}\n\nexport function removeRegistryEventHandler(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n handler: SkillEventHandler,\n): void {\n const handlers = eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n }\n}\n\nexport function emitRegistryEvent(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n data: unknown,\n): void {\n const handlers = eventHandlers.get(event);\n if (!handlers) {\n return;\n }\n\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n logger.error('Skill event handler error', {\n event,\n error: error instanceof Error ? error.message : String(error),\n ...(error instanceof Error && error.stack ? { stack: error.stack } : {}),\n });\n }\n });\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\nimport type { Skill, SkillPromptOptions, SkillRegistryConfig } from './types.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function generateSkillPrompt(\n config: SkillRegistryConfig,\n allSkills: Skill[],\n totalDiscovered: number,\n options?: SkillPromptOptions,\n): string {\n if (!config.enabled) {\n logger.debug('Skill prompt generation skipped (disabled)', {\n enabled: config.enabled ?? false,\n });\n return '';\n }\n\n let skills = allSkills;\n\n if (options?.skills && options.skills.length > 0) {\n const requested = new Set(options.skills);\n skills = skills.filter((skill) => requested.has(skill.metadata.name));\n }\n\n let trustedSkills = skills.filter(\n (skill) => skill.trustLevel === 'workspace' || skill.trustLevel === 'trusted',\n );\n let untrustedSkills = skills.filter(\n (skill) => skill.trustLevel !== 'workspace' && skill.trustLevel !== 'trusted',\n );\n\n if (config.maxDiscoveredSkills !== undefined && config.maxDiscoveredSkills >= 0) {\n const trustedLimit = Math.min(config.maxDiscoveredSkills, trustedSkills.length);\n trustedSkills = trustedSkills.slice(0, trustedLimit);\n untrustedSkills = untrustedSkills.slice(0, config.maxDiscoveredSkills - trustedLimit);\n skills = [...trustedSkills, ...untrustedSkills];\n }\n\n if (trustedSkills.length === 0 && untrustedSkills.length === 0) {\n logger.debug('Skill prompt generation produced empty result', {\n totalDiscovered,\n filterApplied: !!(options?.skills && options.skills.length > 0),\n ...(config.maxDiscoveredSkills !== undefined\n ? { maxCap: config.maxDiscoveredSkills }\n : {}),\n });\n return '';\n }\n\n const sections: string[] = [];\n\n if (trustedSkills.length > 0) {\n sections.push(`<available_skills>\\n${trustedSkills.map(renderTrustedSkillEntry).join('\\n')}\\n</available_skills>`);\n }\n\n if (untrustedSkills.length > 0) {\n sections.push(renderUntrustedSkillsSection(untrustedSkills));\n }\n\n const xml = sections.join('\\n');\n const estimatedTokens = Math.ceil(xml.length / 4);\n\n logger.info('Skill prompt generated', {\n skillCount: skills.length,\n trustedSkillCount: trustedSkills.length,\n untrustedSkillCount: untrustedSkills.length,\n totalDiscovered,\n filterApplied: !!(options?.skills && options.skills.length > 0),\n ...(config.maxDiscoveredSkills !== undefined ? { maxCap: config.maxDiscoveredSkills } : {}),\n estimatedTokens,\n xmlLength: xml.length,\n });\n\n return xml;\n}\n\nfunction renderTrustedSkillEntry(skill: Skill): string {\n return [\n ' <skill>',\n ` <name>${escapeXml(skill.metadata.name)}</name>`,\n ` <description>${escapeXml(skill.metadata.description)}</description>`,\n ` <location>${escapeXml(skill.skillPath)}</location>`,\n ` <trust>${escapeXml(skill.trustLevel)}</trust>`,\n ' </skill>',\n ].join('\\n');\n}\n\nfunction renderUntrustedSkillsSection(skills: Skill[]): string {\n return [\n '<untrusted_skills>',\n ' <trust_notice>Untrusted skills are discoverable, but their full SKILL.md bodies stay blocked until the root is promoted to trusted or workspace status.</trust_notice>',\n ...skills.map(renderUntrustedSkillEntry),\n '</untrusted_skills>',\n ].join('\\n');\n}\n\nfunction renderUntrustedSkillEntry(skill: Skill): string {\n return [\n ' <skill>',\n ` <name>${escapeXml(skill.metadata.name)}</name>`,\n ` <description>${escapeXml(skill.metadata.description)}</description>`,\n ` <location>${escapeXml(skill.skillPath)}</location>`,\n ` <trust>${escapeXml(skill.trustLevel)}</trust>`,\n ' <activation_policy>requires-trusted-root</activation_policy>',\n ' </skill>',\n ].join('\\n');\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n","import type {\n Skill,\n SkillEventHandler,\n SkillPromptOptions,\n SkillRegistryConfig,\n TrustLevel,\n} from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport { createSkillActivationTools } from './activation.js';\nimport { discoverSkills } from './registry-discovery.js';\nimport {\n addRegistryEventHandler,\n emitRegistryEvent,\n removeRegistryEventHandler,\n} from './registry-events.js';\nimport type { RegistryEventHandlers } from './registry-internal.js';\nimport { generateSkillPrompt } from './registry-prompt.js';\n\nexport class SkillRegistry {\n private skills: Map<string, Skill> = new Map();\n private eventHandlers: RegistryEventHandlers = new Map();\n private readonly config: SkillRegistryConfig;\n private scanErrors: Array<{ path: string; error: string }> = [];\n private rootTrustMap: Map<string, TrustLevel> = new Map();\n\n constructor(config: SkillRegistryConfig) {\n this.config = config;\n this.discover();\n }\n\n discover(): void {\n this.scanErrors = discoverSkills(this.config, this.skills, this.rootTrustMap, (event, data) => {\n this.emit(event, data);\n });\n }\n\n get(name: string): Skill | undefined {\n return this.skills.get(name);\n }\n\n getAll(): Skill[] {\n return Array.from(this.skills.values());\n }\n\n has(name: string): boolean {\n return this.skills.has(name);\n }\n\n size(): number {\n return this.skills.size;\n }\n\n getNames(): string[] {\n return Array.from(this.skills.keys());\n }\n\n getScanErrors(): ReadonlyArray<{ path: string; error: string }> {\n return this.scanErrors;\n }\n\n getAllowUntrustedScripts(): boolean {\n return this.config.allowUntrustedScripts ?? false;\n }\n\n getAllowedTools(name: string): string[] | undefined {\n return this.skills.get(name)?.metadata.allowedTools;\n }\n\n generatePrompt(options?: SkillPromptOptions): string {\n return generateSkillPrompt(this.config, this.getAll(), this.size(), options);\n }\n\n on(event: SkillRegistryEvent, handler: SkillEventHandler): void {\n addRegistryEventHandler(this.eventHandlers, event, handler);\n }\n\n off(event: SkillRegistryEvent, handler: SkillEventHandler): void {\n removeRegistryEventHandler(this.eventHandlers, event, handler);\n }\n\n emitEvent(event: SkillRegistryEvent, data: unknown): void {\n this.emit(event, data);\n }\n\n toActivationTools(): ReturnType<typeof createSkillActivationTools> {\n return createSkillActivationTools(this);\n }\n\n private emit(event: SkillRegistryEvent, data: unknown): void {\n emitRegistryEvent(this.eventHandlers, event, data);\n }\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -844,29 +844,6 @@ function escapeXml(str) {
|
|
|
844
844
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
845
845
|
}
|
|
846
846
|
|
|
847
|
-
// src/registry-query-api.ts
|
|
848
|
-
function getSkill(skills, name) {
|
|
849
|
-
return skills.get(name);
|
|
850
|
-
}
|
|
851
|
-
function getAllSkills(skills) {
|
|
852
|
-
return Array.from(skills.values());
|
|
853
|
-
}
|
|
854
|
-
function hasSkill(skills, name) {
|
|
855
|
-
return skills.has(name);
|
|
856
|
-
}
|
|
857
|
-
function getSkillCount(skills) {
|
|
858
|
-
return skills.size;
|
|
859
|
-
}
|
|
860
|
-
function getSkillNames(skills) {
|
|
861
|
-
return Array.from(skills.keys());
|
|
862
|
-
}
|
|
863
|
-
function getScanErrors(scanErrors) {
|
|
864
|
-
return scanErrors;
|
|
865
|
-
}
|
|
866
|
-
function getAllowedTools(skills, name) {
|
|
867
|
-
return skills.get(name)?.metadata.allowedTools;
|
|
868
|
-
}
|
|
869
|
-
|
|
870
847
|
// src/registry.ts
|
|
871
848
|
var SkillRegistry = class {
|
|
872
849
|
skills = /* @__PURE__ */ new Map();
|
|
@@ -884,28 +861,28 @@ var SkillRegistry = class {
|
|
|
884
861
|
});
|
|
885
862
|
}
|
|
886
863
|
get(name) {
|
|
887
|
-
return
|
|
864
|
+
return this.skills.get(name);
|
|
888
865
|
}
|
|
889
866
|
getAll() {
|
|
890
|
-
return
|
|
867
|
+
return Array.from(this.skills.values());
|
|
891
868
|
}
|
|
892
869
|
has(name) {
|
|
893
|
-
return
|
|
870
|
+
return this.skills.has(name);
|
|
894
871
|
}
|
|
895
872
|
size() {
|
|
896
|
-
return
|
|
873
|
+
return this.skills.size;
|
|
897
874
|
}
|
|
898
875
|
getNames() {
|
|
899
|
-
return
|
|
876
|
+
return Array.from(this.skills.keys());
|
|
900
877
|
}
|
|
901
878
|
getScanErrors() {
|
|
902
|
-
return
|
|
879
|
+
return this.scanErrors;
|
|
903
880
|
}
|
|
904
881
|
getAllowUntrustedScripts() {
|
|
905
882
|
return this.config.allowUntrustedScripts ?? false;
|
|
906
883
|
}
|
|
907
884
|
getAllowedTools(name) {
|
|
908
|
-
return
|
|
885
|
+
return this.skills.get(name)?.metadata.allowedTools;
|
|
909
886
|
}
|
|
910
887
|
generatePrompt(options) {
|
|
911
888
|
return generateSkillPrompt(this.config, this.getAll(), this.size(), options);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/parser.ts","../src/scanner.ts","../src/activation-content.ts","../src/activation-shared.ts","../src/trust.ts","../src/agent-skill-access.ts","../src/activation-schemas.ts","../src/activation-activate-tool.ts","../src/activation-resource-tool.ts","../src/activation-path.ts","../src/activation.ts","../src/registry-discovery.ts","../src/registry-events.ts","../src/registry-prompt.ts","../src/registry-query-api.ts","../src/registry.ts"],"names":["TrustPolicyReason","SkillRegistryEvent","matter","createLogger","LogLevel","resolve","readFileSync","ToolBuilder","ToolCategory","isAbsolute","relative","realpathSync","logger","resolvePath"],"mappings":";;;;;;;;AAsDO,IAAK,iBAAA,qBAAAA,kBAAAA,KAAL;AAEL,EAAAA,mBAAA,YAAA,CAAA,GAAa,YAAA;AAEb,EAAAA,mBAAA,iBAAA,CAAA,GAAkB,iBAAA;AAElB,EAAAA,mBAAA,cAAA,CAAA,GAAe,cAAA;AAEf,EAAAA,mBAAA,4BAAA,CAAA,GAA6B,4BAAA;AAE7B,EAAAA,mBAAA,0BAAA,CAAA,GAA2B,0BAAA;AAE3B,EAAAA,mBAAA,mCAAA,CAAA,GAAoC,mCAAA;AAEpC,EAAAA,mBAAA,yBAAA,CAAA,GAA0B,yBAAA;AAE1B,EAAAA,mBAAA,0BAAA,CAAA,GAA2B,mCAAA;AAE3B,EAAAA,mBAAA,qBAAA,CAAA,GAAsB,qBAAA;AAlBZ,EAAA,OAAAA,kBAAAA;AAAA,CAAA,EAAA,iBAAA,IAAA,EAAA;AA8IL,IAAK,kBAAA,qBAAAC,mBAAAA,KAAL;AAEL,EAAAA,oBAAA,kBAAA,CAAA,GAAmB,kBAAA;AAEnB,EAAAA,oBAAA,eAAA,CAAA,GAAgB,eAAA;AAEhB,EAAAA,oBAAA,iBAAA,CAAA,GAAkB,iBAAA;AAElB,EAAAA,oBAAA,uBAAA,CAAA,GAAwB,uBAAA;AAExB,EAAAA,oBAAA,qBAAA,CAAA,GAAsB,qBAAA;AAEtB,EAAAA,oBAAA,sBAAA,CAAA,GAAuB,sBAAA;AAZb,EAAA,OAAAA,mBAAAA;AAAA,CAAA,EAAA,kBAAA,IAAA,EAAA;ACjLZ,IAAM,kBAAA,GAAqB,mCAAA;AAC3B,IAAM,qBAAA,GAAwB,EAAA;AAC9B,IAAM,4BAAA,GAA+B,IAAA;AAQ9B,SAAS,kBAAkB,IAAA,EAAuC;AACvE,EAAA,MAAM,SAAiC,EAAC;AAExC,EAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,IAAA,EAAM;AACvC,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,oBAAoB,CAAA;AAC1D,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,yBAAyB,CAAA;AAC/D,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,0BAA0B,CAAA;AAChE,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,qBAAA,EAAuB;AACvC,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,MAAA;AAAA,MACP,OAAA,EAAS,CAAA,qBAAA,EAAwB,qBAAqB,CAAA,iBAAA,EAAoB,KAAK,MAAM,CAAA,CAAA;AAAA,KACtF,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAA,EAAG;AAClC,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,MAAA;AAAA,MACP,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG;AACvB,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,MAAA;AAAA,MACP,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,MAAA;AACT;AAQO,SAAS,yBAAyB,WAAA,EAA8C;AACrF,EAAA,MAAM,SAAiC,EAAC;AAExC,EAAA,IAAI,WAAA,KAAgB,MAAA,IAAa,WAAA,KAAgB,IAAA,EAAM;AACrD,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,aAAA,EAAe,OAAA,EAAS,2BAA2B,CAAA;AACxE,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,gBAAgB,QAAA,EAAU;AACnC,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,aAAA,EAAe,OAAA,EAAS,gCAAgC,CAAA;AAC7E,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAA,CAAY,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA,EAAG;AACnC,IAAA,MAAA,CAAO,KAAK,EAAE,KAAA,EAAO,aAAA,EAAe,OAAA,EAAS,iCAAiC,CAAA;AAC9E,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAA,CAAY,SAAS,4BAAA,EAA8B;AACrD,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,aAAA;AAAA,MACP,OAAA,EAAS,CAAA,4BAAA,EAA+B,4BAA4B,CAAA,iBAAA,EAAoB,YAAY,MAAM,CAAA,CAAA;AAAA,KAC3G,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,MAAA;AACT;AASO,SAAS,2BAAA,CAA4B,MAAc,OAAA,EAAyC;AACjG,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,OAAO,CAAC;AAAA,MACN,KAAA,EAAO,MAAA;AAAA,MACP,OAAA,EAAS,CAAA,MAAA,EAAS,IAAI,CAAA,oCAAA,EAAuC,OAAO,CAAA,CAAA;AAAA,KACrE,CAAA;AAAA,EACH;AACA,EAAA,OAAO,EAAC;AACV;AAYO,SAAS,iBAAA,CAAkB,SAAiB,OAAA,EAAmC;AACpF,EAAA,IAAI,MAAA;AAEJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,OAAO,OAAO,CAAA;AAAA,EACzB,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,gCAAgC,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,KACzF;AAAA,EACF;AAEA,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AAGpB,EAAA,MAAM,MAAA,GAAiC;AAAA,IACrC,GAAG,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA;AAAA,IAC9B,GAAG,wBAAA,CAAyB,IAAA,CAAK,WAAW;AAAA,GAC9C;AAGA,EAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,IAAY,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAA,IAAK,kBAAA,CAAmB,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,EAAG;AAC/F,IAAA,MAAA,CAAO,KAAK,GAAG,2BAAA,CAA4B,IAAA,CAAK,IAAA,EAAM,OAAO,CAAC,CAAA;AAAA,EAChE;AAEA,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,MAAA,CAAO,GAAA,CAAI,CAAC,MAAM,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI;AAAA,KAChE;AAAA,EACF;AAGA,EAAA,MAAM,QAAA,GAA0B;AAAA,IAC9B,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,aAAa,IAAA,CAAK;AAAA,GACpB;AAGA,EAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAW;AAC9B,IAAA,QAAA,CAAS,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,EACxC;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,aAAa,CAAA,EAAG;AACrC,IAAA,QAAA,CAAS,aAAA,GAAgB,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,MAAM,CAAA;AAAA,EACxD;AAEA,EAAA,IAAI,IAAA,CAAK,aAAa,MAAA,IAAa,OAAO,KAAK,QAAA,KAAa,QAAA,IAAY,IAAA,CAAK,QAAA,KAAa,IAAA,EAAM;AAC9F,IAAA,QAAA,CAAS,WAAW,IAAA,CAAK,QAAA;AAAA,EAC3B;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,eAAe,CAAC,CAAA,EAAG;AACxC,IAAA,QAAA,CAAS,YAAA,GAAe,IAAA,CAAK,eAAe,CAAA,CAAE,IAAI,MAAM,CAAA;AAAA,EAC1D;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,IAAA;AAAA,IACT,QAAA;AAAA,IACA,MAAM,MAAA,CAAO;AAAA,GACf;AACF;ACrLA,IAAM,SAAS,YAAA,CAAa,2BAAA,EAA6B,EAAE,KAAA,EAAO,QAAA,CAAS,MAAM,CAAA;AAmB1E,SAAS,WAAW,CAAA,EAAmB;AAC5C,EAAA,IAAI,CAAA,CAAE,UAAA,CAAW,IAAI,CAAA,IAAK,MAAM,GAAA,EAAK;AACnC,IAAA,OAAO,QAAQ,OAAA,EAAQ,EAAG,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,CAAA;AACT;AAQO,SAAS,cAAc,QAAA,EAAoC;AAChE,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,UAAA,CAAW,QAAQ,CAAC,CAAA;AACjD,EAAA,MAAM,aAA+B,EAAC;AAEtC,EAAA,IAAI,CAAC,UAAA,CAAW,YAAY,CAAA,EAAG;AAC7B,IAAA,MAAA,CAAO,KAAA,CAAM,qCAAA,EAAuC,EAAE,QAAA,EAAU,cAAc,CAAA;AAC9E,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,YAAY,YAAY,CAAA;AAAA,EACpC,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,CAAO,KAAK,qCAAA,EAAuC;AAAA,MACjD,QAAA,EAAU,YAAA;AAAA,MACV,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,KACvD,CAAA;AACD,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,YAAA,EAAc,KAAK,CAAA;AAG7C,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,IAAA,GAAO,SAAS,SAAS,CAAA;AAAA,IAC3B,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,IAAA,CAAK,WAAA,EAAY,EAAG;AACvB,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,SAAA,EAAW,UAAU,CAAA;AACjD,IAAA,IAAI,CAAC,UAAA,CAAW,WAAW,CAAA,EAAG;AAC5B,MAAA;AAAA,IACF;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,YAAA,CAAa,WAAA,EAAa,OAAO,CAAA;AACjD,MAAA,UAAA,CAAW,IAAA,CAAK;AAAA,QACd,SAAA,EAAW,SAAA;AAAA,QACX,OAAA,EAAS,SAAS,SAAS,CAAA;AAAA,QAC3B,OAAA;AAAA,QACA,QAAA,EAAU;AAAA,OACX,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,MAAA,CAAO,KAAK,yBAAA,EAA2B;AAAA,QACrC,IAAA,EAAM,WAAA;AAAA,QACN,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,OACvD,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,MAAA,CAAO,MAAM,oBAAA,EAAsB;AAAA,IACjC,QAAA,EAAU,YAAA;AAAA,IACV,iBAAiB,UAAA,CAAW;AAAA,GAC7B,CAAA;AAED,EAAA,OAAO,UAAA;AACT;AAQO,SAAS,kBAAkB,UAAA,EAAwC;AACxE,EAAA,MAAM,gBAAkC,EAAC;AAEzC,EAAA,KAAA,MAAW,QAAQ,UAAA,EAAY;AAC7B,IAAA,MAAM,UAAA,GAAa,cAAc,IAAI,CAAA;AACrC,IAAA,aAAA,CAAc,IAAA,CAAK,GAAG,UAAU,CAAA;AAAA,EAClC;AAEA,EAAA,MAAA,CAAO,KAAK,0BAAA,EAA4B;AAAA,IACtC,cAAc,UAAA,CAAW,MAAA;AAAA,IACzB,iBAAiB,aAAA,CAAc;AAAA,GAChC,CAAA;AAED,EAAA,OAAO,aAAA;AACT;ACtHO,SAAS,YAAY,OAAA,EAAyB;AACnD,EAAA,OAAOC,MAAAA,CAAO,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAK;AACtC;ACXO,IAAM,gBAAA,GAAmBC,aAAa,8BAAA,EAAgC;AAAA,EAC3E,OAAOC,QAAAA,CAAS;AAClB,CAAC,CAAA;AAEM,SAAS,yBAAA,CAA0B,MAAc,cAAA,EAAkC;AACxF,EAAA,MAAM,UAAA,GAAa,eAAe,MAAA,GAAS,CAAA,GACvC,sBAAsB,cAAA,CAAe,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GAC/C,sCAAA;AAEJ,EAAA,OAAO,CAAA,OAAA,EAAU,IAAI,CAAA,YAAA,EAAe,UAAU,CAAA,CAAA;AAChD;;;ACaA,IAAM,kBAAA,GAAqB,UAAA;AAC3B,IAAM,iBAAA,GAAoB,SAAA;AAYnB,SAAS,oBAAoB,IAAA,EAAiD;AACnF,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,WAAA,EAAY;AAAA,EAC1C;AACA,EAAA,OAAO,IAAA;AACT;AAYO,SAAS,iBAAiB,YAAA,EAA+B;AAE9D,EAAA,IAAI,aAAa,YAAA,CAAa,IAAA,EAAK,CAAE,OAAA,CAAQ,OAAO,GAAG,CAAA;AAGvD,EAAA,UAAA,GAAa,UAAA,CAAW,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA;AAG3C,EAAA,OAAO,UAAA,CAAW,UAAA,CAAW,IAAI,CAAA,EAAG;AAClC,IAAA,UAAA,GAAa,UAAA,CAAW,MAAM,CAAC,CAAA;AAAA,EACjC;AAGA,EAAA,MAAM,KAAA,GAAQ,WAAW,WAAA,EAAY;AAErC,EAAA,OAAO,KAAA,KAAU,iBAAA,IACZ,KAAA,CAAM,UAAA,CAAW,kBAAkB,CAAA;AAC1C;AAiBO,SAAS,mBAAA,CACd,YAAA,EACA,UAAA,EACA,qBAAA,GAAiC,KAAA,EACZ;AAErB,EAAA,IAAI,CAAC,gBAAA,CAAiB,YAAY,CAAA,EAAG;AACnC,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,MAAA,EAAA,YAAA;AAAA,MACA,OAAA,EAAS;AAAA,KACX;AAAA,EACF;AAGA,EAAA,QAAQ,UAAA;AAAY,IAClB,KAAK,WAAA;AACH,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA,EAAA,iBAAA;AAAA,QACA,OAAA,EAAS;AAAA,OACX;AAAA,IAEF,KAAK,SAAA;AACH,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA,EAAA,cAAA;AAAA,QACA,OAAA,EAAS;AAAA,OACX;AAAA,IAEF,KAAK,WAAA;AACH,MAAA,IAAI,qBAAA,EAAuB;AACzB,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,MAAA,EAAA,mCAAA;AAAA,UACA,OAAA,EAAS;AAAA,SACX;AAAA,MACF;AACA,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,MAAA,EAAA,yBAAA;AAAA,QACA,OAAA,EAAS,CAAA,4PAAA;AAAA,OAIX;AAAA,IAEF;AACE,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,MAAA,EAAA,qBAAA;AAAA,QACA,OAAA,EAAS,4CAAuC,UAAU,CAAA,sDAAA;AAAA,OAC5D;AAAA;AAEN;AASO,SAAS,8BAA8B,UAAA,EAA6C;AACzF,EAAA,QAAQ,UAAA;AAAY,IAClB,KAAK,WAAA;AACH,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA,EAAA,4BAAA;AAAA,QACA,OAAA,EAAS;AAAA,OACX;AAAA,IAEF,KAAK,SAAA;AACH,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA,EAAA,0BAAA;AAAA,QACA,OAAA,EAAS;AAAA,OACX;AAAA,IAEF,KAAK,WAAA;AACH,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,MAAA,EAAA,mCAAA;AAAA,QACA,OAAA,EAAS,CAAA,sPAAA;AAAA,OAGX;AAAA,IAEF;AACE,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,MAAA,EAAA,qBAAA;AAAA,QACA,OAAA,EAAS,gDAA2C,UAAU,CAAA,sDAAA;AAAA,OAChE;AAAA;AAEN;;;AChLA,IAAM,sBAAA,GACJ,0FAAA;AACF,IAAM,sBAAA,GAAyB,iEAAA;AAc/B,SAAS,YAAY,KAAA,EAAwB;AAC3C,EAAA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC9D;AAEA,SAAS,uBAAA,CAAwB,OAAgB,YAAA,EAA8B;AAC7E,EAAA,MAAM,OAAA,GAAU,YAAY,KAAK,CAAA;AACjC,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AACxC,EAAA,MAAM,SAAS,WAAA,KAAgB,EAAA,GAAK,UAAU,OAAA,CAAQ,KAAA,CAAM,GAAG,WAAW,CAAA;AAC1E,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,QAAA,EAAW,YAAY,CAAA,CAAA,CAAA;AACzC;AAEA,SAAS,4BAAA,CACP,WACA,YAAA,EAC6B;AAC7B,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,OAAO,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,yCAAA,EAA0C;AAAA,EACrF;AAEA,EAAA,IAAI,YAAA,CAAa,MAAM,OAAO,CAAA,CAAE,KAAK,CAAC,OAAA,KAAY,OAAA,KAAY,IAAI,CAAA,EAAG;AACnE,IAAA,OAAO,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,sBAAA,EAAuB;AAAA,EAClE;AAEA,EAAA,MAAM,iBAAA,GAAoBC,QAAQ,SAAS,CAAA;AAC3C,EAAA,MAAM,YAAA,GAAeA,OAAAA,CAAQ,iBAAA,EAAmB,YAAY,CAAA;AAC5D,EAAA,MAAM,mBAAA,GAAsB,QAAA,CAAS,iBAAA,EAAmB,YAAY,CAAA;AACpE,EAAA,IACE,mBAAA,CAAoB,UAAA,CAAW,IAAI,CAAA,IACnC,UAAA,CAAW,mBAAmB,CAAA,IAC9BA,OAAAA,CAAQ,iBAAA,EAAmB,mBAAmB,CAAA,KAAM,YAAA,EACpD;AACA,IAAA,OAAO,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,sBAAA,EAAuB;AAAA,EAClE;AAEA,EAAA,IAAI,kBAAA;AACJ,EAAA,IAAI;AACF,IAAA,kBAAA,GAAqB,aAAa,iBAAiB,CAAA;AAAA,EACrD,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,EAAE,IAAA,EAAM,cAAA,EAAgB,OAAO,uBAAA,CAAwB,KAAA,EAAO,YAAY,CAAA,EAAE;AAAA,EACrF;AAEA,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI;AACF,IAAA,aAAA,GAAgB,aAAa,YAAY,CAAA;AAAA,EAC3C,SAAS,KAAA,EAAO;AACd,IAAA,IAAK,KAAA,CAAgC,SAAS,QAAA,EAAU;AACtD,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,oBAAA;AAAA,QACN,YAAA;AAAA,QACA,KAAA,EAAO,uBAAA,CAAwB,KAAA,EAAO,YAAY;AAAA,OACpD;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,qBAAA;AAAA,MACN,YAAA;AAAA,MACA,KAAA,EAAO,uBAAA,CAAwB,KAAA,EAAO,YAAY;AAAA,KACpD;AAAA,EACF;AAEA,EAAA,MAAM,qBAAA,GAAwB,QAAA,CAAS,kBAAA,EAAoB,aAAa,CAAA;AACxE,EAAA,IAAI,sBAAsB,UAAA,CAAW,IAAI,CAAA,IAAK,UAAA,CAAW,qBAAqB,CAAA,EAAG;AAC/E,IAAA,OAAO,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,sBAAA,EAAuB;AAAA,EAClE;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,YAAA,EAAc,eAAe,qBAAA,EAAsB;AAC/E;AAgBO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,QAAA,EAAyB;AAAzB,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAAA,EAA0B;AAAA,EAEvD,MAAM,YAAA,CAAa,IAAA,EAAc,YAAA,EAAoD;AACnF,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AACpC,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,QAAA,CAAS,QAAA,EAAS;AAC9C,MAAA,gBAAA,CAAiB,KAAK,mDAAA,EAAgD;AAAA,QACpE,IAAA;AAAA,QACA;AAAA,OACD,CAAA;AACD,MAAA,OAAO,EAAE,IAAA,EAAM,iBAAA,EAAmB,IAAA,EAAM,cAAA,EAAe;AAAA,IACzD;AAEA,IAAA,MAAM,UAAA,GAAa,4BAAA,CAA6B,KAAA,CAAM,SAAA,EAAW,YAAY,CAAA;AAC7E,IAAA,IAAI,UAAA,CAAW,SAAS,eAAA,EAAiB;AACvC,MAAA,gBAAA,CAAiB,KAAK,mDAAA,EAAgD;AAAA,QACpE,IAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAO,UAAA,CAAW;AAAA,OACnB,CAAA;AACD,MAAA,OAAO,UAAA;AAAA,IACT;AACA,IAAA,IAAI,UAAA,CAAW,SAAS,cAAA,EAAgB;AACtC,MAAA,gBAAA,CAAiB,KAAK,gEAAA,EAA6D;AAAA,QACjF,IAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAO,UAAA,CAAW;AAAA,OACnB,CAAA;AACD,MAAA,OAAO,EAAE,GAAG,UAAA,EAAY,IAAA,EAAM,YAAA,EAAa;AAAA,IAC7C;AAEA,IAAA,MAAM,qBAAA,GAAwBA,OAAAA,CAAQ,KAAA,CAAM,SAAA,EAAW,UAAU,CAAA;AACjE,IAAA,IAAI,sBACF,UAAA,CAAW,YAAA,CAAa,WAAA,EAAY,KAAM,sBAAsB,WAAA,EAAY;AAC9E,IAAA,IAAI,CAAC,mBAAA,IAAuB,UAAA,CAAW,IAAA,KAAS,SAAA,EAAW;AACzD,MAAA,IAAI;AACF,QAAA,mBAAA,GACE,WAAW,aAAA,CAAc,WAAA,OACzB,YAAA,CAAa,qBAAqB,EAAE,WAAA,EAAY;AAAA,MACpD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA,IAAI,mBAAA,EAAqB;AACvB,MAAA,MAAM,kBAAA,GAAqB,6BAAA,CAA8B,KAAA,CAAM,UAAU,CAAA;AACzE,MAAA,IAAI,CAAC,mBAAmB,OAAA,EAAS;AAC/B,QAAA,gBAAA,CAAiB,KAAK,oEAAA,EAAiE;AAAA,UACrF,IAAA;AAAA,UACA,YAAA;AAAA,UACA,YAAY,KAAA,CAAM,UAAA;AAAA,UAClB,QAAQ,kBAAA,CAAmB,MAAA;AAAA,UAC3B,SAAS,kBAAA,CAAmB;AAAA,SAC7B,CAAA;AAED,QAAA,IAAA,CAAK,SAAS,SAAA,CAAA,qBAAA,4BAAkD;AAAA,UAC9D,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,UACrB,YAAA,EAAc,UAAA;AAAA,UACd,YAAY,KAAA,CAAM,UAAA;AAAA,UAClB,QAAQ,kBAAA,CAAmB,MAAA;AAAA,UAC3B,SAAS,kBAAA,CAAmB;AAAA,SAC7B,CAAA;AAED,QAAA,OAAO;AAAA,UACL,IAAA,EAAM,eAAA;AAAA,UACN,QAAQ,kBAAA,CAAmB,MAAA;AAAA,UAC3B,SAAS,kBAAA,CAAmB;AAAA,SAC9B;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,cAAA,GAAiB,mBAAA;AAAA,MACrB,UAAA,CAAW,IAAA,KAAS,SAAA,GAAY,UAAA,CAAW,qBAAA,GAAwB,YAAA;AAAA,MACnE,KAAA,CAAM,UAAA;AAAA,MACN,IAAA,CAAK,SAAS,wBAAA;AAAyB,KACzC;AACA,IAAA,IAAI,CAAC,eAAe,OAAA,EAAS;AAC3B,MAAA,gBAAA,CAAiB,KAAK,iDAAA,EAA8C;AAAA,QAClE,IAAA;AAAA,QACA,YAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OACzB,CAAA;AAED,MAAA,IAAA,CAAK,SAAS,SAAA,CAAA,qBAAA,4BAAkD;AAAA,QAC9D,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,QACrB,YAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OACzB,CAAA;AAED,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,eAAA;AAAA,QACN,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OAC1B;AAAA,IACF;AAEA,IAAA,IAAI,eAAe,MAAA,KAAA,YAAA,mBAAyC;AAC1D,MAAA,gBAAA,CAAiB,KAAK,4CAAA,EAAyC;AAAA,QAC7D,IAAA;AAAA,QACA,YAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe;AAAA,OACxB,CAAA;AAED,MAAA,IAAA,CAAK,SAAS,SAAA,CAAA,sBAAA,6BAAmD;AAAA,QAC/D,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,QACrB,YAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe;AAAA,OACxB,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,UAAA,CAAW,IAAA,KAAS,oBAAA,IAAwB,UAAA,CAAW,SAAS,qBAAA,EAAuB;AACzF,MAAA,gBAAA,CAAiB,KAAK,gEAAA,EAA6D;AAAA,QACjF,IAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAO,UAAA,CAAW;AAAA,OACnB,CAAA;AACD,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,UAAA,CAAW,IAAA,KAAS,oBAAA,GAAuB,oBAAA,GAAuB,cAAA;AAAA,QACxE,IAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAO,UAAA,CAAW;AAAA,OACpB;AAAA,IACF;AAEA,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAUC,YAAAA,CAAa,UAAA,CAAW,aAAA,EAAe,OAAO,CAAA;AAAA,IAC1D,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,MAAA,gBAAA,CAAiB,KAAK,gEAAA,EAA6D;AAAA,QACjF,IAAA;AAAA,QACA,YAAA;AAAA,QACA,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,IAAK,KAAA,CAAgC,SAAS,QAAA,EAAU;AACtD,QAAA,OAAO,EAAE,IAAA,EAAM,oBAAA,EAAsB,IAAA,EAAM,YAAA,EAAc,OAAO,OAAA,EAAQ;AAAA,MAC1E;AACA,MAAA,OAAO,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAM,YAAA,EAAc,OAAO,OAAA,EAAQ;AAAA,IACpE;AAEA,IAAA,gBAAA,CAAiB,KAAK,uBAAA,EAAyB;AAAA,MAC7C,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,MACrB,YAAA;AAAA,MACA,cAAc,UAAA,CAAW,YAAA;AAAA,MACzB,eAAe,OAAA,CAAQ;AAAA,KACxB,CAAA;AAED,IAAA,IAAA,CAAK,SAAS,SAAA,CAAA,uBAAA,8BAAoD;AAAA,MAChE,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,MACrB,YAAA;AAAA,MACA,cAAc,UAAA,CAAW,YAAA;AAAA,MACzB,eAAe,OAAA,CAAQ;AAAA,KACxB,CAAA;AAED,IAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,OAAA,EAAQ;AAAA,EACpC;AAAA,EAEA,MAAM,SAAS,IAAA,EAA8C;AAC3D,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AACpC,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,QAAA,CAAS,QAAA,EAAS;AAC9C,MAAA,gBAAA,CAAiB,KAAK,0CAAA,EAAuC;AAAA,QAC3D,IAAA;AAAA,QACA,gBAAgB,cAAA,CAAe;AAAA,OAChC,CAAA;AACD,MAAA,OAAO,EAAE,IAAA,EAAM,iBAAA,EAAmB,IAAA,EAAM,cAAA,EAAe;AAAA,IACzD;AAEA,IAAA,MAAM,cAAA,GAAiB,6BAAA,CAA8B,KAAA,CAAM,UAAU,CAAA;AACrE,IAAA,IAAI,CAAC,eAAe,OAAA,EAAS;AAC3B,MAAA,gBAAA,CAAiB,KAAK,8CAAA,EAA2C;AAAA,QAC/D,IAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OACzB,CAAA;AAED,MAAA,IAAA,CAAK,SAAS,SAAA,CAAA,qBAAA,4BAAkD;AAAA,QAC9D,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,QACrB,YAAA,EAAc,UAAA;AAAA,QACd,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OACzB,CAAA;AAED,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,eAAA;AAAA,QACN,QAAQ,cAAA,CAAe,MAAA;AAAA,QACvB,SAAS,cAAA,CAAe;AAAA,OAC1B;AAAA,IACF;AAEA,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,UAAUA,YAAAA,CAAaD,OAAAA,CAAQ,MAAM,SAAA,EAAW,UAAU,GAAG,OAAO,CAAA;AAC1E,MAAA,IAAA,GAAO,YAAY,OAAO,CAAA;AAAA,IAC5B,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,MAAA,gBAAA,CAAiB,MAAM,2CAAA,EAAwC;AAAA,QAC7D,IAAA;AAAA,QACA,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,OAAO,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAM,OAAO,OAAA,EAAQ;AAAA,IACtD;AAEA,IAAA,gBAAA,CAAiB,KAAK,iBAAA,EAAmB;AAAA,MACvC,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,MACrB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,YAAY,IAAA,CAAK,MAAA;AAAA,MACjB,YAAY,KAAA,CAAM,UAAA;AAAA,MAClB,kBAAkB,cAAA,CAAe;AAAA,KAClC,CAAA;AAED,IAAA,IAAA,CAAK,SAAS,SAAA,CAAA,iBAAA,wBAA8C;AAAA,MAC1D,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,MACrB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,YAAY,IAAA,CAAK,MAAA;AAAA,MACjB,YAAY,KAAA,CAAM;AAAA,KACnB,CAAA;AAED,IAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAK;AAAA,EACjC;AACF,CAAA;AC5UO,IAAM,mBAAA,GAAsB,EAAE,MAAA,CAAO;AAAA,EAC1C,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,yDAAyD;AACrF,CAAC,CAAA;AAEM,IAAM,uBAAA,GAA0B,EAAE,MAAA,CAAO;AAAA,EAC9C,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,8CAA8C,CAAA;AAAA,EACxE,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,iHAAiH;AAC7I,CAAC,CAAA;;;ACQM,SAAS,wBACd,QAAA,EACmD;AACnD,EAAA,MAAM,MAAA,GAAS,IAAI,gBAAA,CAAiB,QAAQ,CAAA;AAE5C,EAAA,OAAO,IAAI,WAAA,EAAyD,CACjE,IAAA,CAAK,gBAAgB,CAAA,CACrB,WAAA;AAAA,IACC;AAAA,IAKD,QAAA,CAAS,YAAA,CAAa,MAAM,CAAA,CAC5B,IAAA,CAAK,CAAC,OAAA,EAAS,YAAA,EAAc,cAAc,CAAC,CAAA,CAC5C,OAAO,mBAAmB,CAAA,CAC1B,UAAU,OAAO,EAAE,MAAK,KAAM;AAC7B,IAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA;AAEzC,IAAA,QAAQ,OAAO,IAAA;AAAM,MACnB,KAAK,SAAA;AACH,QAAA,OAAO,MAAA,CAAO,IAAA;AAAA,MAChB,KAAK,iBAAA;AACH,QAAA,OAAO,yBAAA,CAA0B,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,cAAc,CAAA;AAAA,MACrE,KAAK,eAAA;AACH,QAAA,OAAO,MAAA,CAAO,OAAA;AAAA,MAChB,KAAK,cAAA;AACH,QAAA,OAAO,CAAA,sBAAA,EAAyB,MAAA,CAAO,IAAI,CAAA,gBAAA,EAAmB,OAAO,KAAK,CAAA,CAAA;AAAA;AAC9E,EACF,CAAC,EACA,KAAA,EAAM;AACX;AC/BO,SAAS,4BACd,QAAA,EACuD;AACvD,EAAA,MAAM,MAAA,GAAS,IAAI,gBAAA,CAAiB,QAAQ,CAAA;AAE5C,EAAA,OAAO,IAAIE,WAAAA,EAA6D,CACrE,IAAA,CAAK,qBAAqB,CAAA,CAC1B,WAAA;AAAA,IACC;AAAA,GAIF,CACC,SAASC,YAAAA,CAAa,MAAM,EAC5B,IAAA,CAAK,CAAC,SAAS,UAAA,EAAY,cAAc,CAAC,CAAA,CAC1C,MAAA,CAAO,uBAAuB,CAAA,CAC9B,SAAA,CAAU,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,YAAA,EAAa,KAAM;AACjD,IAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,YAAA,CAAa,MAAM,YAAY,CAAA;AAE3D,IAAA,QAAQ,OAAO,IAAA;AAAM,MACnB,KAAK,SAAA;AACH,QAAA,OAAO,MAAA,CAAO,OAAA;AAAA,MAChB,KAAK,iBAAA;AACH,QAAA,OAAO,yBAAA,CAA0B,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,cAAc,CAAA;AAAA,MACrE,KAAK,eAAA;AACH,QAAA,OAAO,MAAA,CAAO,OAAA;AAAA,MAChB,KAAK,oBAAA;AAAA,MACL,KAAK,cAAA;AACH,QAAA,OAAO,CAAA,yBAAA,EAA4B,OAAO,YAAY,CAAA,cAAA,EAAiB,OAAO,IAAI,CAAA,GAAA,EAAM,OAAO,KAAK,CAAA,CAAA;AAAA;AACxG,EACF,CAAC,EACA,KAAA,EAAM;AACX;ACpCO,SAAS,mBAAA,CACd,WACA,YAAA,EAC6E;AAC7E,EAAA,IAAIC,UAAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,yCAAA,EAA0C;AAAA,EAC5E;AAEA,EAAA,MAAM,QAAA,GAAW,YAAA,CAAa,KAAA,CAAM,OAAO,CAAA;AAC3C,EAAA,IAAI,SAAS,IAAA,CAAK,CAAC,GAAA,KAAQ,GAAA,KAAQ,IAAI,CAAA,EAAG;AACxC,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,0FAAA,EAAsF;AAAA,EACxH;AAEA,EAAA,MAAM,YAAA,GAAeJ,OAAAA,CAAQ,SAAA,EAAW,YAAY,CAAA;AACpD,EAAA,MAAM,iBAAA,GAAoBA,QAAQ,SAAS,CAAA;AAC3C,EAAA,MAAM,GAAA,GAAMK,QAAAA,CAAS,iBAAA,EAAmB,YAAY,CAAA;AACpD,EAAA,IAAI,GAAA,CAAI,WAAW,IAAI,CAAA,IAAKL,QAAQ,iBAAA,EAAmB,GAAG,MAAM,YAAA,EAAc;AAC5E,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,0FAAA,EAAsF;AAAA,EACxH;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,aAAA,GAAgBM,aAAa,iBAAiB,CAAA;AACpD,IAAA,MAAM,UAAA,GAAaA,aAAa,YAAY,CAAA;AAC5C,IAAA,MAAM,OAAA,GAAUD,QAAAA,CAAS,aAAA,EAAe,UAAU,CAAA;AAClD,IAAA,IAAI,QAAQ,UAAA,CAAW,IAAI,CAAA,IAAKD,UAAAA,CAAW,OAAO,CAAA,EAAG;AACnD,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,iEAAA,EAA6D;AAAA,IAC/F;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAGR;AAEA,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,YAAA,EAAa;AACvC;;;ACTO,SAAS,2BACd,QAAA,EAC4G;AAC5G,EAAA,OAAO;AAAA,IACL,wBAAwB,QAAQ,CAAA;AAAA,IAChC,4BAA4B,QAAQ;AAAA,GACtC;AACF;ACnCA,IAAMG,UAAST,YAAAA,CAAa,4BAAA,EAA8B,EAAE,KAAA,EAAOC,QAAAA,CAAS,MAAM,CAAA;AAE3E,SAAS,cAAA,CACd,MAAA,EACA,MAAA,EACA,YAAA,EACA,IAAA,EACa;AACb,EAAA,MAAA,CAAO,KAAA,EAAM;AACb,EAAA,YAAA,CAAa,KAAA,EAAM;AACnB,EAAA,MAAM,aAA0B,EAAC;AAEjC,EAAA,MAAM,eAAA,GAAkB,MAAA,CAAO,UAAA,CAAW,GAAA,CAAI,mBAAmB,CAAA;AACjE,EAAA,MAAM,aAAa,eAAA,CAAgB,GAAA,CAAI,CAAC,IAAA,KAAS,KAAK,IAAI,CAAA;AAE1D,EAAA,KAAA,MAAW,QAAQ,eAAA,EAAiB;AAClC,IAAA,MAAM,YAAA,GAAeS,OAAA,CAAY,UAAA,CAAW,IAAA,CAAK,IAAI,CAAC,CAAA;AACtD,IAAA,YAAA,CAAa,GAAA,CAAI,YAAA,EAAc,IAAA,CAAK,KAAK,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,UAAA,GAAa,kBAAkB,UAAU,CAAA;AAE/C,EAAA,IAAI,YAAA,GAAe,CAAA;AACnB,EAAA,IAAI,YAAA,GAAe,CAAA;AAEnB,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,MAAM,MAAA,GAAS,iBAAA,CAAkB,SAAA,CAAU,OAAA,EAAS,UAAU,OAAO,CAAA;AAErE,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,YAAA,EAAA;AACA,MAAA,eAAA,CAAgB,UAAA,EAAY,SAAA,CAAU,SAAA,EAAW,MAAA,CAAO,SAAS,qBAAqB,CAAA;AACtF,MAAA,IAAA,CAAA,eAAA,sBAAuC;AAAA,QACrC,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,UAAU,SAAA,CAAU,QAAA;AAAA,QACpB,OAAO,MAAA,CAAO;AAAA,OACf,CAAA;AACD,MAAAD,OAAAA,CAAO,KAAK,wBAAA,EAA0B;AAAA,QACpC,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,GAAI,OAAO,KAAA,GAAQ,EAAE,OAAO,MAAA,CAAO,KAAA,KAAU;AAAC,OAC/C,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAe;AAAA,MACnB,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,WAAW,SAAA,CAAU,SAAA;AAAA,MACrB,UAAU,SAAA,CAAU,QAAA;AAAA,MACpB,UAAA,EAAY,YAAA,CAAa,GAAA,CAAI,SAAA,CAAU,QAAQ,CAAA,IAAK;AAAA,KACtD;AAEA,IAAA,IAAI,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA,EAAG;AACnC,MAAA,YAAA,EAAA;AACA,MAAA,MAAM,QAAA,GAAW,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,SAAS,IAAI,CAAA;AAC/C,MAAA,MAAM,cAAA,GACJ,CAAA,sBAAA,EAAyB,KAAA,CAAM,QAAA,CAAS,IAAI,WAAW,SAAA,CAAU,QAAQ,CAAA,+BAAA,EAChD,QAAA,CAAS,QAAQ,CAAA,+BAAA,CAAA;AAE5C,MAAA,eAAA,CAAgB,UAAA,EAAY,SAAA,CAAU,SAAA,EAAW,cAAc,CAAA;AAC/D,MAAA,IAAA,CAAA,eAAA,sBAAuC;AAAA,QACrC,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,UAAU,SAAA,CAAU,QAAA;AAAA,QACpB,aAAa,QAAA,CAAS,SAAA;AAAA,QACtB,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAAA,OAAAA,CAAO,KAAK,qCAAA,EAAuC;AAAA,QACjD,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,QACrB,MAAM,QAAA,CAAS,SAAA;AAAA,QACf,SAAS,SAAA,CAAU;AAAA,OACpB,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,QAAA,CAAS,IAAA,EAAM,KAAK,CAAA;AACrC,IAAA,YAAA,EAAA;AACA,IAAA,IAAA,CAAA,kBAAA,yBAA0C,KAAK,CAAA;AAC/C,IAAAA,OAAAA,CAAO,MAAM,kBAAA,EAAoB;AAAA,MAC/B,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,MACrB,aAAa,KAAA,CAAM,QAAA,CAAS,WAAA,CAAY,KAAA,CAAM,GAAG,EAAE,CAAA;AAAA,MACnD,WAAW,KAAA,CAAM;AAAA,KAClB,CAAA;AAAA,EACH;AAEA,EAAAA,OAAAA,CAAO,KAAK,0BAAA,EAA4B;AAAA,IACtC,YAAA,EAAc,OAAO,UAAA,CAAW,MAAA;AAAA,IAChC,gBAAA,EAAkB,YAAA;AAAA,IAClB,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,OAAO,UAAA;AACT;AAEA,SAAS,eAAA,CAAgB,UAAA,EAAyB,IAAA,EAAc,KAAA,EAAqB;AACnF,EAAA,UAAA,CAAW,IAAA,CAAK,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA;AACjC;ACjGA,IAAMA,UAAST,YAAAA,CAAa,4BAAA,EAA8B,EAAE,KAAA,EAAOC,QAAAA,CAAS,MAAM,CAAA;AAE3E,SAAS,uBAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACM;AACN,EAAA,IAAI,CAAC,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,EAAG;AAC7B,IAAA,aAAA,CAAc,GAAA,CAAI,KAAA,kBAAO,IAAI,GAAA,EAAK,CAAA;AAAA,EACpC;AAEA,EAAA,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,CAAG,GAAA,CAAI,OAAO,CAAA;AACvC;AAEO,SAAS,0BAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACM;AACN,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AACxC,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,QAAA,CAAS,OAAO,OAAO,CAAA;AAAA,EACzB;AACF;AAEO,SAAS,iBAAA,CACd,aAAA,EACA,KAAA,EACA,IAAA,EACM;AACN,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AACxC,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA;AAAA,EACF;AAEA,EAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC5B,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IACd,SAAS,KAAA,EAAO;AACd,MAAAQ,OAAAA,CAAO,MAAM,2BAAA,EAA6B;AAAA,QACxC,KAAA;AAAA,QACA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAAA,QAC5D,GAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,KAAA,GAAQ,EAAE,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,GAAI;AAAC,OACvE,CAAA;AAAA,IACH;AAAA,EACF,CAAC,CAAA;AACH;AChDA,IAAMA,UAAST,YAAAA,CAAa,4BAAA,EAA8B,EAAE,KAAA,EAAOC,QAAAA,CAAS,MAAM,CAAA;AAE3E,SAAS,mBAAA,CACd,MAAA,EACA,SAAA,EACA,eAAA,EACA,OAAA,EACQ;AACR,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAAQ,OAAAA,CAAO,MAAM,4CAAA,EAA8C;AAAA,MACzD,OAAA,EAAS,OAAO,OAAA,IAAW;AAAA,KAC5B,CAAA;AACD,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,IAAI,MAAA,GAAS,SAAA;AAEb,EAAA,IAAI,OAAA,EAAS,MAAA,IAAU,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,EAAG;AAChD,IAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,OAAA,CAAQ,MAAM,CAAA;AACxC,IAAA,MAAA,GAAS,MAAA,CAAO,OAAO,CAAC,KAAA,KAAU,UAAU,GAAA,CAAI,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA;AAAA,EACtE;AAEA,EAAA,IAAI,gBAAgB,MAAA,CAAO,MAAA;AAAA,IACzB,CAAC,KAAA,KAAU,KAAA,CAAM,UAAA,KAAe,WAAA,IAAe,MAAM,UAAA,KAAe;AAAA,GACtE;AACA,EAAA,IAAI,kBAAkB,MAAA,CAAO,MAAA;AAAA,IAC3B,CAAC,KAAA,KAAU,KAAA,CAAM,UAAA,KAAe,WAAA,IAAe,MAAM,UAAA,KAAe;AAAA,GACtE;AAEA,EAAA,IAAI,MAAA,CAAO,mBAAA,KAAwB,MAAA,IAAa,MAAA,CAAO,uBAAuB,CAAA,EAAG;AAC/E,IAAA,MAAM,eAAe,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,mBAAA,EAAqB,cAAc,MAAM,CAAA;AAC9E,IAAA,aAAA,GAAgB,aAAA,CAAc,KAAA,CAAM,CAAA,EAAG,YAAY,CAAA;AACnD,IAAA,eAAA,GAAkB,eAAA,CAAgB,KAAA,CAAM,CAAA,EAAG,MAAA,CAAO,sBAAsB,YAAY,CAAA;AACpF,IAAA,MAAA,GAAS,CAAC,GAAG,aAAA,EAAe,GAAG,eAAe,CAAA;AAAA,EAChD;AAEA,EAAA,IAAI,aAAA,CAAc,MAAA,KAAW,CAAA,IAAK,eAAA,CAAgB,WAAW,CAAA,EAAG;AAC9D,IAAAA,OAAAA,CAAO,MAAM,+CAAA,EAAiD;AAAA,MAC5D,eAAA;AAAA,MACA,eAAe,CAAC,EAAE,SAAS,MAAA,IAAU,OAAA,CAAQ,OAAO,MAAA,GAAS,CAAA,CAAA;AAAA,MAC7D,GAAI,OAAO,mBAAA,KAAwB,MAAA,GAC/B,EAAE,MAAA,EAAQ,MAAA,CAAO,mBAAA,EAAoB,GACrC;AAAC,KACN,CAAA;AACD,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAqB,EAAC;AAE5B,EAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,IAAA,QAAA,CAAS,IAAA,CAAK,CAAA;AAAA,EAAuB,cAAc,GAAA,CAAI,uBAAuB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC;AAAA,mBAAA,CAAuB,CAAA;AAAA,EACnH;AAEA,EAAA,IAAI,eAAA,CAAgB,SAAS,CAAA,EAAG;AAC9B,IAAA,QAAA,CAAS,IAAA,CAAK,4BAAA,CAA6B,eAAe,CAAC,CAAA;AAAA,EAC7D;AAEA,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA;AAC9B,EAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,SAAS,CAAC,CAAA;AAEhD,EAAAA,OAAAA,CAAO,KAAK,wBAAA,EAA0B;AAAA,IACpC,YAAY,MAAA,CAAO,MAAA;AAAA,IACnB,mBAAmB,aAAA,CAAc,MAAA;AAAA,IACjC,qBAAqB,eAAA,CAAgB,MAAA;AAAA,IACrC,eAAA;AAAA,IACA,eAAe,CAAC,EAAE,SAAS,MAAA,IAAU,OAAA,CAAQ,OAAO,MAAA,GAAS,CAAA,CAAA;AAAA,IAC7D,GAAI,OAAO,mBAAA,KAAwB,MAAA,GAAY,EAAE,MAAA,EAAQ,MAAA,CAAO,mBAAA,EAAoB,GAAI,EAAC;AAAA,IACzF,eAAA;AAAA,IACA,WAAW,GAAA,CAAI;AAAA,GAChB,CAAA;AAED,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,wBAAwB,KAAA,EAAsB;AACrD,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,CAAA,UAAA,EAAa,SAAA,CAAU,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,OAAA,CAAA;AAAA,IAC3C,CAAA,iBAAA,EAAoB,SAAA,CAAU,KAAA,CAAM,QAAA,CAAS,WAAW,CAAC,CAAA,cAAA,CAAA;AAAA,IACzD,CAAA,cAAA,EAAiB,SAAA,CAAU,KAAA,CAAM,SAAS,CAAC,CAAA,WAAA,CAAA;AAAA,IAC3C,CAAA,WAAA,EAAc,SAAA,CAAU,KAAA,CAAM,UAAU,CAAC,CAAA,QAAA,CAAA;AAAA,IACzC;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;AAEA,SAAS,6BAA6B,MAAA,EAAyB;AAC7D,EAAA,OAAO;AAAA,IACL,oBAAA;AAAA,IACA,0KAAA;AAAA,IACA,GAAG,MAAA,CAAO,GAAA,CAAI,yBAAyB,CAAA;AAAA,IACvC;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;AAEA,SAAS,0BAA0B,KAAA,EAAsB;AACvD,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,CAAA,UAAA,EAAa,SAAA,CAAU,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,OAAA,CAAA;AAAA,IAC3C,CAAA,iBAAA,EAAoB,SAAA,CAAU,KAAA,CAAM,QAAA,CAAS,WAAW,CAAC,CAAA,cAAA,CAAA;AAAA,IACzD,CAAA,cAAA,EAAiB,SAAA,CAAU,KAAA,CAAM,SAAS,CAAC,CAAA,WAAA,CAAA;AAAA,IAC3C,CAAA,WAAA,EAAc,SAAA,CAAU,KAAA,CAAM,UAAU,CAAC,CAAA,QAAA,CAAA;AAAA,IACzC,kEAAA;AAAA,IACA;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;AAEA,SAAS,UAAU,GAAA,EAAqB;AACtC,EAAA,OAAO,IACJ,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA,CACrB,OAAA,CAAQ,MAAM,MAAM,CAAA,CACpB,QAAQ,IAAA,EAAM,MAAM,EACpB,OAAA,CAAQ,IAAA,EAAM,QAAQ,CAAA,CACtB,OAAA,CAAQ,MAAM,QAAQ,CAAA;AAC3B;;;ACjHO,SAAS,QAAA,CAAS,QAA4B,IAAA,EAAiC;AACpF,EAAA,OAAO,MAAA,CAAO,IAAI,IAAI,CAAA;AACxB;AAEO,SAAS,aAAa,MAAA,EAAqC;AAChE,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ,CAAA;AACnC;AAEO,SAAS,QAAA,CAAS,QAA4B,IAAA,EAAuB;AAC1E,EAAA,OAAO,MAAA,CAAO,IAAI,IAAI,CAAA;AACxB;AAEO,SAAS,cAAc,MAAA,EAAoC;AAChE,EAAA,OAAO,MAAA,CAAO,IAAA;AAChB;AAEO,SAAS,cAAc,MAAA,EAAsC;AAClE,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,IAAA,EAAM,CAAA;AACjC;AAEO,SAAS,cAAc,UAAA,EAAmD;AAC/E,EAAA,OAAO,UAAA;AACT;AAEO,SAAS,eAAA,CAAgB,QAA4B,IAAA,EAAoC;AAC9F,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA,EAAG,QAAA,CAAS,YAAA;AACpC;;;ACFO,IAAM,gBAAN,MAAoB;AAAA,EACjB,MAAA,uBAAiC,GAAA,EAAI;AAAA,EACrC,aAAA,uBAA2C,GAAA,EAAI;AAAA,EACtC,MAAA;AAAA,EACT,aAAqD,EAAC;AAAA,EACtD,YAAA,uBAA4C,GAAA,EAAI;AAAA,EAExD,YAAY,MAAA,EAA6B;AACvC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,QAAA,EAAS;AAAA,EAChB;AAAA,EAEA,QAAA,GAAiB;AACf,IAAA,IAAA,CAAK,UAAA,GAAa,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,QAAQ,IAAA,CAAK,YAAA,EAAc,CAAC,KAAA,EAAO,IAAA,KAAS;AAC7F,MAAA,IAAA,CAAK,IAAA,CAAK,OAAO,IAAI,CAAA;AAAA,IACvB,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,IAAI,IAAA,EAAiC;AACnC,IAAA,OAAO,QAAA,CAAS,IAAA,CAAK,MAAA,EAAQ,IAAI,CAAA;AAAA,EACnC;AAAA,EAEA,MAAA,GAAkB;AAChB,IAAA,OAAO,YAAA,CAAa,KAAK,MAAM,CAAA;AAAA,EACjC;AAAA,EAEA,IAAI,IAAA,EAAuB;AACzB,IAAA,OAAO,QAAA,CAAS,IAAA,CAAK,MAAA,EAAQ,IAAI,CAAA;AAAA,EACnC;AAAA,EAEA,IAAA,GAAe;AACb,IAAA,OAAO,aAAA,CAAc,KAAK,MAAM,CAAA;AAAA,EAClC;AAAA,EAEA,QAAA,GAAqB;AACnB,IAAA,OAAO,aAAA,CAAc,KAAK,MAAM,CAAA;AAAA,EAClC;AAAA,EAEA,aAAA,GAAgE;AAC9D,IAAA,OAAO,aAAA,CAAc,KAAK,UAAU,CAAA;AAAA,EACtC;AAAA,EAEA,wBAAA,GAAoC;AAClC,IAAA,OAAO,IAAA,CAAK,OAAO,qBAAA,IAAyB,KAAA;AAAA,EAC9C;AAAA,EAEA,gBAAgB,IAAA,EAAoC;AAClD,IAAA,OAAO,eAAA,CAAgB,IAAA,CAAK,MAAA,EAAQ,IAAI,CAAA;AAAA,EAC1C;AAAA,EAEA,eAAe,OAAA,EAAsC;AACnD,IAAA,OAAO,mBAAA,CAAoB,KAAK,MAAA,EAAQ,IAAA,CAAK,QAAO,EAAG,IAAA,CAAK,IAAA,EAAK,EAAG,OAAO,CAAA;AAAA,EAC7E;AAAA,EAEA,EAAA,CAAG,OAA2B,OAAA,EAAkC;AAC9D,IAAA,uBAAA,CAAwB,IAAA,CAAK,aAAA,EAAe,KAAA,EAAO,OAAO,CAAA;AAAA,EAC5D;AAAA,EAEA,GAAA,CAAI,OAA2B,OAAA,EAAkC;AAC/D,IAAA,0BAAA,CAA2B,IAAA,CAAK,aAAA,EAAe,KAAA,EAAO,OAAO,CAAA;AAAA,EAC/D;AAAA,EAEA,SAAA,CAAU,OAA2B,IAAA,EAAqB;AACxD,IAAA,IAAA,CAAK,IAAA,CAAK,OAAO,IAAI,CAAA;AAAA,EACvB;AAAA,EAEA,iBAAA,GAAmE;AACjE,IAAA,OAAO,2BAA2B,IAAI,CAAA;AAAA,EACxC;AAAA,EAEQ,IAAA,CAAK,OAA2B,IAAA,EAAqB;AAC3D,IAAA,iBAAA,CAAkB,IAAA,CAAK,aAAA,EAAe,KAAA,EAAO,IAAI,CAAA;AAAA,EACnD;AACF","file":"index.js","sourcesContent":["/**\n * Skill System Types\n *\n * Core type definitions for the AgentForge Agent Skills system.\n * These types align with the Agent Skills specification (https://agentskills.io/specification).\n */\n\n// ─── Trust Policy Types ──────────────────────────────────────────────────\n\n/**\n * Trust level for a skill root directory.\n *\n * - `workspace` — Skills from the project workspace (highest trust, scripts allowed)\n * - `trusted` — Explicitly trusted skill roots (scripts allowed)\n * - `untrusted` — Untrusted roots like community packs (scripts blocked by default)\n */\nexport type TrustLevel = 'workspace' | 'trusted' | 'untrusted';\n\n/**\n * Configuration for a skill root with an explicit trust level.\n *\n * @example\n * ```ts\n * const roots: SkillRootConfig[] = [\n * { path: '.agentskills', trust: 'workspace' },\n * { path: '~/.agentskills', trust: 'trusted' },\n * { path: '/shared/community-skills', trust: 'untrusted' },\n * ];\n * ```\n */\nexport interface SkillRootConfig {\n /** Directory path to scan for skills */\n path: string;\n /** Trust level assigned to all skills discovered from this root */\n trust: TrustLevel;\n}\n\n/**\n * Policy decision returned by trust enforcement checks.\n */\nexport interface TrustPolicyDecision {\n /** Whether the action is allowed */\n allowed: boolean;\n /** Machine-readable reason code for auditing */\n reason: TrustPolicyReason;\n /** Human-readable explanation */\n message: string;\n}\n\n/**\n * Reason codes for trust policy decisions.\n *\n * Used for structured logging and auditing of guardrail behavior.\n */\nexport enum TrustPolicyReason {\n /** Resource is not a script — no trust check needed */\n NOT_SCRIPT = 'not-script',\n /** Skill root has workspace trust — scripts allowed */\n WORKSPACE_TRUST = 'workspace-trust',\n /** Skill root has explicit trusted status — scripts allowed */\n TRUSTED_ROOT = 'trusted-root',\n /** Skill body activation allowed because the root is workspace-owned */\n WORKSPACE_SKILL_ACTIVATION = 'workspace-skill-activation',\n /** Skill body activation allowed because the root is explicitly trusted */\n TRUSTED_SKILL_ACTIVATION = 'trusted-skill-activation',\n /** Full skill-body activation denied for an untrusted root */\n UNTRUSTED_SKILL_ACTIVATION_DENIED = 'untrusted-skill-activation-denied',\n /** Skill root is untrusted — scripts denied by default */\n UNTRUSTED_SCRIPT_DENIED = 'untrusted-script-denied',\n /** Untrusted script access was explicitly allowed via config override */\n UNTRUSTED_SCRIPT_ALLOWED = 'untrusted-script-allowed-override',\n /** Trust level is unknown — treated as untrusted for security */\n UNKNOWN_TRUST_LEVEL = 'unknown-trust-level',\n}\n\n/**\n * Parsed metadata from a SKILL.md frontmatter block.\n *\n * Required fields: `name`, `description`.\n * All other fields are optional per the Agent Skills spec.\n */\nexport interface SkillMetadata {\n /** Skill name (1-64 chars, lowercase alphanumeric + hyphens, must match parent dir name) */\n name: string;\n /** Human-readable description (1-1024 chars) */\n description: string;\n /** SPDX license identifier */\n license?: string;\n /** List of compatible agent frameworks / tool hosts */\n compatibility?: string[];\n /** Arbitrary key-value metadata (author, version, etc.) */\n metadata?: Record<string, unknown>;\n /** Tools that this skill is allowed to use */\n allowedTools?: string[];\n}\n\n/**\n * A fully resolved skill entry in the registry.\n *\n * Contains parsed metadata plus internal tracking fields\n * that are not part of the SKILL.md frontmatter.\n */\nexport interface Skill {\n /** Parsed frontmatter metadata */\n metadata: SkillMetadata;\n /** Absolute path to the skill directory */\n skillPath: string;\n /** Which configured skill root this was discovered from */\n rootPath: string;\n /** Trust level assigned to this skill (inherited from root config) */\n trustLevel: TrustLevel;\n}\n\n/**\n * Configuration for the SkillRegistry.\n */\nexport interface SkillRegistryConfig {\n /**\n * Array of directory paths to scan for skills.\n *\n * Each entry can be a plain string (defaults to `'untrusted'` trust level)\n * or a `SkillRootConfig` object with an explicit trust level.\n *\n * Paths may be absolute or relative (resolved against `cwd`).\n * The `~` prefix is expanded to `$HOME`.\n *\n * @example\n * ```ts\n * // Simple string roots (default to 'untrusted')\n * skillRoots: ['.agentskills', '~/.agentskills']\n *\n * // Trust-aware roots\n * skillRoots: [\n * { path: '.agentskills', trust: 'workspace' },\n * { path: '~/.agentskills', trust: 'trusted' },\n * { path: '/shared/community', trust: 'untrusted' },\n * ]\n * ```\n */\n skillRoots: Array<string | SkillRootConfig>;\n\n /**\n * Feature flag to enable Agent Skills in system prompts.\n *\n * When `false` (default), `generatePrompt()` returns an empty string\n * so agents operate with unmodified system prompts.\n *\n * @default false\n */\n enabled?: boolean;\n\n /**\n * Maximum number of skills to include in generated prompts.\n *\n * Caps prompt token usage when many skills are discovered.\n * Skills are included in discovery order (first root first).\n * When undefined, all discovered skills are included.\n */\n maxDiscoveredSkills?: number;\n\n /**\n * Allow script resources from untrusted roots.\n *\n * When `true`, scripts from `scripts/` directories in untrusted\n * skill roots are returned instead of being denied. This disables\n * the default-deny policy for untrusted scripts.\n *\n * **Security warning:** Only enable when you have reviewed all\n * skill packs from untrusted roots.\n *\n * @default false\n */\n allowUntrustedScripts?: boolean;\n}\n\n/**\n * Options for `SkillRegistry.generatePrompt()`.\n */\nexport interface SkillPromptOptions {\n /**\n * Subset of skill names to include in the generated prompt.\n *\n * When provided, only skills matching these names appear in the\n * `<available_skills>` XML block. This enables creating focused\n * agents with different skill sets from the same registry.\n *\n * When omitted or empty, all discovered skills are included.\n *\n * @example ['code-review', 'testing-strategy']\n */\n skills?: string[];\n}\n\n/**\n * Events emitted by the SkillRegistry during discovery and usage.\n */\nexport enum SkillRegistryEvent {\n /** Emitted when a valid skill is discovered during scanning */\n SKILL_DISCOVERED = 'skill:discovered',\n /** Emitted when a skill parse or validation issue is encountered */\n SKILL_WARNING = 'skill:warning',\n /** Emitted when a skill is activated (full body loaded) */\n SKILL_ACTIVATED = 'skill:activated',\n /** Emitted when a skill resource file is loaded */\n SKILL_RESOURCE_LOADED = 'skill:resource-loaded',\n /** Emitted when a trust policy denies access to a resource */\n TRUST_POLICY_DENIED = 'trust:policy-denied',\n /** Emitted when a trust policy allows access (for auditing) */\n TRUST_POLICY_ALLOWED = 'trust:policy-allowed',\n}\n\n/**\n * Event handler type for skill registry events.\n */\nexport type SkillEventHandler = (data: unknown) => void;\n\n/**\n * Result of parsing a single SKILL.md file.\n */\nexport interface SkillParseResult {\n /** Whether parsing and validation succeeded */\n success: boolean;\n /** Parsed metadata (present when success is true) */\n metadata?: SkillMetadata;\n /** The raw markdown body below the frontmatter (present when success is true) */\n body?: string;\n /** Error description (present when success is false) */\n error?: string;\n}\n\n/**\n * Validation error detail.\n */\nexport interface SkillValidationError {\n /** Which field failed validation */\n field: string;\n /** Human-readable error message */\n message: string;\n}\n","/**\n * SKILL.md Frontmatter Parser\n *\n * Parses YAML frontmatter from SKILL.md files and validates\n * against the Agent Skills specification constraints.\n *\n * @see https://agentskills.io/specification\n */\n\nimport matter from 'gray-matter';\nimport type { SkillMetadata, SkillParseResult, SkillValidationError } from './types.js';\n\n/**\n * Skill name validation constraints (per spec).\n *\n * - 1-64 characters\n * - Lowercase alphanumeric and hyphens only\n * - No leading, trailing, or consecutive hyphens\n */\nconst SKILL_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\nconst SKILL_NAME_MAX_LENGTH = 64;\nconst SKILL_DESCRIPTION_MAX_LENGTH = 1024;\n\n/**\n * Validate the `name` field per the Agent Skills spec.\n *\n * @param name - The name value from frontmatter\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillName(name: unknown): SkillValidationError[] {\n const errors: SkillValidationError[] = [];\n\n if (name === undefined || name === null) {\n errors.push({ field: 'name', message: 'name is required' });\n return errors;\n }\n\n if (typeof name !== 'string') {\n errors.push({ field: 'name', message: 'name must be a string' });\n return errors;\n }\n\n if (name.length === 0) {\n errors.push({ field: 'name', message: 'name must not be empty' });\n return errors;\n }\n\n if (name.length > SKILL_NAME_MAX_LENGTH) {\n errors.push({\n field: 'name',\n message: `name must be at most ${SKILL_NAME_MAX_LENGTH} characters (got ${name.length})`,\n });\n return errors;\n }\n\n if (!SKILL_NAME_PATTERN.test(name)) {\n errors.push({\n field: 'name',\n message: 'name must be lowercase alphanumeric with hyphens, no leading/trailing/consecutive hyphens',\n });\n }\n\n if (name.includes('--')) {\n errors.push({\n field: 'name',\n message: 'name must not contain consecutive hyphens',\n });\n }\n\n return errors;\n}\n\n/**\n * Validate the `description` field per the Agent Skills spec.\n *\n * @param description - The description value from frontmatter\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillDescription(description: unknown): SkillValidationError[] {\n const errors: SkillValidationError[] = [];\n\n if (description === undefined || description === null) {\n errors.push({ field: 'description', message: 'description is required' });\n return errors;\n }\n\n if (typeof description !== 'string') {\n errors.push({ field: 'description', message: 'description must be a string' });\n return errors;\n }\n\n if (description.trim().length === 0) {\n errors.push({ field: 'description', message: 'description must not be empty' });\n return errors;\n }\n\n if (description.length > SKILL_DESCRIPTION_MAX_LENGTH) {\n errors.push({\n field: 'description',\n message: `description must be at most ${SKILL_DESCRIPTION_MAX_LENGTH} characters (got ${description.length})`,\n });\n }\n\n return errors;\n}\n\n/**\n * Validate that the skill name matches its parent directory name (per spec).\n *\n * @param name - The name from frontmatter\n * @param dirName - The parent directory name\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillNameMatchesDir(name: string, dirName: string): SkillValidationError[] {\n if (name !== dirName) {\n return [{\n field: 'name',\n message: `name \"${name}\" must match parent directory name \"${dirName}\"`,\n }];\n }\n return [];\n}\n\n/**\n * Parse and validate a SKILL.md file's raw content.\n *\n * Extracts YAML frontmatter using gray-matter, then validates\n * required and optional fields against spec constraints.\n *\n * @param content - Raw file content of the SKILL.md\n * @param dirName - Parent directory name for name-match validation\n * @returns Parse result with metadata or error\n */\nexport function parseSkillContent(content: string, dirName: string): SkillParseResult {\n let parsed: matter.GrayMatterFile<string>;\n\n try {\n parsed = matter(content);\n } catch (err) {\n return {\n success: false,\n error: `Failed to parse frontmatter: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n const data = parsed.data;\n\n // Validate required fields\n const errors: SkillValidationError[] = [\n ...validateSkillName(data.name),\n ...validateSkillDescription(data.description),\n ];\n\n // If name is valid, validate it matches directory name\n if (typeof data.name === 'string' && data.name.length > 0 && SKILL_NAME_PATTERN.test(data.name)) {\n errors.push(...validateSkillNameMatchesDir(data.name, dirName));\n }\n\n if (errors.length > 0) {\n return {\n success: false,\n error: errors.map((e) => `${e.field}: ${e.message}`).join('; '),\n };\n }\n\n // Build metadata from validated fields\n const metadata: SkillMetadata = {\n name: data.name as string,\n description: data.description as string,\n };\n\n // Optional fields\n if (data.license !== undefined) {\n metadata.license = String(data.license);\n }\n\n if (Array.isArray(data.compatibility)) {\n metadata.compatibility = data.compatibility.map(String);\n }\n\n if (data.metadata !== undefined && typeof data.metadata === 'object' && data.metadata !== null) {\n metadata.metadata = data.metadata as Record<string, unknown>;\n }\n\n if (Array.isArray(data['allowed-tools'])) {\n metadata.allowedTools = data['allowed-tools'].map(String);\n }\n\n return {\n success: true,\n metadata,\n body: parsed.content,\n };\n}\n","/**\n * Skill Directory Scanner\n *\n * Scans configured skill roots for directories containing valid SKILL.md files.\n * Returns a list of candidate skill paths for the parser to process.\n */\n\nimport { existsSync, readdirSync, statSync, readFileSync } from 'node:fs';\nimport { resolve, basename } from 'node:path';\nimport { homedir } from 'node:os';\nimport { createLogger, LogLevel } from '@agentforge/core';\n\nconst logger = createLogger('agentforge:skills:scanner', { level: LogLevel.INFO });\n\n/**\n * Discovered skill candidate — a directory containing a SKILL.md file.\n */\nexport interface SkillCandidate {\n /** Absolute path to the skill directory */\n skillPath: string;\n /** The parent directory name (expected to match the skill name) */\n dirName: string;\n /** Raw content of the SKILL.md file */\n content: string;\n /** Which configured root this came from */\n rootPath: string;\n}\n\n/**\n * Expand `~` prefix to the user's home directory.\n */\nexport function expandHome(p: string): string {\n if (p.startsWith('~/') || p === '~') {\n return resolve(homedir(), p.slice(2));\n }\n return p;\n}\n\n/**\n * Scan a single skill root for directories containing SKILL.md.\n *\n * @param rootPath - The root directory to scan (may not exist)\n * @returns Array of valid skill candidates found under this root\n */\nexport function scanSkillRoot(rootPath: string): SkillCandidate[] {\n const resolvedRoot = resolve(expandHome(rootPath));\n const candidates: SkillCandidate[] = [];\n\n if (!existsSync(resolvedRoot)) {\n logger.debug('Skill root does not exist, skipping', { rootPath: resolvedRoot });\n return candidates;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(resolvedRoot);\n } catch (err) {\n logger.warn('Failed to read skill root directory', {\n rootPath: resolvedRoot,\n error: err instanceof Error ? err.message : String(err),\n });\n return candidates;\n }\n\n for (const entry of entries) {\n const entryPath = resolve(resolvedRoot, entry);\n\n // Only process directories\n let stat;\n try {\n stat = statSync(entryPath);\n } catch {\n continue;\n }\n if (!stat.isDirectory()) {\n continue;\n }\n\n // Check for SKILL.md inside the directory\n const skillMdPath = resolve(entryPath, 'SKILL.md');\n if (!existsSync(skillMdPath)) {\n continue;\n }\n\n // Read the SKILL.md content\n try {\n const content = readFileSync(skillMdPath, 'utf-8');\n candidates.push({\n skillPath: entryPath,\n dirName: basename(entryPath),\n content,\n rootPath: resolvedRoot,\n });\n } catch (err) {\n logger.warn('Failed to read SKILL.md', {\n path: skillMdPath,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n logger.debug('Scanned skill root', {\n rootPath: resolvedRoot,\n candidatesFound: candidates.length,\n });\n\n return candidates;\n}\n\n/**\n * Scan multiple skill roots for directories containing SKILL.md.\n *\n * @param skillRoots - Array of root paths to scan\n * @returns Array of all skill candidates found across all roots\n */\nexport function scanAllSkillRoots(skillRoots: string[]): SkillCandidate[] {\n const allCandidates: SkillCandidate[] = [];\n\n for (const root of skillRoots) {\n const candidates = scanSkillRoot(root);\n allCandidates.push(...candidates);\n }\n\n logger.info('Skill discovery complete', {\n rootsScanned: skillRoots.length,\n totalCandidates: allCandidates.length,\n });\n\n return allCandidates;\n}\n","import matter from 'gray-matter';\n\n/**\n * Extract the body content below YAML frontmatter from a SKILL.md file.\n *\n * Delegates to `gray-matter` for consistent frontmatter handling across\n * the codebase (matches `parseSkillContent()` in parser.ts).\n *\n * @param content - The full SKILL.md file content\n * @returns The body content below the frontmatter\n */\nexport function extractBody(content: string): string {\n return matter(content).content.trim();\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\n\nexport const activationLogger = createLogger('agentforge:skills:activation', {\n level: LogLevel.INFO,\n});\n\nexport function formatMissingSkillMessage(name: string, availableNames: string[]): string {\n const suggestion = availableNames.length > 0\n ? ` Available skills: ${availableNames.join(', ')}`\n : ' No skills are currently registered.';\n\n return `Skill \"${name}\" not found.${suggestion}`;\n}\n","/**\n * Skill Trust Policy Engine\n *\n * Enforces trust-level-based access control for skill resources.\n * Scripts from untrusted roots are denied by default unless explicitly allowed.\n *\n * Trust levels:\n * - `workspace` — Project-local skills, highest trust. Scripts always allowed.\n * - `trusted` — Explicitly trusted roots. Scripts allowed.\n * - `untrusted` — Community or third-party skills. Scripts denied by default.\n *\n * @see https://agentskills.io/specification\n */\n\nimport type { TrustLevel, TrustPolicyDecision, SkillRootConfig } from './types.js';\nimport { TrustPolicyReason } from './types.js';\n\n// ─── Constants ───────────────────────────────────────────────────────────\n\n/**\n * Resource path prefix that requires trust enforcement.\n *\n * Only resources under `scripts/` are subject to trust policy checks.\n * Other directories (references/, assets/, etc.) are always accessible.\n */\nconst SCRIPT_PATH_PREFIX = 'scripts/';\nconst SCRIPT_PATH_EXACT = 'scripts';\n\n// ─── Helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Normalize a skill root config entry.\n *\n * String entries default to `'untrusted'` trust level for safe defaults.\n *\n * @param root - A string path or SkillRootConfig object\n * @returns Normalized SkillRootConfig with explicit trust level\n */\nexport function normalizeRootConfig(root: string | SkillRootConfig): SkillRootConfig {\n if (typeof root === 'string') {\n return { path: root, trust: 'untrusted' };\n }\n return root;\n}\n\n/**\n * Check whether a resource path refers to a script.\n *\n * A resource is considered a script if its relative path starts with\n * `scripts/` or is exactly `scripts`, after normalizing path separators,\n * stripping leading \"./\" segments, and ignoring case.\n *\n * @param resourcePath - Relative path within the skill directory\n * @returns True if the resource is in the scripts/ directory\n */\nexport function isScriptResource(resourcePath: string): boolean {\n // Normalize to forward slashes and trim for consistent checking\n let normalized = resourcePath.trim().replace(/\\\\/g, '/');\n\n // Collapse repeated separators (e.g., \"scripts//setup.sh\" → \"scripts/setup.sh\")\n normalized = normalized.replace(/\\/+/g, '/');\n\n // Strip leading \"./\" segments (e.g., \"./scripts/setup.sh\" → \"scripts/setup.sh\")\n while (normalized.startsWith('./')) {\n normalized = normalized.slice(2);\n }\n\n // Case-insensitive comparison to handle case-insensitive file systems\n const lower = normalized.toLowerCase();\n\n return lower === SCRIPT_PATH_EXACT\n || lower.startsWith(SCRIPT_PATH_PREFIX);\n}\n\n// ─── Policy Engine ───────────────────────────────────────────────────────\n\n/**\n * Evaluate the trust policy for a resource access request.\n *\n * Non-script resources are allowed regardless of trust level, except for\n * SKILL.md, which is protected by the activation policy.\n * Script resources require `workspace` or `trusted` trust, or the\n * `allowUntrustedScripts` override to be enabled.\n *\n * @param resourcePath - Relative path to the resource within the skill directory\n * @param trustLevel - Trust level of the skill's root directory\n * @param allowUntrustedScripts - Override flag to permit untrusted scripts\n * @returns Policy decision with allow/deny, reason code, and message\n */\nexport function evaluateTrustPolicy(\n resourcePath: string,\n trustLevel: TrustLevel,\n allowUntrustedScripts: boolean = false,\n): TrustPolicyDecision {\n // Non-script resources — SKILL.md is checked separately by the resource tool.\n if (!isScriptResource(resourcePath)) {\n return {\n allowed: true,\n reason: TrustPolicyReason.NOT_SCRIPT,\n message: 'Resource is not a script — no trust check required',\n };\n }\n\n // Script resources — check trust level\n switch (trustLevel) {\n case 'workspace':\n return {\n allowed: true,\n reason: TrustPolicyReason.WORKSPACE_TRUST,\n message: 'Script allowed — skill root has workspace trust',\n };\n\n case 'trusted':\n return {\n allowed: true,\n reason: TrustPolicyReason.TRUSTED_ROOT,\n message: 'Script allowed — skill root is explicitly trusted',\n };\n\n case 'untrusted':\n if (allowUntrustedScripts) {\n return {\n allowed: true,\n reason: TrustPolicyReason.UNTRUSTED_SCRIPT_ALLOWED,\n message: 'Script from untrusted root allowed via allowUntrustedScripts override',\n };\n }\n return {\n allowed: false,\n reason: TrustPolicyReason.UNTRUSTED_SCRIPT_DENIED,\n message: `Script access denied — skill root is untrusted. ` +\n `Scripts from untrusted roots are blocked by default for security. ` +\n `To allow, set 'allowUntrustedScripts: true' in SkillRegistryConfig or ` +\n `promote the skill root to 'trusted' or 'workspace' trust level.`,\n };\n\n default:\n return {\n allowed: false,\n reason: TrustPolicyReason.UNKNOWN_TRUST_LEVEL,\n message: `Script access denied — trust level \"${trustLevel}\" is unknown and is treated as untrusted for security.`,\n };\n }\n}\n\n/**\n * Evaluate whether the full SKILL.md body can be exposed through activation.\n *\n * Untrusted roots stay discoverable, but their full instruction bodies are\n * blocked until the operator explicitly promotes that root to `trusted` or\n * `workspace`.\n */\nexport function evaluateSkillActivationPolicy(trustLevel: TrustLevel): TrustPolicyDecision {\n switch (trustLevel) {\n case 'workspace':\n return {\n allowed: true,\n reason: TrustPolicyReason.WORKSPACE_SKILL_ACTIVATION,\n message: 'Skill activation allowed — skill root has workspace trust',\n };\n\n case 'trusted':\n return {\n allowed: true,\n reason: TrustPolicyReason.TRUSTED_SKILL_ACTIVATION,\n message: 'Skill activation allowed — skill root is explicitly trusted',\n };\n\n case 'untrusted':\n return {\n allowed: false,\n reason: TrustPolicyReason.UNTRUSTED_SKILL_ACTIVATION_DENIED,\n message: `Skill activation blocked — skill root is untrusted. ` +\n `Untrusted skills remain discoverable, but their full SKILL.md bodies are blocked by default. ` +\n `Promote the skill root to 'trusted' or 'workspace' trust level after review to allow activation.`,\n };\n\n default:\n return {\n allowed: false,\n reason: TrustPolicyReason.UNKNOWN_TRUST_LEVEL,\n message: `Skill activation blocked — trust level \"${trustLevel}\" is unknown and is treated as untrusted for security.`,\n };\n }\n}\n","import { readFileSync, realpathSync } from 'node:fs';\nimport { isAbsolute, relative, resolve } from 'node:path';\nimport type { SkillRegistry } from './registry.js';\nimport { SkillRegistryEvent, TrustPolicyReason } from './types.js';\nimport { extractBody } from './activation-content.js';\nimport { activationLogger } from './activation-shared.js';\nimport { evaluateSkillActivationPolicy, evaluateTrustPolicy } from './trust.js';\n\nconst PATH_TRAVERSAL_MESSAGE =\n 'Path traversal is not allowed — resource paths must stay within the skill directory';\nconst SYMLINK_ESCAPE_MESSAGE = 'Symlink target escapes the skill directory — access denied';\n\ntype CanonicalResourcePathResult =\n | {\n kind: 'success';\n resolvedPath: string;\n canonicalPath: string;\n canonicalRelativePath: string;\n }\n | { kind: 'access-denied'; message: string }\n | { kind: 'resource-not-found'; resolvedPath: string; error: string }\n | { kind: 'target-read-failure'; resolvedPath: string; error: string }\n | { kind: 'read-failure'; error: string };\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction formatResourceReadError(error: unknown, resolvedPath: string): string {\n const message = formatError(error);\n const detailIndex = message.indexOf(', ');\n const prefix = detailIndex === -1 ? message : message.slice(0, detailIndex);\n return `${prefix}, open '${resolvedPath}'`;\n}\n\nfunction resolveCanonicalResourcePath(\n skillPath: string,\n resourcePath: string\n): CanonicalResourcePathResult {\n if (isAbsolute(resourcePath)) {\n return { kind: 'access-denied', message: 'Absolute resource paths are not allowed' };\n }\n\n if (resourcePath.split(/[/\\\\]/).some((segment) => segment === '..')) {\n return { kind: 'access-denied', message: PATH_TRAVERSAL_MESSAGE };\n }\n\n const resolvedSkillPath = resolve(skillPath);\n const resolvedPath = resolve(resolvedSkillPath, resourcePath);\n const lexicalRelativePath = relative(resolvedSkillPath, resolvedPath);\n if (\n lexicalRelativePath.startsWith('..') ||\n isAbsolute(lexicalRelativePath) ||\n resolve(resolvedSkillPath, lexicalRelativePath) !== resolvedPath\n ) {\n return { kind: 'access-denied', message: PATH_TRAVERSAL_MESSAGE };\n }\n\n let canonicalSkillPath: string;\n try {\n canonicalSkillPath = realpathSync(resolvedSkillPath);\n } catch (error) {\n return { kind: 'read-failure', error: formatResourceReadError(error, resolvedPath) };\n }\n\n let canonicalPath: string;\n try {\n canonicalPath = realpathSync(resolvedPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return {\n kind: 'resource-not-found',\n resolvedPath,\n error: formatResourceReadError(error, resolvedPath),\n };\n }\n return {\n kind: 'target-read-failure',\n resolvedPath,\n error: formatResourceReadError(error, resolvedPath),\n };\n }\n\n const canonicalRelativePath = relative(canonicalSkillPath, canonicalPath);\n if (canonicalRelativePath.startsWith('..') || isAbsolute(canonicalRelativePath)) {\n return { kind: 'access-denied', message: SYMLINK_ESCAPE_MESSAGE };\n }\n\n return { kind: 'success', resolvedPath, canonicalPath, canonicalRelativePath };\n}\n\nexport type SkillActivationResult =\n | { kind: 'success'; body: string }\n | { kind: 'skill-not-found'; name: string; availableNames: string[] }\n | { kind: 'access-denied'; reason: TrustPolicyReason; message: string }\n | { kind: 'read-failure'; name: string; error: string };\n\nexport type SkillResourceResult =\n | { kind: 'success'; content: string }\n | { kind: 'skill-not-found'; name: string; availableNames: string[] }\n | { kind: 'access-denied'; message: string; reason?: TrustPolicyReason }\n | { kind: 'resource-not-found'; name: string; resourcePath: string; error: string }\n | { kind: 'read-failure'; name: string; resourcePath: string; error: string };\n\n/** Package-internal owner of Agent Skill lookup, policy, reads, and audit signals. */\nexport class AgentSkillAccess {\n constructor(private readonly registry: SkillRegistry) {}\n\n async readResource(name: string, resourcePath: string): Promise<SkillResourceResult> {\n const skill = this.registry.get(name);\n if (!skill) {\n const availableNames = this.registry.getNames();\n activationLogger.warn('Skill resource load failed — skill not found', {\n name,\n resourcePath,\n });\n return { kind: 'skill-not-found', name, availableNames };\n }\n\n const pathResult = resolveCanonicalResourcePath(skill.skillPath, resourcePath);\n if (pathResult.kind === 'access-denied') {\n activationLogger.warn('Skill resource load blocked — path traversal', {\n name,\n resourcePath,\n error: pathResult.message,\n });\n return pathResult;\n }\n if (pathResult.kind === 'read-failure') {\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: pathResult.error,\n });\n return { ...pathResult, name, resourcePath };\n }\n\n const skillInstructionsPath = resolve(skill.skillPath, 'SKILL.md');\n let isSkillInstructions =\n pathResult.resolvedPath.toLowerCase() === skillInstructionsPath.toLowerCase();\n if (!isSkillInstructions && pathResult.kind === 'success') {\n try {\n isSkillInstructions =\n pathResult.canonicalPath.toLowerCase() ===\n realpathSync(skillInstructionsPath).toLowerCase();\n } catch {\n // The resource read below reports missing or unreadable paths.\n }\n }\n if (isSkillInstructions) {\n const activationDecision = evaluateSkillActivationPolicy(skill.trustLevel);\n if (!activationDecision.allowed) {\n activationLogger.warn('Skill resource load blocked — skill instructions trust policy', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: activationDecision.reason,\n message: activationDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath: 'SKILL.md',\n trustLevel: skill.trustLevel,\n reason: activationDecision.reason,\n message: activationDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: activationDecision.reason,\n message: activationDecision.message,\n };\n }\n }\n\n const policyDecision = evaluateTrustPolicy(\n pathResult.kind === 'success' ? pathResult.canonicalRelativePath : resourcePath,\n skill.trustLevel,\n this.registry.getAllowUntrustedScripts()\n );\n if (!policyDecision.allowed) {\n activationLogger.warn('Skill resource load blocked — trust policy', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: policyDecision.reason,\n message: policyDecision.message,\n };\n }\n\n if (policyDecision.reason !== TrustPolicyReason.NOT_SCRIPT) {\n activationLogger.info('Skill resource trust policy — allowed', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_ALLOWED, {\n name: skill.metadata.name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n });\n }\n\n if (pathResult.kind === 'resource-not-found' || pathResult.kind === 'target-read-failure') {\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: pathResult.error,\n });\n return {\n kind: pathResult.kind === 'resource-not-found' ? 'resource-not-found' : 'read-failure',\n name,\n resourcePath,\n error: pathResult.error,\n };\n }\n\n let content: string;\n try {\n content = readFileSync(pathResult.canonicalPath, 'utf-8');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: message,\n });\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { kind: 'resource-not-found', name, resourcePath, error: message };\n }\n return { kind: 'read-failure', name, resourcePath, error: message };\n }\n\n activationLogger.info('Skill resource loaded', {\n name: skill.metadata.name,\n resourcePath,\n resolvedPath: pathResult.resolvedPath,\n contentLength: content.length,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.SKILL_RESOURCE_LOADED, {\n name: skill.metadata.name,\n resourcePath,\n resolvedPath: pathResult.resolvedPath,\n contentLength: content.length,\n });\n\n return { kind: 'success', content };\n }\n\n async activate(name: string): Promise<SkillActivationResult> {\n const skill = this.registry.get(name);\n if (!skill) {\n const availableNames = this.registry.getNames();\n activationLogger.warn('Skill activation failed — not found', {\n name,\n availableCount: availableNames.length,\n });\n return { kind: 'skill-not-found', name, availableNames };\n }\n\n const policyDecision = evaluateSkillActivationPolicy(skill.trustLevel);\n if (!policyDecision.allowed) {\n activationLogger.warn('Skill activation blocked — trust policy', {\n name,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath: 'SKILL.md',\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: policyDecision.reason,\n message: policyDecision.message,\n };\n }\n\n let body: string;\n try {\n const content = readFileSync(resolve(skill.skillPath, 'SKILL.md'), 'utf-8');\n body = extractBody(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n activationLogger.error('Skill activation failed — read error', {\n name,\n skillPath: skill.skillPath,\n error: message,\n });\n return { kind: 'read-failure', name, error: message };\n }\n\n activationLogger.info('Skill activated', {\n name: skill.metadata.name,\n skillPath: skill.skillPath,\n bodyLength: body.length,\n trustLevel: skill.trustLevel,\n activationReason: policyDecision.reason,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.SKILL_ACTIVATED, {\n name: skill.metadata.name,\n skillPath: skill.skillPath,\n bodyLength: body.length,\n trustLevel: skill.trustLevel,\n });\n\n return { kind: 'success', body };\n }\n}\n","import { z } from 'zod';\n\nexport const activateSkillSchema = z.object({\n name: z.string().describe('The name of the skill to activate (e.g., \"code-review\")'),\n});\n\nexport const readSkillResourceSchema = z.object({\n name: z.string().describe('The name of the skill that owns the resource'),\n path: z.string().describe('Relative path to the resource file within the skill directory (e.g., \"references/GUIDE.md\", \"scripts/setup.sh\")'),\n});\n","import { ToolBuilder, ToolCategory } from '@agentforge/core';\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { AgentSkillAccess } from './agent-skill-access.js';\nimport { activateSkillSchema } from './activation-schemas.js';\nimport { formatMissingSkillMessage } from './activation-shared.js';\n\n/**\n * Create the `activate-skill` tool bound to a registry instance.\n *\n * Resolves the skill by name, reads the full SKILL.md file, and returns\n * the body content (below frontmatter).\n *\n * @param registry - The SkillRegistry to resolve skills from\n * @returns An AgentForge Tool\n */\nexport function createActivateSkillTool(\n registry: SkillRegistry,\n): Tool<z.infer<typeof activateSkillSchema>, string> {\n const access = new AgentSkillAccess(registry);\n\n return new ToolBuilder<z.infer<typeof activateSkillSchema>, string>()\n .name('activate-skill')\n .description(\n 'Activate an Agent Skill by name, loading its full instructions for trusted roots. ' +\n 'Returns the complete SKILL.md body content for workspace or explicitly trusted skills. ' +\n 'Use this when you see a relevant skill in <available_skills> or <untrusted_skills>; ' +\n 'activation is blocked for untrusted roots until they are promoted.',\n )\n .category(ToolCategory.SKILLS)\n .tags(['skill', 'activation', 'agent-skills'])\n .schema(activateSkillSchema)\n .implement(async ({ name }) => {\n const result = await access.activate(name);\n\n switch (result.kind) {\n case 'success':\n return result.body;\n case 'skill-not-found':\n return formatMissingSkillMessage(result.name, result.availableNames);\n case 'access-denied':\n return result.message;\n case 'read-failure':\n return `Failed to read skill \"${result.name}\" instructions: ${result.error}`;\n }\n })\n .build();\n}\n","import { ToolBuilder, ToolCategory } from '@agentforge/core';\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { AgentSkillAccess } from './agent-skill-access.js';\nimport { readSkillResourceSchema } from './activation-schemas.js';\nimport { formatMissingSkillMessage } from './activation-shared.js';\n\n/**\n * Create the `read-skill-resource` tool bound to a registry instance.\n *\n * Resolves the skill by name, validates the resource path (blocking\n * traversal), and returns the file content.\n *\n * @param registry - The SkillRegistry to resolve skills from\n * @returns An AgentForge Tool\n */\nexport function createReadSkillResourceTool(\n registry: SkillRegistry\n): Tool<z.infer<typeof readSkillResourceSchema>, string> {\n const access = new AgentSkillAccess(registry);\n\n return new ToolBuilder<z.infer<typeof readSkillResourceSchema>, string>()\n .name('read-skill-resource')\n .description(\n 'Read a resource file from an activated Agent Skill. ' +\n 'Returns the content of a file within the skill directory (e.g., references/, scripts/, assets/). ' +\n 'The path must be relative to the skill root and cannot traverse outside it. ' +\n 'SKILL.md is only readable from workspace or trusted roots.'\n )\n .category(ToolCategory.SKILLS)\n .tags(['skill', 'resource', 'agent-skills'])\n .schema(readSkillResourceSchema)\n .implement(async ({ name, path: resourcePath }) => {\n const result = await access.readResource(name, resourcePath);\n\n switch (result.kind) {\n case 'success':\n return result.content;\n case 'skill-not-found':\n return formatMissingSkillMessage(result.name, result.availableNames);\n case 'access-denied':\n return result.message;\n case 'resource-not-found':\n case 'read-failure':\n return `Failed to read resource \"${result.resourcePath}\" from skill \"${result.name}\": ${result.error}`;\n }\n })\n .build();\n}\n","import { isAbsolute, relative, resolve } from 'node:path';\nimport { realpathSync } from 'node:fs';\n\n/**\n * Resolve a resource path within a skill root, blocking path traversal.\n *\n * @param skillPath - Absolute path to the skill directory\n * @param resourcePath - Relative path to the resource file\n * @returns A result containing either the resolved absolute path or an error message\n * @deprecated Use the `read-skill-resource` Tool from\n * `SkillRegistry.toActivationTools()` for Agent Skill resource access. This\n * compatibility helper is planned for removal in the next major release.\n */\nexport function resolveResourcePath(\n skillPath: string,\n resourcePath: string,\n): { success: true; resolvedPath: string } | { success: false; error: string } {\n if (isAbsolute(resourcePath)) {\n return { success: false, error: 'Absolute resource paths are not allowed' };\n }\n\n const segments = resourcePath.split(/[/\\\\]/);\n if (segments.some((seg) => seg === '..')) {\n return { success: false, error: 'Path traversal is not allowed — resource paths must stay within the skill directory' };\n }\n\n const resolvedPath = resolve(skillPath, resourcePath);\n const resolvedSkillPath = resolve(skillPath);\n const rel = relative(resolvedSkillPath, resolvedPath);\n if (rel.startsWith('..') || resolve(resolvedSkillPath, rel) !== resolvedPath) {\n return { success: false, error: 'Path traversal is not allowed — resource paths must stay within the skill directory' };\n }\n\n try {\n const realSkillRoot = realpathSync(resolvedSkillPath);\n const realTarget = realpathSync(resolvedPath);\n const realRel = relative(realSkillRoot, realTarget);\n if (realRel.startsWith('..') || isAbsolute(realRel)) {\n return { success: false, error: 'Symlink target escapes the skill directory — access denied' };\n }\n } catch {\n // File doesn't exist yet (or can't be stat'd) — skip symlink check.\n // The caller will produce a clear error if the file is missing.\n }\n\n return { success: true, resolvedPath };\n}\n","/**\n * Agent Skill Access Tools\n *\n * Provides `activate-skill` and `read-skill-resource` tools built with\n * the AgentForge tool builder API. Skill activation makes trusted Agent\n * Skill instructions available; resource access loads supporting files.\n *\n * @see https://agentskills.io/specification\n *\n * @example\n * ```ts\n * const [activateSkill, readSkillResource] = createSkillActivationTools(registry);\n * // activateSkill — load full SKILL.md body\n * // readSkillResource — load a resource file from a skill\n *\n * // Or use the convenience method:\n * const [activateSkill, readSkillResource] = registry.toActivationTools();\n * ```\n */\n\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { createActivateSkillTool } from './activation-activate-tool.js';\nimport { createReadSkillResourceTool } from './activation-resource-tool.js';\nimport type { activateSkillSchema, readSkillResourceSchema } from './activation-schemas.js';\n\nexport { createActivateSkillTool } from './activation-activate-tool.js';\nexport { resolveResourcePath } from './activation-path.js';\nexport { createReadSkillResourceTool } from './activation-resource-tool.js';\n\n/**\n * Create both skill activation tools bound to a registry instance.\n *\n * @param registry - The SkillRegistry to bind tools to\n * @returns Array of both tools [activate-skill, read-skill-resource]\n */\nexport function createSkillActivationTools(\n registry: SkillRegistry,\n): [Tool<z.infer<typeof activateSkillSchema>, string>, Tool<z.infer<typeof readSkillResourceSchema>, string>] {\n return [\n createActivateSkillTool(registry),\n createReadSkillResourceTool(registry),\n ];\n}\n","import { resolve as resolvePath } from 'node:path';\nimport { createLogger, LogLevel } from '@agentforge/core';\nimport { parseSkillContent } from './parser.js';\nimport { scanAllSkillRoots, expandHome } from './scanner.js';\nimport { normalizeRootConfig } from './trust.js';\nimport type { Skill, SkillRegistryConfig, TrustLevel } from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport type { RegistryEmit, ScanError } from './registry-internal.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function discoverSkills(\n config: Pick<SkillRegistryConfig, 'skillRoots'>,\n skills: Map<string, Skill>,\n rootTrustMap: Map<string, TrustLevel>,\n emit: RegistryEmit,\n): ScanError[] {\n skills.clear();\n rootTrustMap.clear();\n const scanErrors: ScanError[] = [];\n\n const normalizedRoots = config.skillRoots.map(normalizeRootConfig);\n const plainPaths = normalizedRoots.map((root) => root.path);\n\n for (const root of normalizedRoots) {\n const resolvedPath = resolvePath(expandHome(root.path));\n rootTrustMap.set(resolvedPath, root.trust);\n }\n\n const candidates = scanAllSkillRoots(plainPaths);\n\n let successCount = 0;\n let warningCount = 0;\n\n for (const candidate of candidates) {\n const result = parseSkillContent(candidate.content, candidate.dirName);\n\n if (!result.success) {\n warningCount++;\n recordScanError(scanErrors, candidate.skillPath, result.error || 'Unknown parse error');\n emit(SkillRegistryEvent.SKILL_WARNING, {\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n error: result.error,\n });\n logger.warn('Skipping invalid skill', {\n skillPath: candidate.skillPath,\n ...(result.error ? { error: result.error } : {}),\n });\n continue;\n }\n\n const skill: Skill = {\n metadata: result.metadata!,\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n trustLevel: rootTrustMap.get(candidate.rootPath) ?? 'untrusted',\n };\n\n if (skills.has(skill.metadata.name)) {\n warningCount++;\n const existing = skills.get(skill.metadata.name)!;\n const warningMessage =\n `Duplicate skill name \"${skill.metadata.name}\" from \"${candidate.rootPath}\" — ` +\n `keeping version from \"${existing.rootPath}\" (first root takes precedence)`;\n\n recordScanError(scanErrors, candidate.skillPath, warningMessage);\n emit(SkillRegistryEvent.SKILL_WARNING, {\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n duplicateOf: existing.skillPath,\n error: warningMessage,\n });\n logger.warn('Duplicate skill name, keeping first', {\n name: skill.metadata.name,\n kept: existing.skillPath,\n skipped: candidate.skillPath,\n });\n continue;\n }\n\n skills.set(skill.metadata.name, skill);\n successCount++;\n emit(SkillRegistryEvent.SKILL_DISCOVERED, skill);\n logger.debug('Skill discovered', {\n name: skill.metadata.name,\n description: skill.metadata.description.slice(0, 80),\n skillPath: skill.skillPath,\n });\n }\n\n logger.info('Skill registry populated', {\n rootsScanned: config.skillRoots.length,\n skillsDiscovered: successCount,\n warnings: warningCount,\n });\n\n return scanErrors;\n}\n\nfunction recordScanError(scanErrors: ScanError[], path: string, error: string): void {\n scanErrors.push({ path, error });\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\nimport type { SkillEventHandler } from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport type { RegistryEventHandlers } from './registry-internal.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function addRegistryEventHandler(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n handler: SkillEventHandler,\n): void {\n if (!eventHandlers.has(event)) {\n eventHandlers.set(event, new Set());\n }\n\n eventHandlers.get(event)!.add(handler);\n}\n\nexport function removeRegistryEventHandler(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n handler: SkillEventHandler,\n): void {\n const handlers = eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n }\n}\n\nexport function emitRegistryEvent(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n data: unknown,\n): void {\n const handlers = eventHandlers.get(event);\n if (!handlers) {\n return;\n }\n\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n logger.error('Skill event handler error', {\n event,\n error: error instanceof Error ? error.message : String(error),\n ...(error instanceof Error && error.stack ? { stack: error.stack } : {}),\n });\n }\n });\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\nimport type { Skill, SkillPromptOptions, SkillRegistryConfig } from './types.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function generateSkillPrompt(\n config: SkillRegistryConfig,\n allSkills: Skill[],\n totalDiscovered: number,\n options?: SkillPromptOptions,\n): string {\n if (!config.enabled) {\n logger.debug('Skill prompt generation skipped (disabled)', {\n enabled: config.enabled ?? false,\n });\n return '';\n }\n\n let skills = allSkills;\n\n if (options?.skills && options.skills.length > 0) {\n const requested = new Set(options.skills);\n skills = skills.filter((skill) => requested.has(skill.metadata.name));\n }\n\n let trustedSkills = skills.filter(\n (skill) => skill.trustLevel === 'workspace' || skill.trustLevel === 'trusted',\n );\n let untrustedSkills = skills.filter(\n (skill) => skill.trustLevel !== 'workspace' && skill.trustLevel !== 'trusted',\n );\n\n if (config.maxDiscoveredSkills !== undefined && config.maxDiscoveredSkills >= 0) {\n const trustedLimit = Math.min(config.maxDiscoveredSkills, trustedSkills.length);\n trustedSkills = trustedSkills.slice(0, trustedLimit);\n untrustedSkills = untrustedSkills.slice(0, config.maxDiscoveredSkills - trustedLimit);\n skills = [...trustedSkills, ...untrustedSkills];\n }\n\n if (trustedSkills.length === 0 && untrustedSkills.length === 0) {\n logger.debug('Skill prompt generation produced empty result', {\n totalDiscovered,\n filterApplied: !!(options?.skills && options.skills.length > 0),\n ...(config.maxDiscoveredSkills !== undefined\n ? { maxCap: config.maxDiscoveredSkills }\n : {}),\n });\n return '';\n }\n\n const sections: string[] = [];\n\n if (trustedSkills.length > 0) {\n sections.push(`<available_skills>\\n${trustedSkills.map(renderTrustedSkillEntry).join('\\n')}\\n</available_skills>`);\n }\n\n if (untrustedSkills.length > 0) {\n sections.push(renderUntrustedSkillsSection(untrustedSkills));\n }\n\n const xml = sections.join('\\n');\n const estimatedTokens = Math.ceil(xml.length / 4);\n\n logger.info('Skill prompt generated', {\n skillCount: skills.length,\n trustedSkillCount: trustedSkills.length,\n untrustedSkillCount: untrustedSkills.length,\n totalDiscovered,\n filterApplied: !!(options?.skills && options.skills.length > 0),\n ...(config.maxDiscoveredSkills !== undefined ? { maxCap: config.maxDiscoveredSkills } : {}),\n estimatedTokens,\n xmlLength: xml.length,\n });\n\n return xml;\n}\n\nfunction renderTrustedSkillEntry(skill: Skill): string {\n return [\n ' <skill>',\n ` <name>${escapeXml(skill.metadata.name)}</name>`,\n ` <description>${escapeXml(skill.metadata.description)}</description>`,\n ` <location>${escapeXml(skill.skillPath)}</location>`,\n ` <trust>${escapeXml(skill.trustLevel)}</trust>`,\n ' </skill>',\n ].join('\\n');\n}\n\nfunction renderUntrustedSkillsSection(skills: Skill[]): string {\n return [\n '<untrusted_skills>',\n ' <trust_notice>Untrusted skills are discoverable, but their full SKILL.md bodies stay blocked until the root is promoted to trusted or workspace status.</trust_notice>',\n ...skills.map(renderUntrustedSkillEntry),\n '</untrusted_skills>',\n ].join('\\n');\n}\n\nfunction renderUntrustedSkillEntry(skill: Skill): string {\n return [\n ' <skill>',\n ` <name>${escapeXml(skill.metadata.name)}</name>`,\n ` <description>${escapeXml(skill.metadata.description)}</description>`,\n ` <location>${escapeXml(skill.skillPath)}</location>`,\n ` <trust>${escapeXml(skill.trustLevel)}</trust>`,\n ' <activation_policy>requires-trusted-root</activation_policy>',\n ' </skill>',\n ].join('\\n');\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n","import type { Skill } from './types.js';\nimport type { ScanError } from './registry-internal.js';\n\nexport function getSkill(skills: Map<string, Skill>, name: string): Skill | undefined {\n return skills.get(name);\n}\n\nexport function getAllSkills(skills: Map<string, Skill>): Skill[] {\n return Array.from(skills.values());\n}\n\nexport function hasSkill(skills: Map<string, Skill>, name: string): boolean {\n return skills.has(name);\n}\n\nexport function getSkillCount(skills: Map<string, Skill>): number {\n return skills.size;\n}\n\nexport function getSkillNames(skills: Map<string, Skill>): string[] {\n return Array.from(skills.keys());\n}\n\nexport function getScanErrors(scanErrors: ScanError[]): ReadonlyArray<ScanError> {\n return scanErrors;\n}\n\nexport function getAllowedTools(skills: Map<string, Skill>, name: string): string[] | undefined {\n return skills.get(name)?.metadata.allowedTools;\n}\n","import type {\n Skill,\n SkillEventHandler,\n SkillPromptOptions,\n SkillRegistryConfig,\n TrustLevel,\n} from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport { createSkillActivationTools } from './activation.js';\nimport { discoverSkills } from './registry-discovery.js';\nimport {\n addRegistryEventHandler,\n emitRegistryEvent,\n removeRegistryEventHandler,\n} from './registry-events.js';\nimport type { RegistryEventHandlers } from './registry-internal.js';\nimport { generateSkillPrompt } from './registry-prompt.js';\nimport {\n getAllSkills,\n getAllowedTools,\n getScanErrors,\n getSkill,\n getSkillCount,\n getSkillNames,\n hasSkill,\n} from './registry-query-api.js';\n\nexport class SkillRegistry {\n private skills: Map<string, Skill> = new Map();\n private eventHandlers: RegistryEventHandlers = new Map();\n private readonly config: SkillRegistryConfig;\n private scanErrors: Array<{ path: string; error: string }> = [];\n private rootTrustMap: Map<string, TrustLevel> = new Map();\n\n constructor(config: SkillRegistryConfig) {\n this.config = config;\n this.discover();\n }\n\n discover(): void {\n this.scanErrors = discoverSkills(this.config, this.skills, this.rootTrustMap, (event, data) => {\n this.emit(event, data);\n });\n }\n\n get(name: string): Skill | undefined {\n return getSkill(this.skills, name);\n }\n\n getAll(): Skill[] {\n return getAllSkills(this.skills);\n }\n\n has(name: string): boolean {\n return hasSkill(this.skills, name);\n }\n\n size(): number {\n return getSkillCount(this.skills);\n }\n\n getNames(): string[] {\n return getSkillNames(this.skills);\n }\n\n getScanErrors(): ReadonlyArray<{ path: string; error: string }> {\n return getScanErrors(this.scanErrors);\n }\n\n getAllowUntrustedScripts(): boolean {\n return this.config.allowUntrustedScripts ?? false;\n }\n\n getAllowedTools(name: string): string[] | undefined {\n return getAllowedTools(this.skills, name);\n }\n\n generatePrompt(options?: SkillPromptOptions): string {\n return generateSkillPrompt(this.config, this.getAll(), this.size(), options);\n }\n\n on(event: SkillRegistryEvent, handler: SkillEventHandler): void {\n addRegistryEventHandler(this.eventHandlers, event, handler);\n }\n\n off(event: SkillRegistryEvent, handler: SkillEventHandler): void {\n removeRegistryEventHandler(this.eventHandlers, event, handler);\n }\n\n emitEvent(event: SkillRegistryEvent, data: unknown): void {\n this.emit(event, data);\n }\n\n toActivationTools(): ReturnType<typeof createSkillActivationTools> {\n return createSkillActivationTools(this);\n }\n\n private emit(event: SkillRegistryEvent, data: unknown): void {\n emitRegistryEvent(this.eventHandlers, event, data);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/parser.ts","../src/scanner.ts","../src/activation-content.ts","../src/activation-shared.ts","../src/trust.ts","../src/agent-skill-access.ts","../src/activation-schemas.ts","../src/activation-activate-tool.ts","../src/activation-resource-tool.ts","../src/activation-path.ts","../src/activation.ts","../src/registry-discovery.ts","../src/registry-events.ts","../src/registry-prompt.ts","../src/registry.ts"],"names":["TrustPolicyReason","SkillRegistryEvent","matter","createLogger","LogLevel","resolve","readFileSync","ToolBuilder","ToolCategory","isAbsolute","relative","realpathSync","logger","resolvePath"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Skill System Types\n *\n * Core type definitions for the AgentForge Agent Skills system.\n * These types align with the Agent Skills specification (https://agentskills.io/specification).\n */\n\n// ─── Trust Policy Types ──────────────────────────────────────────────────\n\n/**\n * Trust level for a skill root directory.\n *\n * - `workspace` — Skills from the project workspace (highest trust, scripts allowed)\n * - `trusted` — Explicitly trusted skill roots (scripts allowed)\n * - `untrusted` — Untrusted roots like community packs (scripts blocked by default)\n */\nexport type TrustLevel = 'workspace' | 'trusted' | 'untrusted';\n\n/**\n * Configuration for a skill root with an explicit trust level.\n *\n * @example\n * ```ts\n * const roots: SkillRootConfig[] = [\n * { path: '.agentskills', trust: 'workspace' },\n * { path: '~/.agentskills', trust: 'trusted' },\n * { path: '/shared/community-skills', trust: 'untrusted' },\n * ];\n * ```\n */\nexport interface SkillRootConfig {\n /** Directory path to scan for skills */\n path: string;\n /** Trust level assigned to all skills discovered from this root */\n trust: TrustLevel;\n}\n\n/**\n * Policy decision returned by trust enforcement checks.\n */\nexport interface TrustPolicyDecision {\n /** Whether the action is allowed */\n allowed: boolean;\n /** Machine-readable reason code for auditing */\n reason: TrustPolicyReason;\n /** Human-readable explanation */\n message: string;\n}\n\n/**\n * Reason codes for trust policy decisions.\n *\n * Used for structured logging and auditing of guardrail behavior.\n */\nexport enum TrustPolicyReason {\n /** Resource is not a script — no trust check needed */\n NOT_SCRIPT = 'not-script',\n /** Skill root has workspace trust — scripts allowed */\n WORKSPACE_TRUST = 'workspace-trust',\n /** Skill root has explicit trusted status — scripts allowed */\n TRUSTED_ROOT = 'trusted-root',\n /** Skill body activation allowed because the root is workspace-owned */\n WORKSPACE_SKILL_ACTIVATION = 'workspace-skill-activation',\n /** Skill body activation allowed because the root is explicitly trusted */\n TRUSTED_SKILL_ACTIVATION = 'trusted-skill-activation',\n /** Full skill-body activation denied for an untrusted root */\n UNTRUSTED_SKILL_ACTIVATION_DENIED = 'untrusted-skill-activation-denied',\n /** Skill root is untrusted — scripts denied by default */\n UNTRUSTED_SCRIPT_DENIED = 'untrusted-script-denied',\n /** Untrusted script access was explicitly allowed via config override */\n UNTRUSTED_SCRIPT_ALLOWED = 'untrusted-script-allowed-override',\n /** Trust level is unknown — treated as untrusted for security */\n UNKNOWN_TRUST_LEVEL = 'unknown-trust-level',\n}\n\n/**\n * Parsed metadata from a SKILL.md frontmatter block.\n *\n * Required fields: `name`, `description`.\n * All other fields are optional per the Agent Skills spec.\n */\nexport interface SkillMetadata {\n /** Skill name (1-64 chars, lowercase alphanumeric + hyphens, must match parent dir name) */\n name: string;\n /** Human-readable description (1-1024 chars) */\n description: string;\n /** SPDX license identifier */\n license?: string;\n /** List of compatible agent frameworks / tool hosts */\n compatibility?: string[];\n /** Arbitrary key-value metadata (author, version, etc.) */\n metadata?: Record<string, unknown>;\n /** Tools that this skill is allowed to use */\n allowedTools?: string[];\n}\n\n/**\n * A fully resolved skill entry in the registry.\n *\n * Contains parsed metadata plus internal tracking fields\n * that are not part of the SKILL.md frontmatter.\n */\nexport interface Skill {\n /** Parsed frontmatter metadata */\n metadata: SkillMetadata;\n /** Absolute path to the skill directory */\n skillPath: string;\n /** Which configured skill root this was discovered from */\n rootPath: string;\n /** Trust level assigned to this skill (inherited from root config) */\n trustLevel: TrustLevel;\n}\n\n/**\n * Configuration for the SkillRegistry.\n */\nexport interface SkillRegistryConfig {\n /**\n * Array of directory paths to scan for skills.\n *\n * Each entry can be a plain string (defaults to `'untrusted'` trust level)\n * or a `SkillRootConfig` object with an explicit trust level.\n *\n * Paths may be absolute or relative (resolved against `cwd`).\n * The `~` prefix is expanded to `$HOME`.\n *\n * @example\n * ```ts\n * // Simple string roots (default to 'untrusted')\n * skillRoots: ['.agentskills', '~/.agentskills']\n *\n * // Trust-aware roots\n * skillRoots: [\n * { path: '.agentskills', trust: 'workspace' },\n * { path: '~/.agentskills', trust: 'trusted' },\n * { path: '/shared/community', trust: 'untrusted' },\n * ]\n * ```\n */\n skillRoots: Array<string | SkillRootConfig>;\n\n /**\n * Feature flag to enable Agent Skills in system prompts.\n *\n * When `false` (default), `generatePrompt()` returns an empty string\n * so agents operate with unmodified system prompts.\n *\n * @default false\n */\n enabled?: boolean;\n\n /**\n * Maximum number of skills to include in generated prompts.\n *\n * Caps prompt token usage when many skills are discovered.\n * Skills are included in discovery order (first root first).\n * When undefined, all discovered skills are included.\n */\n maxDiscoveredSkills?: number;\n\n /**\n * Allow script resources from untrusted roots.\n *\n * When `true`, scripts from `scripts/` directories in untrusted\n * skill roots are returned instead of being denied. This disables\n * the default-deny policy for untrusted scripts.\n *\n * **Security warning:** Only enable when you have reviewed all\n * skill packs from untrusted roots.\n *\n * @default false\n */\n allowUntrustedScripts?: boolean;\n}\n\n/**\n * Options for `SkillRegistry.generatePrompt()`.\n */\nexport interface SkillPromptOptions {\n /**\n * Subset of skill names to include in the generated prompt.\n *\n * When provided, only skills matching these names appear in the\n * `<available_skills>` XML block. This enables creating focused\n * agents with different skill sets from the same registry.\n *\n * When omitted or empty, all discovered skills are included.\n *\n * @example ['code-review', 'testing-strategy']\n */\n skills?: string[];\n}\n\n/**\n * Events emitted by the SkillRegistry during discovery and usage.\n */\nexport enum SkillRegistryEvent {\n /** Emitted when a valid skill is discovered during scanning */\n SKILL_DISCOVERED = 'skill:discovered',\n /** Emitted when a skill parse or validation issue is encountered */\n SKILL_WARNING = 'skill:warning',\n /** Emitted when a skill is activated (full body loaded) */\n SKILL_ACTIVATED = 'skill:activated',\n /** Emitted when a skill resource file is loaded */\n SKILL_RESOURCE_LOADED = 'skill:resource-loaded',\n /** Emitted when a trust policy denies access to a resource */\n TRUST_POLICY_DENIED = 'trust:policy-denied',\n /** Emitted when a trust policy allows access (for auditing) */\n TRUST_POLICY_ALLOWED = 'trust:policy-allowed',\n}\n\n/**\n * Event handler type for skill registry events.\n */\nexport type SkillEventHandler = (data: unknown) => void;\n\n/**\n * Result of parsing a single SKILL.md file.\n */\nexport interface SkillParseResult {\n /** Whether parsing and validation succeeded */\n success: boolean;\n /** Parsed metadata (present when success is true) */\n metadata?: SkillMetadata;\n /** The raw markdown body below the frontmatter (present when success is true) */\n body?: string;\n /** Error description (present when success is false) */\n error?: string;\n}\n\n/**\n * Validation error detail.\n */\nexport interface SkillValidationError {\n /** Which field failed validation */\n field: string;\n /** Human-readable error message */\n message: string;\n}\n","/**\n * SKILL.md Frontmatter Parser\n *\n * Parses YAML frontmatter from SKILL.md files and validates\n * against the Agent Skills specification constraints.\n *\n * @see https://agentskills.io/specification\n */\n\nimport matter from 'gray-matter';\nimport type { SkillMetadata, SkillParseResult, SkillValidationError } from './types.js';\n\n/**\n * Skill name validation constraints (per spec).\n *\n * - 1-64 characters\n * - Lowercase alphanumeric and hyphens only\n * - No leading, trailing, or consecutive hyphens\n */\nconst SKILL_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\nconst SKILL_NAME_MAX_LENGTH = 64;\nconst SKILL_DESCRIPTION_MAX_LENGTH = 1024;\n\n/**\n * Validate the `name` field per the Agent Skills spec.\n *\n * @param name - The name value from frontmatter\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillName(name: unknown): SkillValidationError[] {\n const errors: SkillValidationError[] = [];\n\n if (name === undefined || name === null) {\n errors.push({ field: 'name', message: 'name is required' });\n return errors;\n }\n\n if (typeof name !== 'string') {\n errors.push({ field: 'name', message: 'name must be a string' });\n return errors;\n }\n\n if (name.length === 0) {\n errors.push({ field: 'name', message: 'name must not be empty' });\n return errors;\n }\n\n if (name.length > SKILL_NAME_MAX_LENGTH) {\n errors.push({\n field: 'name',\n message: `name must be at most ${SKILL_NAME_MAX_LENGTH} characters (got ${name.length})`,\n });\n return errors;\n }\n\n if (!SKILL_NAME_PATTERN.test(name)) {\n errors.push({\n field: 'name',\n message: 'name must be lowercase alphanumeric with hyphens, no leading/trailing/consecutive hyphens',\n });\n }\n\n if (name.includes('--')) {\n errors.push({\n field: 'name',\n message: 'name must not contain consecutive hyphens',\n });\n }\n\n return errors;\n}\n\n/**\n * Validate the `description` field per the Agent Skills spec.\n *\n * @param description - The description value from frontmatter\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillDescription(description: unknown): SkillValidationError[] {\n const errors: SkillValidationError[] = [];\n\n if (description === undefined || description === null) {\n errors.push({ field: 'description', message: 'description is required' });\n return errors;\n }\n\n if (typeof description !== 'string') {\n errors.push({ field: 'description', message: 'description must be a string' });\n return errors;\n }\n\n if (description.trim().length === 0) {\n errors.push({ field: 'description', message: 'description must not be empty' });\n return errors;\n }\n\n if (description.length > SKILL_DESCRIPTION_MAX_LENGTH) {\n errors.push({\n field: 'description',\n message: `description must be at most ${SKILL_DESCRIPTION_MAX_LENGTH} characters (got ${description.length})`,\n });\n }\n\n return errors;\n}\n\n/**\n * Validate that the skill name matches its parent directory name (per spec).\n *\n * @param name - The name from frontmatter\n * @param dirName - The parent directory name\n * @returns Array of validation errors (empty = valid)\n */\nexport function validateSkillNameMatchesDir(name: string, dirName: string): SkillValidationError[] {\n if (name !== dirName) {\n return [{\n field: 'name',\n message: `name \"${name}\" must match parent directory name \"${dirName}\"`,\n }];\n }\n return [];\n}\n\n/**\n * Parse and validate a SKILL.md file's raw content.\n *\n * Extracts YAML frontmatter using gray-matter, then validates\n * required and optional fields against spec constraints.\n *\n * @param content - Raw file content of the SKILL.md\n * @param dirName - Parent directory name for name-match validation\n * @returns Parse result with metadata or error\n */\nexport function parseSkillContent(content: string, dirName: string): SkillParseResult {\n let parsed: matter.GrayMatterFile<string>;\n\n try {\n parsed = matter(content);\n } catch (err) {\n return {\n success: false,\n error: `Failed to parse frontmatter: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n const data = parsed.data;\n\n // Validate required fields\n const errors: SkillValidationError[] = [\n ...validateSkillName(data.name),\n ...validateSkillDescription(data.description),\n ];\n\n // If name is valid, validate it matches directory name\n if (typeof data.name === 'string' && data.name.length > 0 && SKILL_NAME_PATTERN.test(data.name)) {\n errors.push(...validateSkillNameMatchesDir(data.name, dirName));\n }\n\n if (errors.length > 0) {\n return {\n success: false,\n error: errors.map((e) => `${e.field}: ${e.message}`).join('; '),\n };\n }\n\n // Build metadata from validated fields\n const metadata: SkillMetadata = {\n name: data.name as string,\n description: data.description as string,\n };\n\n // Optional fields\n if (data.license !== undefined) {\n metadata.license = String(data.license);\n }\n\n if (Array.isArray(data.compatibility)) {\n metadata.compatibility = data.compatibility.map(String);\n }\n\n if (data.metadata !== undefined && typeof data.metadata === 'object' && data.metadata !== null) {\n metadata.metadata = data.metadata as Record<string, unknown>;\n }\n\n if (Array.isArray(data['allowed-tools'])) {\n metadata.allowedTools = data['allowed-tools'].map(String);\n }\n\n return {\n success: true,\n metadata,\n body: parsed.content,\n };\n}\n","/**\n * Skill Directory Scanner\n *\n * Scans configured skill roots for directories containing valid SKILL.md files.\n * Returns a list of candidate skill paths for the parser to process.\n */\n\nimport { existsSync, readdirSync, statSync, readFileSync } from 'node:fs';\nimport { resolve, basename } from 'node:path';\nimport { homedir } from 'node:os';\nimport { createLogger, LogLevel } from '@agentforge/core';\n\nconst logger = createLogger('agentforge:skills:scanner', { level: LogLevel.INFO });\n\n/**\n * Discovered skill candidate — a directory containing a SKILL.md file.\n */\nexport interface SkillCandidate {\n /** Absolute path to the skill directory */\n skillPath: string;\n /** The parent directory name (expected to match the skill name) */\n dirName: string;\n /** Raw content of the SKILL.md file */\n content: string;\n /** Which configured root this came from */\n rootPath: string;\n}\n\n/**\n * Expand `~` prefix to the user's home directory.\n */\nexport function expandHome(p: string): string {\n if (p.startsWith('~/') || p === '~') {\n return resolve(homedir(), p.slice(2));\n }\n return p;\n}\n\n/**\n * Scan a single skill root for directories containing SKILL.md.\n *\n * @param rootPath - The root directory to scan (may not exist)\n * @returns Array of valid skill candidates found under this root\n */\nexport function scanSkillRoot(rootPath: string): SkillCandidate[] {\n const resolvedRoot = resolve(expandHome(rootPath));\n const candidates: SkillCandidate[] = [];\n\n if (!existsSync(resolvedRoot)) {\n logger.debug('Skill root does not exist, skipping', { rootPath: resolvedRoot });\n return candidates;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(resolvedRoot);\n } catch (err) {\n logger.warn('Failed to read skill root directory', {\n rootPath: resolvedRoot,\n error: err instanceof Error ? err.message : String(err),\n });\n return candidates;\n }\n\n for (const entry of entries) {\n const entryPath = resolve(resolvedRoot, entry);\n\n // Only process directories\n let stat;\n try {\n stat = statSync(entryPath);\n } catch {\n continue;\n }\n if (!stat.isDirectory()) {\n continue;\n }\n\n // Check for SKILL.md inside the directory\n const skillMdPath = resolve(entryPath, 'SKILL.md');\n if (!existsSync(skillMdPath)) {\n continue;\n }\n\n // Read the SKILL.md content\n try {\n const content = readFileSync(skillMdPath, 'utf-8');\n candidates.push({\n skillPath: entryPath,\n dirName: basename(entryPath),\n content,\n rootPath: resolvedRoot,\n });\n } catch (err) {\n logger.warn('Failed to read SKILL.md', {\n path: skillMdPath,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n logger.debug('Scanned skill root', {\n rootPath: resolvedRoot,\n candidatesFound: candidates.length,\n });\n\n return candidates;\n}\n\n/**\n * Scan multiple skill roots for directories containing SKILL.md.\n *\n * @param skillRoots - Array of root paths to scan\n * @returns Array of all skill candidates found across all roots\n */\nexport function scanAllSkillRoots(skillRoots: string[]): SkillCandidate[] {\n const allCandidates: SkillCandidate[] = [];\n\n for (const root of skillRoots) {\n const candidates = scanSkillRoot(root);\n allCandidates.push(...candidates);\n }\n\n logger.info('Skill discovery complete', {\n rootsScanned: skillRoots.length,\n totalCandidates: allCandidates.length,\n });\n\n return allCandidates;\n}\n","import matter from 'gray-matter';\n\n/**\n * Extract the body content below YAML frontmatter from a SKILL.md file.\n *\n * Delegates to `gray-matter` for consistent frontmatter handling across\n * the codebase (matches `parseSkillContent()` in parser.ts).\n *\n * @param content - The full SKILL.md file content\n * @returns The body content below the frontmatter\n */\nexport function extractBody(content: string): string {\n return matter(content).content.trim();\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\n\nexport const activationLogger = createLogger('agentforge:skills:activation', {\n level: LogLevel.INFO,\n});\n\nexport function formatMissingSkillMessage(name: string, availableNames: string[]): string {\n const suggestion = availableNames.length > 0\n ? ` Available skills: ${availableNames.join(', ')}`\n : ' No skills are currently registered.';\n\n return `Skill \"${name}\" not found.${suggestion}`;\n}\n","/**\n * Skill Trust Policy Engine\n *\n * Enforces trust-level-based access control for skill resources.\n * Scripts from untrusted roots are denied by default unless explicitly allowed.\n *\n * Trust levels:\n * - `workspace` — Project-local skills, highest trust. Scripts always allowed.\n * - `trusted` — Explicitly trusted roots. Scripts allowed.\n * - `untrusted` — Community or third-party skills. Scripts denied by default.\n *\n * @see https://agentskills.io/specification\n */\n\nimport type { TrustLevel, TrustPolicyDecision, SkillRootConfig } from './types.js';\nimport { TrustPolicyReason } from './types.js';\n\n// ─── Constants ───────────────────────────────────────────────────────────\n\n/**\n * Resource path prefix that requires trust enforcement.\n *\n * Only resources under `scripts/` are subject to trust policy checks.\n * Other directories (references/, assets/, etc.) are always accessible.\n */\nconst SCRIPT_PATH_PREFIX = 'scripts/';\nconst SCRIPT_PATH_EXACT = 'scripts';\n\n// ─── Helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Normalize a skill root config entry.\n *\n * String entries default to `'untrusted'` trust level for safe defaults.\n *\n * @param root - A string path or SkillRootConfig object\n * @returns Normalized SkillRootConfig with explicit trust level\n */\nexport function normalizeRootConfig(root: string | SkillRootConfig): SkillRootConfig {\n if (typeof root === 'string') {\n return { path: root, trust: 'untrusted' };\n }\n return root;\n}\n\n/**\n * Check whether a resource path refers to a script.\n *\n * A resource is considered a script if its relative path starts with\n * `scripts/` or is exactly `scripts`, after normalizing path separators,\n * stripping leading \"./\" segments, and ignoring case.\n *\n * @param resourcePath - Relative path within the skill directory\n * @returns True if the resource is in the scripts/ directory\n */\nexport function isScriptResource(resourcePath: string): boolean {\n // Normalize to forward slashes and trim for consistent checking\n let normalized = resourcePath.trim().replace(/\\\\/g, '/');\n\n // Collapse repeated separators (e.g., \"scripts//setup.sh\" → \"scripts/setup.sh\")\n normalized = normalized.replace(/\\/+/g, '/');\n\n // Strip leading \"./\" segments (e.g., \"./scripts/setup.sh\" → \"scripts/setup.sh\")\n while (normalized.startsWith('./')) {\n normalized = normalized.slice(2);\n }\n\n // Case-insensitive comparison to handle case-insensitive file systems\n const lower = normalized.toLowerCase();\n\n return lower === SCRIPT_PATH_EXACT\n || lower.startsWith(SCRIPT_PATH_PREFIX);\n}\n\n// ─── Policy Engine ───────────────────────────────────────────────────────\n\n/**\n * Evaluate the trust policy for a resource access request.\n *\n * Non-script resources are allowed regardless of trust level, except for\n * SKILL.md, which is protected by the activation policy.\n * Script resources require `workspace` or `trusted` trust, or the\n * `allowUntrustedScripts` override to be enabled.\n *\n * @param resourcePath - Relative path to the resource within the skill directory\n * @param trustLevel - Trust level of the skill's root directory\n * @param allowUntrustedScripts - Override flag to permit untrusted scripts\n * @returns Policy decision with allow/deny, reason code, and message\n */\nexport function evaluateTrustPolicy(\n resourcePath: string,\n trustLevel: TrustLevel,\n allowUntrustedScripts: boolean = false,\n): TrustPolicyDecision {\n // Non-script resources — SKILL.md is checked separately by the resource tool.\n if (!isScriptResource(resourcePath)) {\n return {\n allowed: true,\n reason: TrustPolicyReason.NOT_SCRIPT,\n message: 'Resource is not a script — no trust check required',\n };\n }\n\n // Script resources — check trust level\n switch (trustLevel) {\n case 'workspace':\n return {\n allowed: true,\n reason: TrustPolicyReason.WORKSPACE_TRUST,\n message: 'Script allowed — skill root has workspace trust',\n };\n\n case 'trusted':\n return {\n allowed: true,\n reason: TrustPolicyReason.TRUSTED_ROOT,\n message: 'Script allowed — skill root is explicitly trusted',\n };\n\n case 'untrusted':\n if (allowUntrustedScripts) {\n return {\n allowed: true,\n reason: TrustPolicyReason.UNTRUSTED_SCRIPT_ALLOWED,\n message: 'Script from untrusted root allowed via allowUntrustedScripts override',\n };\n }\n return {\n allowed: false,\n reason: TrustPolicyReason.UNTRUSTED_SCRIPT_DENIED,\n message: `Script access denied — skill root is untrusted. ` +\n `Scripts from untrusted roots are blocked by default for security. ` +\n `To allow, set 'allowUntrustedScripts: true' in SkillRegistryConfig or ` +\n `promote the skill root to 'trusted' or 'workspace' trust level.`,\n };\n\n default:\n return {\n allowed: false,\n reason: TrustPolicyReason.UNKNOWN_TRUST_LEVEL,\n message: `Script access denied — trust level \"${trustLevel}\" is unknown and is treated as untrusted for security.`,\n };\n }\n}\n\n/**\n * Evaluate whether the full SKILL.md body can be exposed through activation.\n *\n * Untrusted roots stay discoverable, but their full instruction bodies are\n * blocked until the operator explicitly promotes that root to `trusted` or\n * `workspace`.\n */\nexport function evaluateSkillActivationPolicy(trustLevel: TrustLevel): TrustPolicyDecision {\n switch (trustLevel) {\n case 'workspace':\n return {\n allowed: true,\n reason: TrustPolicyReason.WORKSPACE_SKILL_ACTIVATION,\n message: 'Skill activation allowed — skill root has workspace trust',\n };\n\n case 'trusted':\n return {\n allowed: true,\n reason: TrustPolicyReason.TRUSTED_SKILL_ACTIVATION,\n message: 'Skill activation allowed — skill root is explicitly trusted',\n };\n\n case 'untrusted':\n return {\n allowed: false,\n reason: TrustPolicyReason.UNTRUSTED_SKILL_ACTIVATION_DENIED,\n message: `Skill activation blocked — skill root is untrusted. ` +\n `Untrusted skills remain discoverable, but their full SKILL.md bodies are blocked by default. ` +\n `Promote the skill root to 'trusted' or 'workspace' trust level after review to allow activation.`,\n };\n\n default:\n return {\n allowed: false,\n reason: TrustPolicyReason.UNKNOWN_TRUST_LEVEL,\n message: `Skill activation blocked — trust level \"${trustLevel}\" is unknown and is treated as untrusted for security.`,\n };\n }\n}\n","import { readFileSync, realpathSync } from 'node:fs';\nimport { isAbsolute, relative, resolve } from 'node:path';\nimport type { SkillRegistry } from './registry.js';\nimport { SkillRegistryEvent, TrustPolicyReason } from './types.js';\nimport { extractBody } from './activation-content.js';\nimport { activationLogger } from './activation-shared.js';\nimport { evaluateSkillActivationPolicy, evaluateTrustPolicy } from './trust.js';\n\nconst PATH_TRAVERSAL_MESSAGE =\n 'Path traversal is not allowed — resource paths must stay within the skill directory';\nconst SYMLINK_ESCAPE_MESSAGE = 'Symlink target escapes the skill directory — access denied';\n\ntype CanonicalResourcePathResult =\n | {\n kind: 'success';\n resolvedPath: string;\n canonicalPath: string;\n canonicalRelativePath: string;\n }\n | { kind: 'access-denied'; message: string }\n | { kind: 'resource-not-found'; resolvedPath: string; error: string }\n | { kind: 'target-read-failure'; resolvedPath: string; error: string }\n | { kind: 'read-failure'; error: string };\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction formatResourceReadError(error: unknown, resolvedPath: string): string {\n const message = formatError(error);\n const detailIndex = message.indexOf(', ');\n const prefix = detailIndex === -1 ? message : message.slice(0, detailIndex);\n return `${prefix}, open '${resolvedPath}'`;\n}\n\nfunction resolveCanonicalResourcePath(\n skillPath: string,\n resourcePath: string\n): CanonicalResourcePathResult {\n if (isAbsolute(resourcePath)) {\n return { kind: 'access-denied', message: 'Absolute resource paths are not allowed' };\n }\n\n if (resourcePath.split(/[/\\\\]/).some((segment) => segment === '..')) {\n return { kind: 'access-denied', message: PATH_TRAVERSAL_MESSAGE };\n }\n\n const resolvedSkillPath = resolve(skillPath);\n const resolvedPath = resolve(resolvedSkillPath, resourcePath);\n const lexicalRelativePath = relative(resolvedSkillPath, resolvedPath);\n if (\n lexicalRelativePath.startsWith('..') ||\n isAbsolute(lexicalRelativePath) ||\n resolve(resolvedSkillPath, lexicalRelativePath) !== resolvedPath\n ) {\n return { kind: 'access-denied', message: PATH_TRAVERSAL_MESSAGE };\n }\n\n let canonicalSkillPath: string;\n try {\n canonicalSkillPath = realpathSync(resolvedSkillPath);\n } catch (error) {\n return { kind: 'read-failure', error: formatResourceReadError(error, resolvedPath) };\n }\n\n let canonicalPath: string;\n try {\n canonicalPath = realpathSync(resolvedPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return {\n kind: 'resource-not-found',\n resolvedPath,\n error: formatResourceReadError(error, resolvedPath),\n };\n }\n return {\n kind: 'target-read-failure',\n resolvedPath,\n error: formatResourceReadError(error, resolvedPath),\n };\n }\n\n const canonicalRelativePath = relative(canonicalSkillPath, canonicalPath);\n if (canonicalRelativePath.startsWith('..') || isAbsolute(canonicalRelativePath)) {\n return { kind: 'access-denied', message: SYMLINK_ESCAPE_MESSAGE };\n }\n\n return { kind: 'success', resolvedPath, canonicalPath, canonicalRelativePath };\n}\n\nexport type SkillActivationResult =\n | { kind: 'success'; body: string }\n | { kind: 'skill-not-found'; name: string; availableNames: string[] }\n | { kind: 'access-denied'; reason: TrustPolicyReason; message: string }\n | { kind: 'read-failure'; name: string; error: string };\n\nexport type SkillResourceResult =\n | { kind: 'success'; content: string }\n | { kind: 'skill-not-found'; name: string; availableNames: string[] }\n | { kind: 'access-denied'; message: string; reason?: TrustPolicyReason }\n | { kind: 'resource-not-found'; name: string; resourcePath: string; error: string }\n | { kind: 'read-failure'; name: string; resourcePath: string; error: string };\n\n/** Package-internal owner of Agent Skill lookup, policy, reads, and audit signals. */\nexport class AgentSkillAccess {\n constructor(private readonly registry: SkillRegistry) {}\n\n async readResource(name: string, resourcePath: string): Promise<SkillResourceResult> {\n const skill = this.registry.get(name);\n if (!skill) {\n const availableNames = this.registry.getNames();\n activationLogger.warn('Skill resource load failed — skill not found', {\n name,\n resourcePath,\n });\n return { kind: 'skill-not-found', name, availableNames };\n }\n\n const pathResult = resolveCanonicalResourcePath(skill.skillPath, resourcePath);\n if (pathResult.kind === 'access-denied') {\n activationLogger.warn('Skill resource load blocked — path traversal', {\n name,\n resourcePath,\n error: pathResult.message,\n });\n return pathResult;\n }\n if (pathResult.kind === 'read-failure') {\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: pathResult.error,\n });\n return { ...pathResult, name, resourcePath };\n }\n\n const skillInstructionsPath = resolve(skill.skillPath, 'SKILL.md');\n let isSkillInstructions =\n pathResult.resolvedPath.toLowerCase() === skillInstructionsPath.toLowerCase();\n if (!isSkillInstructions && pathResult.kind === 'success') {\n try {\n isSkillInstructions =\n pathResult.canonicalPath.toLowerCase() ===\n realpathSync(skillInstructionsPath).toLowerCase();\n } catch {\n // The resource read below reports missing or unreadable paths.\n }\n }\n if (isSkillInstructions) {\n const activationDecision = evaluateSkillActivationPolicy(skill.trustLevel);\n if (!activationDecision.allowed) {\n activationLogger.warn('Skill resource load blocked — skill instructions trust policy', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: activationDecision.reason,\n message: activationDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath: 'SKILL.md',\n trustLevel: skill.trustLevel,\n reason: activationDecision.reason,\n message: activationDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: activationDecision.reason,\n message: activationDecision.message,\n };\n }\n }\n\n const policyDecision = evaluateTrustPolicy(\n pathResult.kind === 'success' ? pathResult.canonicalRelativePath : resourcePath,\n skill.trustLevel,\n this.registry.getAllowUntrustedScripts()\n );\n if (!policyDecision.allowed) {\n activationLogger.warn('Skill resource load blocked — trust policy', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: policyDecision.reason,\n message: policyDecision.message,\n };\n }\n\n if (policyDecision.reason !== TrustPolicyReason.NOT_SCRIPT) {\n activationLogger.info('Skill resource trust policy — allowed', {\n name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_ALLOWED, {\n name: skill.metadata.name,\n resourcePath,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n });\n }\n\n if (pathResult.kind === 'resource-not-found' || pathResult.kind === 'target-read-failure') {\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: pathResult.error,\n });\n return {\n kind: pathResult.kind === 'resource-not-found' ? 'resource-not-found' : 'read-failure',\n name,\n resourcePath,\n error: pathResult.error,\n };\n }\n\n let content: string;\n try {\n content = readFileSync(pathResult.canonicalPath, 'utf-8');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n activationLogger.warn('Skill resource load failed — file not found or unreadable', {\n name,\n resourcePath,\n error: message,\n });\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { kind: 'resource-not-found', name, resourcePath, error: message };\n }\n return { kind: 'read-failure', name, resourcePath, error: message };\n }\n\n activationLogger.info('Skill resource loaded', {\n name: skill.metadata.name,\n resourcePath,\n resolvedPath: pathResult.resolvedPath,\n contentLength: content.length,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.SKILL_RESOURCE_LOADED, {\n name: skill.metadata.name,\n resourcePath,\n resolvedPath: pathResult.resolvedPath,\n contentLength: content.length,\n });\n\n return { kind: 'success', content };\n }\n\n async activate(name: string): Promise<SkillActivationResult> {\n const skill = this.registry.get(name);\n if (!skill) {\n const availableNames = this.registry.getNames();\n activationLogger.warn('Skill activation failed — not found', {\n name,\n availableCount: availableNames.length,\n });\n return { kind: 'skill-not-found', name, availableNames };\n }\n\n const policyDecision = evaluateSkillActivationPolicy(skill.trustLevel);\n if (!policyDecision.allowed) {\n activationLogger.warn('Skill activation blocked — trust policy', {\n name,\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.TRUST_POLICY_DENIED, {\n name: skill.metadata.name,\n resourcePath: 'SKILL.md',\n trustLevel: skill.trustLevel,\n reason: policyDecision.reason,\n message: policyDecision.message,\n });\n\n return {\n kind: 'access-denied',\n reason: policyDecision.reason,\n message: policyDecision.message,\n };\n }\n\n let body: string;\n try {\n const content = readFileSync(resolve(skill.skillPath, 'SKILL.md'), 'utf-8');\n body = extractBody(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n activationLogger.error('Skill activation failed — read error', {\n name,\n skillPath: skill.skillPath,\n error: message,\n });\n return { kind: 'read-failure', name, error: message };\n }\n\n activationLogger.info('Skill activated', {\n name: skill.metadata.name,\n skillPath: skill.skillPath,\n bodyLength: body.length,\n trustLevel: skill.trustLevel,\n activationReason: policyDecision.reason,\n });\n\n this.registry.emitEvent(SkillRegistryEvent.SKILL_ACTIVATED, {\n name: skill.metadata.name,\n skillPath: skill.skillPath,\n bodyLength: body.length,\n trustLevel: skill.trustLevel,\n });\n\n return { kind: 'success', body };\n }\n}\n","import { z } from 'zod';\n\nexport const activateSkillSchema = z.object({\n name: z.string().describe('The name of the skill to activate (e.g., \"code-review\")'),\n});\n\nexport const readSkillResourceSchema = z.object({\n name: z.string().describe('The name of the skill that owns the resource'),\n path: z.string().describe('Relative path to the resource file within the skill directory (e.g., \"references/GUIDE.md\", \"scripts/setup.sh\")'),\n});\n","import { ToolBuilder, ToolCategory } from '@agentforge/core';\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { AgentSkillAccess } from './agent-skill-access.js';\nimport { activateSkillSchema } from './activation-schemas.js';\nimport { formatMissingSkillMessage } from './activation-shared.js';\n\n/**\n * Create the `activate-skill` tool bound to a registry instance.\n *\n * Resolves the skill by name, reads the full SKILL.md file, and returns\n * the body content (below frontmatter).\n *\n * @param registry - The SkillRegistry to resolve skills from\n * @returns An AgentForge Tool\n */\nexport function createActivateSkillTool(\n registry: SkillRegistry,\n): Tool<z.infer<typeof activateSkillSchema>, string> {\n const access = new AgentSkillAccess(registry);\n\n return new ToolBuilder<z.infer<typeof activateSkillSchema>, string>()\n .name('activate-skill')\n .description(\n 'Activate an Agent Skill by name, loading its full instructions for trusted roots. ' +\n 'Returns the complete SKILL.md body content for workspace or explicitly trusted skills. ' +\n 'Use this when you see a relevant skill in <available_skills> or <untrusted_skills>; ' +\n 'activation is blocked for untrusted roots until they are promoted.',\n )\n .category(ToolCategory.SKILLS)\n .tags(['skill', 'activation', 'agent-skills'])\n .schema(activateSkillSchema)\n .implement(async ({ name }) => {\n const result = await access.activate(name);\n\n switch (result.kind) {\n case 'success':\n return result.body;\n case 'skill-not-found':\n return formatMissingSkillMessage(result.name, result.availableNames);\n case 'access-denied':\n return result.message;\n case 'read-failure':\n return `Failed to read skill \"${result.name}\" instructions: ${result.error}`;\n }\n })\n .build();\n}\n","import { ToolBuilder, ToolCategory } from '@agentforge/core';\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { AgentSkillAccess } from './agent-skill-access.js';\nimport { readSkillResourceSchema } from './activation-schemas.js';\nimport { formatMissingSkillMessage } from './activation-shared.js';\n\n/**\n * Create the `read-skill-resource` tool bound to a registry instance.\n *\n * Resolves the skill by name, validates the resource path (blocking\n * traversal), and returns the file content.\n *\n * @param registry - The SkillRegistry to resolve skills from\n * @returns An AgentForge Tool\n */\nexport function createReadSkillResourceTool(\n registry: SkillRegistry\n): Tool<z.infer<typeof readSkillResourceSchema>, string> {\n const access = new AgentSkillAccess(registry);\n\n return new ToolBuilder<z.infer<typeof readSkillResourceSchema>, string>()\n .name('read-skill-resource')\n .description(\n 'Read a resource file from an activated Agent Skill. ' +\n 'Returns the content of a file within the skill directory (e.g., references/, scripts/, assets/). ' +\n 'The path must be relative to the skill root and cannot traverse outside it. ' +\n 'SKILL.md is only readable from workspace or trusted roots.'\n )\n .category(ToolCategory.SKILLS)\n .tags(['skill', 'resource', 'agent-skills'])\n .schema(readSkillResourceSchema)\n .implement(async ({ name, path: resourcePath }) => {\n const result = await access.readResource(name, resourcePath);\n\n switch (result.kind) {\n case 'success':\n return result.content;\n case 'skill-not-found':\n return formatMissingSkillMessage(result.name, result.availableNames);\n case 'access-denied':\n return result.message;\n case 'resource-not-found':\n case 'read-failure':\n return `Failed to read resource \"${result.resourcePath}\" from skill \"${result.name}\": ${result.error}`;\n }\n })\n .build();\n}\n","import { isAbsolute, relative, resolve } from 'node:path';\nimport { realpathSync } from 'node:fs';\n\n/**\n * Resolve a resource path within a skill root, blocking path traversal.\n *\n * @param skillPath - Absolute path to the skill directory\n * @param resourcePath - Relative path to the resource file\n * @returns A result containing either the resolved absolute path or an error message\n * @deprecated Use the `read-skill-resource` Tool from\n * `SkillRegistry.toActivationTools()` for Agent Skill resource access. This\n * compatibility helper is planned for removal in the next major release.\n */\nexport function resolveResourcePath(\n skillPath: string,\n resourcePath: string,\n): { success: true; resolvedPath: string } | { success: false; error: string } {\n if (isAbsolute(resourcePath)) {\n return { success: false, error: 'Absolute resource paths are not allowed' };\n }\n\n const segments = resourcePath.split(/[/\\\\]/);\n if (segments.some((seg) => seg === '..')) {\n return { success: false, error: 'Path traversal is not allowed — resource paths must stay within the skill directory' };\n }\n\n const resolvedPath = resolve(skillPath, resourcePath);\n const resolvedSkillPath = resolve(skillPath);\n const rel = relative(resolvedSkillPath, resolvedPath);\n if (rel.startsWith('..') || resolve(resolvedSkillPath, rel) !== resolvedPath) {\n return { success: false, error: 'Path traversal is not allowed — resource paths must stay within the skill directory' };\n }\n\n try {\n const realSkillRoot = realpathSync(resolvedSkillPath);\n const realTarget = realpathSync(resolvedPath);\n const realRel = relative(realSkillRoot, realTarget);\n if (realRel.startsWith('..') || isAbsolute(realRel)) {\n return { success: false, error: 'Symlink target escapes the skill directory — access denied' };\n }\n } catch {\n // File doesn't exist yet (or can't be stat'd) — skip symlink check.\n // The caller will produce a clear error if the file is missing.\n }\n\n return { success: true, resolvedPath };\n}\n","/**\n * Agent Skill Access Tools\n *\n * Provides `activate-skill` and `read-skill-resource` tools built with\n * the AgentForge tool builder API. Skill activation makes trusted Agent\n * Skill instructions available; resource access loads supporting files.\n *\n * @see https://agentskills.io/specification\n *\n * @example\n * ```ts\n * const [activateSkill, readSkillResource] = createSkillActivationTools(registry);\n * // activateSkill — load full SKILL.md body\n * // readSkillResource — load a resource file from a skill\n *\n * // Or use the convenience method:\n * const [activateSkill, readSkillResource] = registry.toActivationTools();\n * ```\n */\n\nimport type { Tool } from '@agentforge/core';\nimport type { z } from 'zod';\nimport type { SkillRegistry } from './registry.js';\nimport { createActivateSkillTool } from './activation-activate-tool.js';\nimport { createReadSkillResourceTool } from './activation-resource-tool.js';\nimport type { activateSkillSchema, readSkillResourceSchema } from './activation-schemas.js';\n\nexport { createActivateSkillTool } from './activation-activate-tool.js';\nexport { resolveResourcePath } from './activation-path.js';\nexport { createReadSkillResourceTool } from './activation-resource-tool.js';\n\n/**\n * Create both skill activation tools bound to a registry instance.\n *\n * @param registry - The SkillRegistry to bind tools to\n * @returns Array of both tools [activate-skill, read-skill-resource]\n */\nexport function createSkillActivationTools(\n registry: SkillRegistry,\n): [Tool<z.infer<typeof activateSkillSchema>, string>, Tool<z.infer<typeof readSkillResourceSchema>, string>] {\n return [\n createActivateSkillTool(registry),\n createReadSkillResourceTool(registry),\n ];\n}\n","import { resolve as resolvePath } from 'node:path';\nimport { createLogger, LogLevel } from '@agentforge/core';\nimport { parseSkillContent } from './parser.js';\nimport { scanAllSkillRoots, expandHome } from './scanner.js';\nimport { normalizeRootConfig } from './trust.js';\nimport type { Skill, SkillRegistryConfig, TrustLevel } from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport type { RegistryEmit, ScanError } from './registry-internal.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function discoverSkills(\n config: Pick<SkillRegistryConfig, 'skillRoots'>,\n skills: Map<string, Skill>,\n rootTrustMap: Map<string, TrustLevel>,\n emit: RegistryEmit,\n): ScanError[] {\n skills.clear();\n rootTrustMap.clear();\n const scanErrors: ScanError[] = [];\n\n const normalizedRoots = config.skillRoots.map(normalizeRootConfig);\n const plainPaths = normalizedRoots.map((root) => root.path);\n\n for (const root of normalizedRoots) {\n const resolvedPath = resolvePath(expandHome(root.path));\n rootTrustMap.set(resolvedPath, root.trust);\n }\n\n const candidates = scanAllSkillRoots(plainPaths);\n\n let successCount = 0;\n let warningCount = 0;\n\n for (const candidate of candidates) {\n const result = parseSkillContent(candidate.content, candidate.dirName);\n\n if (!result.success) {\n warningCount++;\n recordScanError(scanErrors, candidate.skillPath, result.error || 'Unknown parse error');\n emit(SkillRegistryEvent.SKILL_WARNING, {\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n error: result.error,\n });\n logger.warn('Skipping invalid skill', {\n skillPath: candidate.skillPath,\n ...(result.error ? { error: result.error } : {}),\n });\n continue;\n }\n\n const skill: Skill = {\n metadata: result.metadata!,\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n trustLevel: rootTrustMap.get(candidate.rootPath) ?? 'untrusted',\n };\n\n if (skills.has(skill.metadata.name)) {\n warningCount++;\n const existing = skills.get(skill.metadata.name)!;\n const warningMessage =\n `Duplicate skill name \"${skill.metadata.name}\" from \"${candidate.rootPath}\" — ` +\n `keeping version from \"${existing.rootPath}\" (first root takes precedence)`;\n\n recordScanError(scanErrors, candidate.skillPath, warningMessage);\n emit(SkillRegistryEvent.SKILL_WARNING, {\n skillPath: candidate.skillPath,\n rootPath: candidate.rootPath,\n duplicateOf: existing.skillPath,\n error: warningMessage,\n });\n logger.warn('Duplicate skill name, keeping first', {\n name: skill.metadata.name,\n kept: existing.skillPath,\n skipped: candidate.skillPath,\n });\n continue;\n }\n\n skills.set(skill.metadata.name, skill);\n successCount++;\n emit(SkillRegistryEvent.SKILL_DISCOVERED, skill);\n logger.debug('Skill discovered', {\n name: skill.metadata.name,\n description: skill.metadata.description.slice(0, 80),\n skillPath: skill.skillPath,\n });\n }\n\n logger.info('Skill registry populated', {\n rootsScanned: config.skillRoots.length,\n skillsDiscovered: successCount,\n warnings: warningCount,\n });\n\n return scanErrors;\n}\n\nfunction recordScanError(scanErrors: ScanError[], path: string, error: string): void {\n scanErrors.push({ path, error });\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\nimport type { SkillEventHandler } from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport type { RegistryEventHandlers } from './registry-internal.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function addRegistryEventHandler(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n handler: SkillEventHandler,\n): void {\n if (!eventHandlers.has(event)) {\n eventHandlers.set(event, new Set());\n }\n\n eventHandlers.get(event)!.add(handler);\n}\n\nexport function removeRegistryEventHandler(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n handler: SkillEventHandler,\n): void {\n const handlers = eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n }\n}\n\nexport function emitRegistryEvent(\n eventHandlers: RegistryEventHandlers,\n event: SkillRegistryEvent,\n data: unknown,\n): void {\n const handlers = eventHandlers.get(event);\n if (!handlers) {\n return;\n }\n\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n logger.error('Skill event handler error', {\n event,\n error: error instanceof Error ? error.message : String(error),\n ...(error instanceof Error && error.stack ? { stack: error.stack } : {}),\n });\n }\n });\n}\n","import { createLogger, LogLevel } from '@agentforge/core';\nimport type { Skill, SkillPromptOptions, SkillRegistryConfig } from './types.js';\n\nconst logger = createLogger('agentforge:skills:registry', { level: LogLevel.INFO });\n\nexport function generateSkillPrompt(\n config: SkillRegistryConfig,\n allSkills: Skill[],\n totalDiscovered: number,\n options?: SkillPromptOptions,\n): string {\n if (!config.enabled) {\n logger.debug('Skill prompt generation skipped (disabled)', {\n enabled: config.enabled ?? false,\n });\n return '';\n }\n\n let skills = allSkills;\n\n if (options?.skills && options.skills.length > 0) {\n const requested = new Set(options.skills);\n skills = skills.filter((skill) => requested.has(skill.metadata.name));\n }\n\n let trustedSkills = skills.filter(\n (skill) => skill.trustLevel === 'workspace' || skill.trustLevel === 'trusted',\n );\n let untrustedSkills = skills.filter(\n (skill) => skill.trustLevel !== 'workspace' && skill.trustLevel !== 'trusted',\n );\n\n if (config.maxDiscoveredSkills !== undefined && config.maxDiscoveredSkills >= 0) {\n const trustedLimit = Math.min(config.maxDiscoveredSkills, trustedSkills.length);\n trustedSkills = trustedSkills.slice(0, trustedLimit);\n untrustedSkills = untrustedSkills.slice(0, config.maxDiscoveredSkills - trustedLimit);\n skills = [...trustedSkills, ...untrustedSkills];\n }\n\n if (trustedSkills.length === 0 && untrustedSkills.length === 0) {\n logger.debug('Skill prompt generation produced empty result', {\n totalDiscovered,\n filterApplied: !!(options?.skills && options.skills.length > 0),\n ...(config.maxDiscoveredSkills !== undefined\n ? { maxCap: config.maxDiscoveredSkills }\n : {}),\n });\n return '';\n }\n\n const sections: string[] = [];\n\n if (trustedSkills.length > 0) {\n sections.push(`<available_skills>\\n${trustedSkills.map(renderTrustedSkillEntry).join('\\n')}\\n</available_skills>`);\n }\n\n if (untrustedSkills.length > 0) {\n sections.push(renderUntrustedSkillsSection(untrustedSkills));\n }\n\n const xml = sections.join('\\n');\n const estimatedTokens = Math.ceil(xml.length / 4);\n\n logger.info('Skill prompt generated', {\n skillCount: skills.length,\n trustedSkillCount: trustedSkills.length,\n untrustedSkillCount: untrustedSkills.length,\n totalDiscovered,\n filterApplied: !!(options?.skills && options.skills.length > 0),\n ...(config.maxDiscoveredSkills !== undefined ? { maxCap: config.maxDiscoveredSkills } : {}),\n estimatedTokens,\n xmlLength: xml.length,\n });\n\n return xml;\n}\n\nfunction renderTrustedSkillEntry(skill: Skill): string {\n return [\n ' <skill>',\n ` <name>${escapeXml(skill.metadata.name)}</name>`,\n ` <description>${escapeXml(skill.metadata.description)}</description>`,\n ` <location>${escapeXml(skill.skillPath)}</location>`,\n ` <trust>${escapeXml(skill.trustLevel)}</trust>`,\n ' </skill>',\n ].join('\\n');\n}\n\nfunction renderUntrustedSkillsSection(skills: Skill[]): string {\n return [\n '<untrusted_skills>',\n ' <trust_notice>Untrusted skills are discoverable, but their full SKILL.md bodies stay blocked until the root is promoted to trusted or workspace status.</trust_notice>',\n ...skills.map(renderUntrustedSkillEntry),\n '</untrusted_skills>',\n ].join('\\n');\n}\n\nfunction renderUntrustedSkillEntry(skill: Skill): string {\n return [\n ' <skill>',\n ` <name>${escapeXml(skill.metadata.name)}</name>`,\n ` <description>${escapeXml(skill.metadata.description)}</description>`,\n ` <location>${escapeXml(skill.skillPath)}</location>`,\n ` <trust>${escapeXml(skill.trustLevel)}</trust>`,\n ' <activation_policy>requires-trusted-root</activation_policy>',\n ' </skill>',\n ].join('\\n');\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n","import type {\n Skill,\n SkillEventHandler,\n SkillPromptOptions,\n SkillRegistryConfig,\n TrustLevel,\n} from './types.js';\nimport { SkillRegistryEvent } from './types.js';\nimport { createSkillActivationTools } from './activation.js';\nimport { discoverSkills } from './registry-discovery.js';\nimport {\n addRegistryEventHandler,\n emitRegistryEvent,\n removeRegistryEventHandler,\n} from './registry-events.js';\nimport type { RegistryEventHandlers } from './registry-internal.js';\nimport { generateSkillPrompt } from './registry-prompt.js';\n\nexport class SkillRegistry {\n private skills: Map<string, Skill> = new Map();\n private eventHandlers: RegistryEventHandlers = new Map();\n private readonly config: SkillRegistryConfig;\n private scanErrors: Array<{ path: string; error: string }> = [];\n private rootTrustMap: Map<string, TrustLevel> = new Map();\n\n constructor(config: SkillRegistryConfig) {\n this.config = config;\n this.discover();\n }\n\n discover(): void {\n this.scanErrors = discoverSkills(this.config, this.skills, this.rootTrustMap, (event, data) => {\n this.emit(event, data);\n });\n }\n\n get(name: string): Skill | undefined {\n return this.skills.get(name);\n }\n\n getAll(): Skill[] {\n return Array.from(this.skills.values());\n }\n\n has(name: string): boolean {\n return this.skills.has(name);\n }\n\n size(): number {\n return this.skills.size;\n }\n\n getNames(): string[] {\n return Array.from(this.skills.keys());\n }\n\n getScanErrors(): ReadonlyArray<{ path: string; error: string }> {\n return this.scanErrors;\n }\n\n getAllowUntrustedScripts(): boolean {\n return this.config.allowUntrustedScripts ?? false;\n }\n\n getAllowedTools(name: string): string[] | undefined {\n return this.skills.get(name)?.metadata.allowedTools;\n }\n\n generatePrompt(options?: SkillPromptOptions): string {\n return generateSkillPrompt(this.config, this.getAll(), this.size(), options);\n }\n\n on(event: SkillRegistryEvent, handler: SkillEventHandler): void {\n addRegistryEventHandler(this.eventHandlers, event, handler);\n }\n\n off(event: SkillRegistryEvent, handler: SkillEventHandler): void {\n removeRegistryEventHandler(this.eventHandlers, event, handler);\n }\n\n emitEvent(event: SkillRegistryEvent, data: unknown): void {\n this.emit(event, data);\n }\n\n toActivationTools(): ReturnType<typeof createSkillActivationTools> {\n return createSkillActivationTools(this);\n }\n\n private emit(event: SkillRegistryEvent, data: unknown): void {\n emitRegistryEvent(this.eventHandlers, event, data);\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentforge/skills",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.5",
|
|
4
4
|
"description": "Composable skill system for building modular TypeScript AI agents: author skills, register capabilities, and compose behaviors.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"README.md"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@agentforge/core": "0.18.
|
|
21
|
+
"@agentforge/core": "0.18.5",
|
|
22
22
|
"gray-matter": "^4.0.3",
|
|
23
23
|
"zod": "^3.24.1"
|
|
24
24
|
},
|