skill-tree 0.1.7 → 0.2.0

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.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/storage/base.ts","../src/storage/sqlite.ts","../src/agents/types.ts","../src/agents/generator.ts","../src/agents/parser.ts","../src/agents/sync.ts","../src/index.ts","../src/types.ts","../src/sync/git-sync-adapter.ts","../src/sync/conflict-store.ts","../src/sync/sync-manager.ts","../src/serving/xml-utils.ts","../src/serving/catalog-renderer.ts","../src/serving/loadout-compiler.ts","../src/serving/project-detector.ts","../src/serving/view-renderer.ts","../src/serving/profiles/index.ts","../src/serving/graph-server.ts","../src/serving/interfaces.ts","../src/federation/remote-store.ts","../src/federation/remote-manager.ts","../src/federation/skilltree-config.ts","../src/versioning/semver.ts","../src/federation/federation-manager.ts","../src/skill-bank.ts","../src/storage/cached.ts","../src/storage/filesystem.ts","../src/versioning/lineage.ts","../src/versioning/merge.ts","../src/hooks/registry.ts","../src/materialization/materializer.ts","../src/storage/index.ts","../src/storage/migration.ts","../src/agents/index.ts","../src/hooks/builtin.ts","../src/sync/index.ts","../src/services/indexer.ts","../src/config/types.ts","../src/config/loader.ts","../src/import/converter.ts"],"sourcesContent":["/**\n * Base storage adapter interface and utilities\n */\n\nimport type {\n StorageAdapter,\n Skill,\n SkillFilter,\n SkillVersion,\n SkillLineage,\n SkillFork,\n SkillScope,\n SkillVisibility,\n} from '../types.js';\n\n/**\n * Abstract base class for storage adapters\n */\nexport abstract class BaseStorageAdapter implements StorageAdapter {\n protected initialized = false;\n\n abstract initialize(): Promise<void>;\n abstract saveSkill(skill: Skill): Promise<void>;\n abstract getSkill(id: string, version?: string): Promise<Skill | null>;\n abstract listSkills(filter?: SkillFilter): Promise<Skill[]>;\n abstract deleteSkill(id: string, version?: string): Promise<boolean>;\n abstract getVersionHistory(skillId: string): Promise<SkillVersion[]>;\n abstract getLineage(skillId: string): Promise<SkillLineage | null>;\n abstract searchSkills(query: string): Promise<Skill[]>;\n\n /**\n * Ensure storage is initialized before operations\n */\n protected ensureInitialized(): void {\n if (!this.initialized) {\n throw new Error('Storage not initialized. Call initialize() first.');\n }\n }\n\n /**\n * Apply filters to a list of skills\n */\n protected applyFilter(skills: Skill[], filter?: SkillFilter): Skill[] {\n if (!filter) return skills;\n\n return skills.filter((skill) => {\n // Status filter\n if (filter.status && filter.status.length > 0) {\n if (!filter.status.includes(skill.status)) return false;\n }\n\n // Tags filter (any match)\n if (filter.tags && filter.tags.length > 0) {\n const hasTag = filter.tags.some((tag) => skill.tags.includes(tag));\n if (!hasTag) return false;\n }\n\n // Author filter\n if (filter.author && skill.author !== filter.author) {\n return false;\n }\n\n // Success rate filter\n if (\n filter.minSuccessRate !== undefined &&\n skill.metrics.successRate < filter.minSuccessRate\n ) {\n return false;\n }\n\n // Date filters\n if (filter.createdAfter && skill.createdAt < filter.createdAfter) {\n return false;\n }\n if (filter.createdBefore && skill.createdAt > filter.createdBefore) {\n return false;\n }\n\n // Namespace filters (for multi-tier skill trees)\n if (!this.applyNamespaceFilter(skill, filter)) {\n return false;\n }\n\n return true;\n });\n }\n\n /**\n * Apply namespace-related filters to a skill\n */\n protected applyNamespaceFilter(skill: Skill, filter: SkillFilter): boolean {\n const namespace = skill.namespace;\n\n // Scope filter\n if (filter.scope) {\n const scopes = Array.isArray(filter.scope) ? filter.scope : [filter.scope];\n const skillScope = namespace?.scope || 'personal';\n if (!scopes.includes(skillScope)) return false;\n }\n\n // Owner filter\n if (filter.owner) {\n const skillOwner = namespace?.owner;\n if (skillOwner !== filter.owner) return false;\n }\n\n // Team filter\n if (filter.team) {\n const skillTeam = namespace?.team;\n if (skillTeam !== filter.team) return false;\n }\n\n // Visibility filter\n if (filter.visibility) {\n const visibilities = Array.isArray(filter.visibility)\n ? filter.visibility\n : [filter.visibility];\n const skillVisibility = namespace?.visibility || 'private';\n if (!visibilities.includes(skillVisibility)) return false;\n }\n\n // Accessibility filter (can this agent access this skill?)\n if (filter.accessibleBy) {\n if (!this.canAgentAccessSkill(skill, filter.accessibleBy, filter.accessibleByTeam)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Check if an agent can access a skill based on namespace rules\n */\n protected canAgentAccessSkill(\n skill: Skill,\n agentId: string,\n agentTeam?: string\n ): boolean {\n const namespace = skill.namespace;\n\n // No namespace = accessible to all (backward compatibility)\n if (!namespace) return true;\n\n // Owner always has access\n if (namespace.owner === agentId) return true;\n\n // Check visibility\n switch (namespace.visibility) {\n case 'public':\n return true;\n\n case 'team-only':\n // Agent must be in the same team\n return agentTeam !== undefined && agentTeam === namespace.team;\n\n case 'private':\n // Only owner has access\n return namespace.owner === agentId;\n\n default:\n return false;\n }\n }\n\n /**\n * Simple text search across skill fields\n */\n protected textSearch(skills: Skill[], query: string): Skill[] {\n const lowerQuery = query.toLowerCase();\n const terms = lowerQuery.split(/\\s+/).filter((t) => t.length > 0);\n\n return skills.filter((skill) => {\n const searchText = [\n skill.name,\n skill.description,\n skill.instructions,\n ...skill.tags,\n ]\n .join(' ')\n .toLowerCase();\n\n // All terms must match\n return terms.every((term) => searchText.includes(term));\n });\n }\n}\n\n/**\n * In-memory storage adapter (useful for testing)\n */\nexport class MemoryStorageAdapter extends BaseStorageAdapter {\n private skills = new Map<string, Map<string, Skill>>(); // skillId -> version -> skill\n private lineages = new Map<string, SkillLineage>();\n\n async initialize(): Promise<void> {\n this.initialized = true;\n }\n\n async saveSkill(skill: Skill): Promise<void> {\n this.ensureInitialized();\n\n // Get or create version map for this skill\n if (!this.skills.has(skill.id)) {\n this.skills.set(skill.id, new Map());\n }\n\n const versionMap = this.skills.get(skill.id)!;\n versionMap.set(skill.version, { ...skill });\n\n // Update lineage\n this.updateLineage(skill);\n }\n\n async getSkill(id: string, version?: string): Promise<Skill | null> {\n this.ensureInitialized();\n\n const versionMap = this.skills.get(id);\n if (!versionMap) return null;\n\n if (version) {\n return versionMap.get(version) || null;\n }\n\n // Return latest version\n const versions = Array.from(versionMap.keys()).sort(this.compareVersions);\n const latestVersion = versions[versions.length - 1];\n return latestVersion ? versionMap.get(latestVersion) || null : null;\n }\n\n async listSkills(filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n\n // Get latest version of each skill\n const skills: Skill[] = [];\n for (const versionMap of this.skills.values()) {\n const versions = Array.from(versionMap.keys()).sort(this.compareVersions);\n const latestVersion = versions[versions.length - 1];\n if (latestVersion) {\n const skill = versionMap.get(latestVersion);\n if (skill) skills.push(skill);\n }\n }\n\n return this.applyFilter(skills, filter);\n }\n\n async deleteSkill(id: string, version?: string): Promise<boolean> {\n this.ensureInitialized();\n\n if (version) {\n const versionMap = this.skills.get(id);\n if (!versionMap) return false;\n return versionMap.delete(version);\n }\n\n // Delete all versions\n const existed = this.skills.has(id);\n this.skills.delete(id);\n this.lineages.delete(id);\n return existed;\n }\n\n async getVersionHistory(skillId: string): Promise<SkillVersion[]> {\n this.ensureInitialized();\n\n const versionMap = this.skills.get(skillId);\n if (!versionMap) return [];\n\n const versions: SkillVersion[] = [];\n for (const [version, skill] of versionMap) {\n versions.push({\n skillId,\n version,\n skill,\n changelog: '', // Not tracked in memory\n createdAt: skill.createdAt,\n contentHash: this.hashSkill(skill),\n });\n }\n\n return versions.sort((a, b) => this.compareVersions(a.version, b.version));\n }\n\n async getLineage(skillId: string): Promise<SkillLineage | null> {\n this.ensureInitialized();\n return this.lineages.get(skillId) || null;\n }\n\n async searchSkills(query: string): Promise<Skill[]> {\n this.ensureInitialized();\n const allSkills = await this.listSkills();\n return this.textSearch(allSkills, query);\n }\n\n private updateLineage(skill: Skill): void {\n if (!this.lineages.has(skill.id)) {\n this.lineages.set(skill.id, {\n rootId: skill.id,\n versions: [],\n forks: [],\n });\n }\n\n const lineage = this.lineages.get(skill.id)!;\n const existingIndex = lineage.versions.findIndex((v) => v.version === skill.version);\n\n const versionEntry: SkillVersion = {\n skillId: skill.id,\n version: skill.version,\n skill,\n changelog: '',\n createdAt: skill.createdAt,\n contentHash: this.hashSkill(skill),\n };\n\n if (existingIndex >= 0) {\n lineage.versions[existingIndex] = versionEntry;\n } else {\n lineage.versions.push(versionEntry);\n lineage.versions.sort((a, b) => this.compareVersions(a.version, b.version));\n }\n }\n\n private compareVersions(a: string, b: string): number {\n const partsA = a.split('.').map(Number);\n const partsB = b.split('.').map(Number);\n\n for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {\n const numA = partsA[i] || 0;\n const numB = partsB[i] || 0;\n if (numA !== numB) return numA - numB;\n }\n return 0;\n }\n\n private hashSkill(skill: Skill): string {\n // Simple hash for content integrity\n const content = JSON.stringify({\n instructions: skill.instructions,\n });\n let hash = 0;\n for (let i = 0; i < content.length; i++) {\n const char = content.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(16);\n }\n\n /**\n * Clear all stored skills (for testing)\n */\n clear(): void {\n this.skills.clear();\n this.lineages.clear();\n }\n\n // ==========================================================================\n // Fork Tracking\n // ==========================================================================\n\n async recordFork(sourceSkillId: string, fork: SkillFork): Promise<void> {\n this.ensureInitialized();\n const lineage = this.lineages.get(sourceSkillId);\n if (lineage) {\n // Avoid duplicates\n const exists = lineage.forks.some(\n (f) => f.forkedSkillId === fork.forkedSkillId\n );\n if (!exists) {\n lineage.forks.push(fork);\n }\n }\n }\n}\n","/**\n * SQLite storage adapter with full-text search\n */\n\nimport Database, { type Database as DatabaseType } from 'better-sqlite3';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { BaseStorageAdapter } from './base.js';\nimport type {\n Skill,\n SkillFilter,\n SkillVersion,\n SkillLineage,\n SkillFork,\n SkillStatus,\n SkillTaxonomy,\n ExternalSource,\n SkillRelationship,\n} from '../types.js';\n\nexport interface SQLiteStorageConfig {\n /** Path to SQLite database file */\n dbPath: string;\n /** Enable WAL mode for better performance (default: true) */\n walMode?: boolean;\n /** Enable full-text search (default: true) */\n enableFTS?: boolean;\n}\n\n// Schema version for migrations\nconst SCHEMA_VERSION = 3;\n\n/**\n * SQLite storage adapter for skill-tree\n */\nexport class SQLiteStorageAdapter extends BaseStorageAdapter {\n private db: DatabaseType | null = null;\n private config: SQLiteStorageConfig;\n\n constructor(config: SQLiteStorageConfig) {\n super();\n this.config = {\n walMode: true,\n enableFTS: true,\n ...config,\n };\n }\n\n async initialize(): Promise<void> {\n // Ensure directory exists\n const dir = path.dirname(this.config.dbPath);\n if (dir && !fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Open database\n this.db = new Database(this.config.dbPath);\n\n // Enable WAL mode for better concurrent performance\n if (this.config.walMode) {\n this.db.pragma('journal_mode = WAL');\n }\n\n // Enable foreign keys\n this.db.pragma('foreign_keys = ON');\n\n // Create schema\n this.createSchema();\n\n // Run migrations if needed\n this.runMigrations();\n\n this.initialized = true;\n }\n\n private createSchema(): void {\n const db = this.getDb();\n\n // Schema version table\n db.exec(`\n CREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY\n )\n `);\n\n // Skills table (stores current/latest version of each skill)\n db.exec(`\n CREATE TABLE IF NOT EXISTS skills (\n id TEXT PRIMARY KEY,\n version TEXT NOT NULL,\n name TEXT NOT NULL,\n description TEXT NOT NULL,\n instructions TEXT NOT NULL DEFAULT '',\n related TEXT,\n author TEXT NOT NULL,\n tags TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n status TEXT NOT NULL,\n parent_version TEXT,\n derived_from TEXT,\n metrics TEXT NOT NULL,\n source TEXT,\n taxonomy TEXT,\n external_source TEXT\n )\n `);\n\n // Skill versions table (stores all versions)\n db.exec(`\n CREATE TABLE IF NOT EXISTS skill_versions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n skill_id TEXT NOT NULL,\n version TEXT NOT NULL,\n skill_data TEXT NOT NULL,\n changelog TEXT NOT NULL,\n created_at TEXT NOT NULL,\n content_hash TEXT NOT NULL,\n UNIQUE(skill_id, version)\n )\n `);\n\n // Lineage table\n db.exec(`\n CREATE TABLE IF NOT EXISTS skill_lineage (\n skill_id TEXT PRIMARY KEY,\n root_id TEXT NOT NULL\n )\n `);\n\n // Forks table\n db.exec(`\n CREATE TABLE IF NOT EXISTS skill_forks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n root_skill_id TEXT NOT NULL,\n forked_skill_id TEXT NOT NULL,\n from_version TEXT NOT NULL,\n reason TEXT NOT NULL,\n forked_at TEXT NOT NULL,\n FOREIGN KEY (root_skill_id) REFERENCES skill_lineage(skill_id)\n )\n `);\n\n // Create indexes\n db.exec(`\n CREATE INDEX IF NOT EXISTS idx_skills_status ON skills(status);\n CREATE INDEX IF NOT EXISTS idx_skills_author ON skills(author);\n CREATE INDEX IF NOT EXISTS idx_skills_updated ON skills(updated_at);\n CREATE INDEX IF NOT EXISTS idx_versions_skill ON skill_versions(skill_id);\n `);\n\n // Full-text search virtual table (standalone, not tied to skills table)\n if (this.config.enableFTS) {\n db.exec(`\n CREATE VIRTUAL TABLE IF NOT EXISTS skills_fts USING fts5(\n skill_id,\n name,\n description,\n instructions,\n tags\n )\n `);\n }\n\n // Taxonomy nodes table (for skill classification hierarchy)\n db.exec(`\n CREATE TABLE IF NOT EXISTS taxonomy_nodes (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n description TEXT,\n parent_id TEXT REFERENCES taxonomy_nodes(id),\n path TEXT NOT NULL,\n skill_count INTEGER DEFAULT 0,\n created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Skill taxonomy placements (links skills to taxonomy nodes)\n db.exec(`\n CREATE TABLE IF NOT EXISTS skill_taxonomy_placements (\n skill_id TEXT NOT NULL,\n node_id TEXT NOT NULL,\n is_primary INTEGER DEFAULT 0,\n confidence REAL,\n reasoning TEXT,\n created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (skill_id, node_id)\n )\n `);\n\n // Skill relationships table\n db.exec(`\n CREATE TABLE IF NOT EXISTS skill_relationships (\n source_skill_id TEXT NOT NULL,\n target_skill_id TEXT NOT NULL,\n type TEXT NOT NULL,\n confidence REAL NOT NULL,\n reasoning TEXT,\n created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (source_skill_id, target_skill_id, type)\n )\n `);\n\n // External sources tracking table\n db.exec(`\n CREATE TABLE IF NOT EXISTS skill_sources (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL,\n url TEXT,\n last_scraped TEXT,\n etag TEXT,\n skill_count INTEGER DEFAULT 0\n )\n `);\n\n // Create indexes for new tables\n db.exec(`\n CREATE INDEX IF NOT EXISTS idx_taxonomy_parent ON taxonomy_nodes(parent_id);\n CREATE INDEX IF NOT EXISTS idx_taxonomy_path ON taxonomy_nodes(path);\n CREATE INDEX IF NOT EXISTS idx_placements_skill ON skill_taxonomy_placements(skill_id);\n CREATE INDEX IF NOT EXISTS idx_placements_node ON skill_taxonomy_placements(node_id);\n CREATE INDEX IF NOT EXISTS idx_relationships_source ON skill_relationships(source_skill_id);\n CREATE INDEX IF NOT EXISTS idx_relationships_target ON skill_relationships(target_skill_id);\n `);\n\n // Set initial schema version if not exists\n const version = db.prepare('SELECT version FROM schema_version').get() as { version: number } | undefined;\n if (!version) {\n db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(SCHEMA_VERSION);\n }\n }\n\n private runMigrations(): void {\n const db = this.getDb();\n const row = db.prepare('SELECT version FROM schema_version').get() as { version: number };\n const currentVersion = row?.version || 0;\n\n // Add migrations here as schema evolves\n if (currentVersion < SCHEMA_VERSION) {\n // Migration to version 2: Add taxonomy and external_source columns\n if (currentVersion < 2) {\n // Add new columns to skills table (if they don't exist)\n try {\n db.exec('ALTER TABLE skills ADD COLUMN taxonomy TEXT');\n } catch {\n // Column already exists\n }\n try {\n db.exec('ALTER TABLE skills ADD COLUMN external_source TEXT');\n } catch {\n // Column already exists\n }\n }\n\n // Migration to version 3: Replace structured fields with instructions\n if (currentVersion < 3) {\n try {\n db.exec('ALTER TABLE skills ADD COLUMN instructions TEXT NOT NULL DEFAULT \\'\\'');\n } catch {\n // Column already exists\n }\n try {\n db.exec('ALTER TABLE skills ADD COLUMN related TEXT');\n } catch {\n // Column already exists\n }\n // Migrate existing data: concatenate old fields into instructions\n try {\n db.exec(`\n UPDATE skills SET instructions =\n COALESCE(problem, '') || CHAR(10) || CHAR(10) ||\n COALESCE(solution, '') || CHAR(10) || CHAR(10) ||\n COALESCE(verification, '')\n WHERE instructions = ''\n `);\n } catch {\n // Best-effort migration\n }\n // Rebuild FTS table with new schema\n if (this.config.enableFTS) {\n try {\n db.exec('DROP TABLE IF EXISTS skills_fts');\n db.exec(`\n CREATE VIRTUAL TABLE skills_fts USING fts5(\n skill_id, name, description, instructions, tags\n )\n `);\n // Re-index existing skills\n const rows = db.prepare('SELECT id, name, description, instructions, tags FROM skills').all() as Array<{id: string; name: string; description: string; instructions: string; tags: string}>;\n const insertFts = db.prepare('INSERT INTO skills_fts (skill_id, name, description, instructions, tags) VALUES (?, ?, ?, ?, ?)');\n for (const row of rows) {\n const tags = (() => { try { return JSON.parse(row.tags).join(' '); } catch { return row.tags; } })();\n insertFts.run(row.id, row.name, row.description, row.instructions, tags);\n }\n } catch {\n // FTS rebuild is best-effort\n }\n }\n }\n\n db.prepare('UPDATE schema_version SET version = ?').run(SCHEMA_VERSION);\n }\n }\n\n private getDb(): DatabaseType {\n if (!this.db) {\n throw new Error('Database not initialized. Call initialize() first.');\n }\n return this.db;\n }\n\n async saveSkill(skill: Skill): Promise<void> {\n this.ensureInitialized();\n const db = this.getDb();\n\n const stmt = db.prepare(`\n INSERT OR REPLACE INTO skills (\n id, version, name, description, instructions, related, author, tags,\n created_at, updated_at, status, parent_version, derived_from, metrics,\n source, taxonomy, external_source\n ) VALUES (\n ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?\n )\n `);\n\n stmt.run(\n skill.id,\n skill.version,\n skill.name,\n skill.description,\n skill.instructions,\n skill.related ? JSON.stringify(skill.related) : null,\n skill.author,\n JSON.stringify(skill.tags),\n skill.createdAt.toISOString(),\n skill.updatedAt.toISOString(),\n skill.status,\n skill.parentVersion || null,\n skill.derivedFrom ? JSON.stringify(skill.derivedFrom) : null,\n JSON.stringify(skill.metrics),\n skill.source ? JSON.stringify(skill.source) : null,\n skill.taxonomy ? JSON.stringify(skill.taxonomy) : null,\n skill.externalSource ? JSON.stringify({\n ...skill.externalSource,\n scrapedAt: skill.externalSource.scrapedAt.toISOString(),\n }) : null\n );\n\n // Save relationships if present\n if (skill.relationships && skill.relationships.length > 0) {\n await this.saveSkillRelationships(skill.id, skill.relationships);\n }\n\n // Update FTS index\n if (this.config.enableFTS) {\n this.updateFTSIndex(skill);\n }\n\n // Save version snapshot\n await this.saveVersionSnapshot(skill);\n\n // Update lineage\n this.updateLineage(skill);\n }\n\n private updateFTSIndex(skill: Skill): void {\n const db = this.getDb();\n\n // Delete existing FTS entry\n db.prepare('DELETE FROM skills_fts WHERE skill_id = ?').run(skill.id);\n\n // Insert new FTS entry\n const tags = skill.tags.join(' ');\n\n db.prepare(`\n INSERT INTO skills_fts (skill_id, name, description, instructions, tags)\n VALUES (?, ?, ?, ?, ?)\n `).run(skill.id, skill.name, skill.description, skill.instructions, tags);\n }\n\n private async saveVersionSnapshot(skill: Skill): Promise<void> {\n const db = this.getDb();\n\n // Check if this version already exists\n const existing = db.prepare(\n 'SELECT id FROM skill_versions WHERE skill_id = ? AND version = ?'\n ).get(skill.id, skill.version);\n\n if (existing) {\n // Update existing version\n db.prepare(`\n UPDATE skill_versions\n SET skill_data = ?, content_hash = ?\n WHERE skill_id = ? AND version = ?\n `).run(\n JSON.stringify(this.serializeSkill(skill)),\n this.hashSkill(skill),\n skill.id,\n skill.version\n );\n } else {\n // Insert new version\n db.prepare(`\n INSERT INTO skill_versions (skill_id, version, skill_data, changelog, created_at, content_hash)\n VALUES (?, ?, ?, ?, ?, ?)\n `).run(\n skill.id,\n skill.version,\n JSON.stringify(this.serializeSkill(skill)),\n '', // Changelog can be added via separate method\n skill.createdAt.toISOString(),\n this.hashSkill(skill)\n );\n }\n }\n\n private updateLineage(skill: Skill): void {\n const db = this.getDb();\n\n // Ensure lineage entry exists\n const existing = db.prepare(\n 'SELECT skill_id FROM skill_lineage WHERE skill_id = ?'\n ).get(skill.id);\n\n if (!existing) {\n db.prepare(\n 'INSERT INTO skill_lineage (skill_id, root_id) VALUES (?, ?)'\n ).run(skill.id, skill.id);\n }\n }\n\n async getSkill(id: string, version?: string): Promise<Skill | null> {\n this.ensureInitialized();\n const db = this.getDb();\n\n if (version) {\n // Get specific version\n const row = db.prepare(\n 'SELECT skill_data FROM skill_versions WHERE skill_id = ? AND version = ?'\n ).get(id, version) as { skill_data: string } | undefined;\n\n if (!row) return null;\n return this.deserializeSkill(JSON.parse(row.skill_data));\n }\n\n // Get latest version\n const row = db.prepare('SELECT * FROM skills WHERE id = ?').get(id) as SkillRow | undefined;\n if (!row) return null;\n\n return this.rowToSkill(row);\n }\n\n async listSkills(filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n const db = this.getDb();\n\n let sql = 'SELECT * FROM skills WHERE 1=1';\n const params: unknown[] = [];\n\n if (filter?.status && filter.status.length > 0) {\n sql += ` AND status IN (${filter.status.map(() => '?').join(',')})`;\n params.push(...filter.status);\n }\n\n if (filter?.author) {\n sql += ' AND author = ?';\n params.push(filter.author);\n }\n\n if (filter?.minSuccessRate !== undefined) {\n sql += ' AND json_extract(metrics, \\'$.successRate\\') >= ?';\n params.push(filter.minSuccessRate);\n }\n\n if (filter?.createdAfter) {\n sql += ' AND created_at >= ?';\n params.push(filter.createdAfter.toISOString());\n }\n\n if (filter?.createdBefore) {\n sql += ' AND created_at <= ?';\n params.push(filter.createdBefore.toISOString());\n }\n\n sql += ' ORDER BY updated_at DESC';\n\n const rows = db.prepare(sql).all(...params) as SkillRow[];\n let skills = rows.map((row) => this.rowToSkill(row));\n\n // Tag filter needs post-processing due to JSON array\n if (filter?.tags && filter.tags.length > 0) {\n skills = skills.filter((skill) =>\n filter.tags!.some((tag) => skill.tags.includes(tag))\n );\n }\n\n return skills;\n }\n\n async deleteSkill(id: string, version?: string): Promise<boolean> {\n this.ensureInitialized();\n const db = this.getDb();\n\n if (version) {\n // Delete specific version\n const result = db.prepare(\n 'DELETE FROM skill_versions WHERE skill_id = ? AND version = ?'\n ).run(id, version);\n return result.changes > 0;\n }\n\n // Delete all versions and the skill\n const transaction = db.transaction(() => {\n db.prepare('DELETE FROM skill_versions WHERE skill_id = ?').run(id);\n db.prepare('DELETE FROM skill_forks WHERE root_skill_id = ? OR forked_skill_id = ?').run(id, id);\n db.prepare('DELETE FROM skill_lineage WHERE skill_id = ?').run(id);\n // Delete from FTS index\n if (this.config.enableFTS) {\n db.prepare('DELETE FROM skills_fts WHERE skill_id = ?').run(id);\n }\n // Delete taxonomy placements\n db.prepare('DELETE FROM skill_taxonomy_placements WHERE skill_id = ?').run(id);\n // Delete relationships\n db.prepare('DELETE FROM skill_relationships WHERE source_skill_id = ? OR target_skill_id = ?').run(id, id);\n const result = db.prepare('DELETE FROM skills WHERE id = ?').run(id);\n return result.changes > 0;\n });\n\n return transaction();\n }\n\n async getVersionHistory(skillId: string): Promise<SkillVersion[]> {\n this.ensureInitialized();\n const db = this.getDb();\n\n const rows = db.prepare(`\n SELECT skill_id, version, skill_data, changelog, created_at, content_hash\n FROM skill_versions\n WHERE skill_id = ?\n ORDER BY created_at ASC\n `).all(skillId) as VersionRow[];\n\n return rows.map((row) => ({\n skillId: row.skill_id,\n version: row.version,\n skill: this.deserializeSkill(JSON.parse(row.skill_data)),\n changelog: row.changelog,\n createdAt: new Date(row.created_at),\n contentHash: row.content_hash,\n }));\n }\n\n async getLineage(skillId: string): Promise<SkillLineage | null> {\n this.ensureInitialized();\n const db = this.getDb();\n\n const lineageRow = db.prepare(\n 'SELECT * FROM skill_lineage WHERE skill_id = ?'\n ).get(skillId) as { skill_id: string; root_id: string } | undefined;\n\n if (!lineageRow) return null;\n\n const versions = await this.getVersionHistory(skillId);\n\n const forkRows = db.prepare(`\n SELECT forked_skill_id, from_version, reason, forked_at\n FROM skill_forks\n WHERE root_skill_id = ?\n `).all(skillId) as ForkRow[];\n\n const forks: SkillFork[] = forkRows.map((row) => ({\n forkedSkillId: row.forked_skill_id,\n fromVersion: row.from_version,\n reason: row.reason,\n forkedAt: new Date(row.forked_at),\n }));\n\n return {\n rootId: lineageRow.root_id,\n versions,\n forks,\n };\n }\n\n async searchSkills(query: string): Promise<Skill[]> {\n this.ensureInitialized();\n const db = this.getDb();\n\n if (this.config.enableFTS) {\n // Use FTS5 for search\n const rows = db.prepare(`\n SELECT s.* FROM skills s\n JOIN skills_fts fts ON s.id = fts.skill_id\n WHERE skills_fts MATCH ?\n ORDER BY rank\n `).all(query) as SkillRow[];\n\n return rows.map((row) => this.rowToSkill(row));\n }\n\n // Fallback to basic text search\n const allSkills = await this.listSkills();\n return this.textSearch(allSkills, query);\n }\n\n /**\n * Add a fork record\n */\n async addFork(\n rootSkillId: string,\n forkedSkillId: string,\n fromVersion: string,\n reason: string\n ): Promise<void> {\n this.ensureInitialized();\n const db = this.getDb();\n\n db.prepare(`\n INSERT INTO skill_forks (root_skill_id, forked_skill_id, from_version, reason, forked_at)\n VALUES (?, ?, ?, ?, ?)\n `).run(rootSkillId, forkedSkillId, fromVersion, reason, new Date().toISOString());\n }\n\n /**\n * Update changelog for a version\n */\n async updateChangelog(skillId: string, version: string, changelog: string): Promise<void> {\n this.ensureInitialized();\n const db = this.getDb();\n\n db.prepare(`\n UPDATE skill_versions SET changelog = ? WHERE skill_id = ? AND version = ?\n `).run(changelog, skillId, version);\n }\n\n /**\n * Get skills by tag\n */\n async getSkillsByTag(tag: string): Promise<Skill[]> {\n return this.listSkills({ tags: [tag] });\n }\n\n /**\n * Get all tags with counts\n */\n async getTagCounts(): Promise<Map<string, number>> {\n this.ensureInitialized();\n const db = this.getDb();\n\n const rows = db.prepare('SELECT tags FROM skills').all() as { tags: string }[];\n const counts = new Map<string, number>();\n\n for (const row of rows) {\n const tags = JSON.parse(row.tags) as string[];\n for (const tag of tags) {\n counts.set(tag, (counts.get(tag) || 0) + 1);\n }\n }\n\n return counts;\n }\n\n /**\n * Get skill count by status\n */\n async getStatusCounts(): Promise<Map<SkillStatus, number>> {\n this.ensureInitialized();\n const db = this.getDb();\n\n const rows = db.prepare(`\n SELECT status, COUNT(*) as count FROM skills GROUP BY status\n `).all() as { status: SkillStatus; count: number }[];\n\n const counts = new Map<SkillStatus, number>();\n for (const row of rows) {\n counts.set(row.status, row.count);\n }\n\n return counts;\n }\n\n /**\n * Close the database connection\n */\n close(): void {\n if (this.db) {\n this.db.close();\n this.db = null;\n this.initialized = false;\n }\n }\n\n /**\n * Export all skills for backup\n */\n async exportAll(): Promise<Skill[]> {\n return this.listSkills();\n }\n\n /**\n * Import skills from backup\n */\n async importSkills(skills: Skill[]): Promise<{ imported: number; failed: number }> {\n let imported = 0;\n let failed = 0;\n\n for (const skill of skills) {\n try {\n await this.saveSkill(skill);\n imported++;\n } catch {\n failed++;\n }\n }\n\n return { imported, failed };\n }\n\n // =========================================================================\n // TAXONOMY METHODS\n // =========================================================================\n\n /**\n * Get or create a taxonomy node\n */\n async ensureTaxonomyNode(path: string[]): Promise<string> {\n this.ensureInitialized();\n const db = this.getDb();\n\n const pathStr = path.join('/');\n const existing = db.prepare('SELECT id FROM taxonomy_nodes WHERE path = ?').get(pathStr) as { id: string } | undefined;\n\n if (existing) return existing.id;\n\n // Create the node\n const id = `node-${pathStr.replace(/\\//g, '-').toLowerCase()}`;\n const name = path[path.length - 1] || 'Root';\n const parentPath = path.slice(0, -1);\n let parentId: string | null = null;\n\n if (parentPath.length > 0) {\n parentId = await this.ensureTaxonomyNode(parentPath);\n }\n\n db.prepare(`\n INSERT INTO taxonomy_nodes (id, name, parent_id, path, created_at)\n VALUES (?, ?, ?, ?, ?)\n `).run(id, name, parentId, pathStr, new Date().toISOString());\n\n return id;\n }\n\n /**\n * Place a skill in the taxonomy\n */\n async placeInTaxonomy(\n skillId: string,\n taxonomy: SkillTaxonomy\n ): Promise<void> {\n this.ensureInitialized();\n const db = this.getDb();\n\n // Ensure primary node exists and create placement\n const primaryNodeId = await this.ensureTaxonomyNode(taxonomy.primaryPath);\n\n db.prepare(`\n INSERT OR REPLACE INTO skill_taxonomy_placements\n (skill_id, node_id, is_primary, confidence, created_at)\n VALUES (?, ?, 1, ?, ?)\n `).run(skillId, primaryNodeId, taxonomy.confidence || null, new Date().toISOString());\n\n // Update skill count\n db.prepare('UPDATE taxonomy_nodes SET skill_count = skill_count + 1 WHERE id = ?').run(primaryNodeId);\n\n // Handle secondary paths\n if (taxonomy.secondaryPaths) {\n for (const secondaryPath of taxonomy.secondaryPaths) {\n const secondaryNodeId = await this.ensureTaxonomyNode(secondaryPath);\n db.prepare(`\n INSERT OR IGNORE INTO skill_taxonomy_placements\n (skill_id, node_id, is_primary, created_at)\n VALUES (?, ?, 0, ?)\n `).run(skillId, secondaryNodeId, new Date().toISOString());\n }\n }\n }\n\n /**\n * Get taxonomy tree\n */\n async getTaxonomyTree(rootPath?: string[]): Promise<TaxonomyTreeNode[]> {\n this.ensureInitialized();\n const db = this.getDb();\n\n let sql = 'SELECT * FROM taxonomy_nodes';\n const params: string[] = [];\n\n if (rootPath && rootPath.length > 0) {\n const pathPrefix = rootPath.join('/');\n sql += ' WHERE path LIKE ? OR path = ?';\n params.push(`${pathPrefix}/%`, pathPrefix);\n }\n\n sql += ' ORDER BY path';\n\n const rows = db.prepare(sql).all(...params) as TaxonomyNodeRow[];\n\n // Build tree structure\n const nodeMap = new Map<string, TaxonomyTreeNode>();\n const roots: TaxonomyTreeNode[] = [];\n\n for (const row of rows) {\n const node: TaxonomyTreeNode = {\n id: row.id,\n name: row.name,\n path: row.path.split('/'),\n skillCount: row.skill_count,\n children: [],\n };\n nodeMap.set(row.id, node);\n\n if (row.parent_id && nodeMap.has(row.parent_id)) {\n nodeMap.get(row.parent_id)!.children.push(node);\n } else {\n roots.push(node);\n }\n }\n\n return roots;\n }\n\n /**\n * Get skills in a taxonomy node\n */\n async getSkillsInTaxonomyNode(nodeId: string): Promise<Skill[]> {\n this.ensureInitialized();\n const db = this.getDb();\n\n const rows = db.prepare(`\n SELECT s.* FROM skills s\n JOIN skill_taxonomy_placements p ON s.id = p.skill_id\n WHERE p.node_id = ?\n `).all(nodeId) as SkillRow[];\n\n return rows.map(row => this.rowToSkill(row));\n }\n\n // =========================================================================\n // RELATIONSHIP METHODS\n // =========================================================================\n\n /**\n * Save skill relationships\n */\n private async saveSkillRelationships(skillId: string, relationships: SkillRelationship[]): Promise<void> {\n const db = this.getDb();\n\n // Clear existing relationships for this skill\n db.prepare('DELETE FROM skill_relationships WHERE source_skill_id = ?').run(skillId);\n\n // Insert new relationships\n const stmt = db.prepare(`\n INSERT OR REPLACE INTO skill_relationships\n (source_skill_id, target_skill_id, type, confidence, reasoning, created_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `);\n\n for (const rel of relationships) {\n stmt.run(\n skillId,\n rel.targetSkillId,\n rel.type,\n rel.confidence,\n rel.reasoning || null,\n new Date().toISOString()\n );\n }\n }\n\n /**\n * Add a relationship between skills\n */\n async addRelationship(\n sourceSkillId: string,\n targetSkillId: string,\n type: SkillRelationship['type'],\n confidence: number,\n reasoning?: string\n ): Promise<void> {\n this.ensureInitialized();\n const db = this.getDb();\n\n db.prepare(`\n INSERT OR REPLACE INTO skill_relationships\n (source_skill_id, target_skill_id, type, confidence, reasoning, created_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `).run(sourceSkillId, targetSkillId, type, confidence, reasoning || null, new Date().toISOString());\n }\n\n /**\n * Get relationships for a skill\n */\n async getRelationships(skillId: string): Promise<SkillRelationship[]> {\n this.ensureInitialized();\n const db = this.getDb();\n\n const rows = db.prepare(`\n SELECT target_skill_id, type, confidence, reasoning\n FROM skill_relationships\n WHERE source_skill_id = ?\n `).all(skillId) as RelationshipRow[];\n\n return rows.map(row => ({\n targetSkillId: row.target_skill_id,\n type: row.type as SkillRelationship['type'],\n confidence: row.confidence,\n reasoning: row.reasoning || undefined,\n }));\n }\n\n /**\n * Get skills that depend on a given skill\n */\n async getDependentSkills(skillId: string): Promise<Skill[]> {\n this.ensureInitialized();\n const db = this.getDb();\n\n const rows = db.prepare(`\n SELECT s.* FROM skills s\n JOIN skill_relationships r ON s.id = r.source_skill_id\n WHERE r.target_skill_id = ? AND r.type = 'depends_on'\n `).all(skillId) as SkillRow[];\n\n return rows.map(row => this.rowToSkill(row));\n }\n\n /**\n * Get related skills (any relationship type)\n */\n async getRelatedSkills(skillId: string): Promise<Array<{ skill: Skill; relationship: SkillRelationship }>> {\n this.ensureInitialized();\n const db = this.getDb();\n\n const rows = db.prepare(`\n SELECT s.*, r.type, r.confidence, r.reasoning\n FROM skills s\n JOIN skill_relationships r ON s.id = r.target_skill_id\n WHERE r.source_skill_id = ?\n `).all(skillId) as (SkillRow & { type: string; confidence: number; reasoning: string | null })[];\n\n return rows.map(row => ({\n skill: this.rowToSkill(row),\n relationship: {\n targetSkillId: row.id,\n type: row.type as SkillRelationship['type'],\n confidence: row.confidence,\n reasoning: row.reasoning || undefined,\n },\n }));\n }\n\n // =========================================================================\n // HELPER METHODS\n // =========================================================================\n\n private rowToSkill(row: SkillRow): Skill {\n const externalSource = row.external_source ? JSON.parse(row.external_source) : undefined;\n\n return {\n id: row.id,\n version: row.version,\n name: row.name,\n description: row.description,\n instructions: row.instructions,\n related: row.related ? JSON.parse(row.related) : undefined,\n author: row.author,\n tags: JSON.parse(row.tags),\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n status: row.status as SkillStatus,\n parentVersion: row.parent_version || undefined,\n derivedFrom: row.derived_from ? JSON.parse(row.derived_from) : undefined,\n metrics: JSON.parse(row.metrics),\n source: row.source ? JSON.parse(row.source) : undefined,\n taxonomy: row.taxonomy ? JSON.parse(row.taxonomy) : undefined,\n externalSource: externalSource ? {\n ...externalSource,\n scrapedAt: new Date(externalSource.scrapedAt),\n } : undefined,\n };\n }\n\n private serializeSkill(skill: Skill): Record<string, unknown> {\n return {\n ...skill,\n createdAt: skill.createdAt.toISOString(),\n updatedAt: skill.updatedAt.toISOString(),\n source: skill.source\n ? {\n ...skill.source,\n importedAt: skill.source.importedAt.toISOString(),\n }\n : undefined,\n metrics: {\n ...skill.metrics,\n lastUsed: skill.metrics.lastUsed?.toISOString(),\n },\n };\n }\n\n private deserializeSkill(data: Record<string, unknown>): Skill {\n return {\n ...data,\n createdAt: new Date(data.createdAt as string),\n updatedAt: new Date(data.updatedAt as string),\n source: data.source\n ? {\n ...(data.source as Record<string, unknown>),\n importedAt: new Date((data.source as Record<string, unknown>).importedAt as string),\n }\n : undefined,\n metrics: {\n ...(data.metrics as Record<string, unknown>),\n lastUsed: (data.metrics as Record<string, unknown>).lastUsed\n ? new Date((data.metrics as Record<string, unknown>).lastUsed as string)\n : undefined,\n },\n } as Skill;\n }\n\n private hashSkill(skill: Skill): string {\n const content = JSON.stringify({\n instructions: skill.instructions,\n });\n let hash = 0;\n for (let i = 0; i < content.length; i++) {\n const char = content.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(16);\n }\n}\n\n// Type definitions for database rows\ninterface SkillRow {\n id: string;\n version: string;\n name: string;\n description: string;\n instructions: string;\n related: string | null;\n author: string;\n tags: string;\n created_at: string;\n updated_at: string;\n status: string;\n parent_version: string | null;\n derived_from: string | null;\n metrics: string;\n source: string | null;\n taxonomy: string | null;\n external_source: string | null;\n}\n\ninterface VersionRow {\n skill_id: string;\n version: string;\n skill_data: string;\n changelog: string;\n created_at: string;\n content_hash: string;\n}\n\ninterface ForkRow {\n forked_skill_id: string;\n from_version: string;\n reason: string;\n forked_at: string;\n}\n\ninterface TaxonomyNodeRow {\n id: string;\n name: string;\n description: string | null;\n parent_id: string | null;\n path: string;\n skill_count: number;\n created_at: string;\n}\n\ninterface RelationshipRow {\n target_skill_id: string;\n type: string;\n confidence: number;\n reasoning: string | null;\n}\n\n/**\n * Taxonomy tree node (for API responses)\n */\nexport interface TaxonomyTreeNode {\n id: string;\n name: string;\n path: string[];\n skillCount: number;\n children: TaxonomyTreeNode[];\n}\n","/**\n * AGENTS.md Integration Types\n */\n\nimport type { Skill } from '../types.js';\n\n/**\n * Format for skill descriptions in AGENTS.md\n */\nexport type SkillFormat = 'xml' | 'markdown' | 'json';\n\n/**\n * Configuration for AGENTS.md generation\n */\nexport interface AgentsGeneratorConfig {\n /** Output format for skills (default: 'xml') */\n format?: SkillFormat;\n /** Include skill IDs as data attributes (default: true) */\n includeIds?: boolean;\n /** Include version information (default: true) */\n includeVersions?: boolean;\n /** Group skills by tags (default: false) */\n groupByTags?: boolean;\n /** Custom header content */\n header?: string;\n /** Custom footer content */\n footer?: string;\n /** Filter skills to include */\n filter?: SkillSelector;\n}\n\n/**\n * Skill selector for filtering which skills to include\n */\nexport interface SkillSelector {\n /** Include only these skill IDs */\n ids?: string[];\n /** Include skills with any of these tags */\n tags?: string[];\n /** Include skills matching this status */\n status?: ('active' | 'experimental')[];\n /** Minimum success rate to include */\n minSuccessRate?: number;\n /** Maximum number of skills to include */\n limit?: number;\n}\n\n/**\n * Parsed skill from AGENTS.md\n */\nexport interface ParsedAgentSkill {\n /** Skill ID (if present) */\n id?: string;\n /** Skill name */\n name: string;\n /** Skill description */\n description: string;\n /** Instructions content */\n instructions?: string;\n /** Problem this skill solves (legacy, used during parsing) */\n problem?: string;\n /** Solution steps (legacy, used during parsing) */\n solution?: string;\n /** Verification steps (legacy, used during parsing) */\n verification?: string;\n /** Additional notes (legacy, used during parsing) */\n notes?: string;\n /** Tags extracted from content */\n tags?: string[];\n /** Version (if present) */\n version?: string;\n /** Raw content block */\n rawContent: string;\n}\n\n/**\n * Result of parsing AGENTS.md\n */\nexport interface ParsedAgentsFile {\n /** Header content before skills */\n header?: string;\n /** Parsed skills */\n skills: ParsedAgentSkill[];\n /** Footer content after skills */\n footer?: string;\n /** Warnings during parsing */\n warnings: string[];\n}\n\n/**\n * Sync result\n */\nexport interface SyncResult {\n /** Skills added to bank */\n added: string[];\n /** Skills updated in bank */\n updated: string[];\n /** Skills removed (in bank but not in AGENTS.md) */\n removed: string[];\n /** Skills unchanged */\n unchanged: string[];\n /** Warnings/issues */\n warnings: string[];\n}\n\n/**\n * Default configuration\n */\nexport const DEFAULT_AGENTS_CONFIG: Required<Omit<AgentsGeneratorConfig, 'header' | 'footer' | 'filter'>> = {\n format: 'xml',\n includeIds: true,\n includeVersions: true,\n groupByTags: false,\n};\n","/**\n * AGENTS.md Generator\n *\n * Generates AGENTS.md content from skill bank for Claude Code integration.\n */\n\nimport type { Skill, StorageAdapter } from '../types.js';\nimport type { AgentsGeneratorConfig, SkillSelector, SkillFormat } from './types.js';\nimport { DEFAULT_AGENTS_CONFIG } from './types.js';\n\n/**\n * Generate AGENTS.md content from skills\n */\nexport class AgentsGenerator {\n private config: Required<Omit<AgentsGeneratorConfig, 'header' | 'footer' | 'filter'>> & AgentsGeneratorConfig;\n\n constructor(config?: AgentsGeneratorConfig) {\n this.config = { ...DEFAULT_AGENTS_CONFIG, ...config };\n }\n\n /**\n * Generate AGENTS.md content from a skill bank\n */\n async generate(storage: StorageAdapter): Promise<string> {\n // Get all skills\n let skills = await storage.listSkills({\n status: this.config.filter?.status || ['active'],\n });\n\n // Apply filters\n skills = this.filterSkills(skills, this.config.filter);\n\n // Sort skills\n skills.sort((a, b) => a.name.localeCompare(b.name));\n\n // Generate content\n const sections: string[] = [];\n\n // Header\n if (this.config.header) {\n sections.push(this.config.header);\n } else {\n sections.push(this.generateDefaultHeader());\n }\n\n // Skills\n if (this.config.groupByTags) {\n sections.push(this.generateGroupedSkills(skills));\n } else {\n sections.push(this.generateSkillsList(skills));\n }\n\n // Footer\n if (this.config.footer) {\n sections.push(this.config.footer);\n }\n\n return sections.join('\\n\\n');\n }\n\n /**\n * Generate content for a single skill\n */\n generateSkill(skill: Skill): string {\n switch (this.config.format) {\n case 'xml':\n return this.generateXmlSkill(skill);\n case 'markdown':\n return this.generateMarkdownSkill(skill);\n case 'json':\n return this.generateJsonSkill(skill);\n default:\n return this.generateXmlSkill(skill);\n }\n }\n\n /**\n * Generate skills list\n */\n private generateSkillsList(skills: Skill[]): string {\n return skills.map((skill) => this.generateSkill(skill)).join('\\n\\n');\n }\n\n /**\n * Generate skills grouped by tags\n */\n private generateGroupedSkills(skills: Skill[]): string {\n // Collect all tags\n const tagGroups = new Map<string, Skill[]>();\n const untagged: Skill[] = [];\n\n for (const skill of skills) {\n if (skill.tags.length === 0) {\n untagged.push(skill);\n } else {\n // Add skill to first tag group (primary tag)\n const primaryTag = skill.tags[0];\n if (!tagGroups.has(primaryTag)) {\n tagGroups.set(primaryTag, []);\n }\n tagGroups.get(primaryTag)!.push(skill);\n }\n }\n\n const sections: string[] = [];\n\n // Generate sections for each tag\n const sortedTags = Array.from(tagGroups.keys()).sort();\n for (const tag of sortedTags) {\n const tagSkills = tagGroups.get(tag)!;\n sections.push(`## ${this.formatTagName(tag)}\\n\\n${this.generateSkillsList(tagSkills)}`);\n }\n\n // Add untagged skills\n if (untagged.length > 0) {\n sections.push(`## Other\\n\\n${this.generateSkillsList(untagged)}`);\n }\n\n return sections.join('\\n\\n');\n }\n\n /**\n * Generate XML format skill (Claude Code native format)\n */\n private generateXmlSkill(skill: Skill): string {\n const lines: string[] = [];\n\n // Opening tag with attributes\n const attrs: string[] = [];\n if (this.config.includeIds) {\n attrs.push(`id=\"${this.escapeXml(skill.id)}\"`);\n }\n if (this.config.includeVersions) {\n attrs.push(`version=\"${this.escapeXml(skill.version)}\"`);\n }\n\n const attrStr = attrs.length > 0 ? ` ${attrs.join(' ')}` : '';\n lines.push(`<skill${attrStr}>`);\n\n // Name\n lines.push(` <name>${this.escapeXml(skill.name)}</name>`);\n\n // Description\n if (skill.description) {\n lines.push(` <description>${this.escapeXml(skill.description)}</description>`);\n }\n\n // Instructions (content)\n if (skill.instructions) {\n lines.push(` <content>\\n${this.indentContent(skill.instructions, 4)}\\n </content>`);\n }\n\n // Tags (as metadata)\n if (skill.tags.length > 0) {\n lines.push(` <tags>${skill.tags.map((t) => this.escapeXml(t)).join(', ')}</tags>`);\n }\n\n lines.push('</skill>');\n\n return lines.join('\\n');\n }\n\n /**\n * Generate Markdown format skill\n */\n private generateMarkdownSkill(skill: Skill): string {\n const lines: string[] = [];\n\n // Heading with ID\n const idSuffix = this.config.includeIds ? ` {#${skill.id}}` : '';\n const versionSuffix = this.config.includeVersions ? ` (v${skill.version})` : '';\n lines.push(`### ${skill.name}${versionSuffix}${idSuffix}`);\n lines.push('');\n\n // Description\n if (skill.description) {\n lines.push(`*${skill.description}*`);\n lines.push('');\n }\n\n // Instructions\n if (skill.instructions) {\n lines.push(skill.instructions);\n lines.push('');\n }\n\n // Tags\n if (skill.tags.length > 0) {\n lines.push(`Tags: ${skill.tags.map((t) => `\\`${t}\\``).join(', ')}`);\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Generate JSON format skill\n */\n private generateJsonSkill(skill: Skill): string {\n const obj: Record<string, unknown> = {\n name: skill.name,\n description: skill.description,\n };\n\n if (this.config.includeIds) {\n obj.id = skill.id;\n }\n\n if (this.config.includeVersions) {\n obj.version = skill.version;\n }\n\n if (skill.instructions) {\n obj.instructions = skill.instructions;\n }\n\n if (skill.tags.length > 0) {\n obj.tags = skill.tags;\n }\n\n return '```json\\n' + JSON.stringify(obj, null, 2) + '\\n```';\n }\n\n /**\n * Filter skills based on selector\n */\n private filterSkills(skills: Skill[], filter?: SkillSelector): Skill[] {\n if (!filter) return skills;\n\n let result = skills;\n\n if (filter.ids && filter.ids.length > 0) {\n result = result.filter((s) => filter.ids!.includes(s.id));\n }\n\n if (filter.tags && filter.tags.length > 0) {\n result = result.filter((s) => s.tags.some((t) => filter.tags!.includes(t)));\n }\n\n if (filter.minSuccessRate !== undefined) {\n result = result.filter((s) => s.metrics.successRate >= filter.minSuccessRate!);\n }\n\n if (filter.limit) {\n result = result.slice(0, filter.limit);\n }\n\n return result;\n }\n\n /**\n * Generate default header\n */\n private generateDefaultHeader(): string {\n return `# Agent Skills\n\nThis file contains skills for the AI agent. Each skill describes a pattern for solving a specific type of problem.\n\n---`;\n }\n\n /**\n * Format tag name for section header\n */\n private formatTagName(tag: string): string {\n return tag\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n }\n\n /**\n * Escape XML special characters\n */\n private escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n }\n\n /**\n * Indent content\n */\n private indentContent(content: string, spaces: number): string {\n const indent = ' '.repeat(spaces);\n return content\n .split('\\n')\n .map((line) => indent + line)\n .join('\\n');\n }\n}\n\n/**\n * Create an AGENTS.md generator\n */\nexport function createAgentsGenerator(config?: AgentsGeneratorConfig): AgentsGenerator {\n return new AgentsGenerator(config);\n}\n","/**\n * AGENTS.md Parser\n *\n * Parses AGENTS.md files to import skills into skill bank.\n */\n\nimport type { Skill } from '../types.js';\nimport type { ParsedAgentSkill, ParsedAgentsFile } from './types.js';\n\n/**\n * Parse AGENTS.md content\n */\nexport class AgentsParser {\n /**\n * Parse AGENTS.md content\n */\n parse(content: string): ParsedAgentsFile {\n const warnings: string[] = [];\n const skills: ParsedAgentSkill[] = [];\n\n // Try to parse as XML format first\n const xmlSkills = this.parseXmlSkills(content);\n if (xmlSkills.length > 0) {\n skills.push(...xmlSkills);\n }\n\n // Also try to parse markdown format\n const mdSkills = this.parseMarkdownSkills(content, xmlSkills);\n if (mdSkills.length > 0) {\n // Only add markdown skills that weren't already found as XML\n const existingNames = new Set(skills.map((s) => s.name.toLowerCase()));\n for (const skill of mdSkills) {\n if (!existingNames.has(skill.name.toLowerCase())) {\n skills.push(skill);\n }\n }\n }\n\n // Extract header (content before first skill)\n const header = this.extractHeader(content, skills);\n\n // Extract footer (content after last skill)\n const footer = this.extractFooter(content, skills);\n\n if (skills.length === 0) {\n warnings.push('No skills found in AGENTS.md');\n }\n\n return { header, skills, footer, warnings };\n }\n\n /**\n * Convert parsed skill to Skill type\n */\n toSkill(parsed: ParsedAgentSkill, defaults?: Partial<Skill>): Skill {\n const now = new Date();\n const id = parsed.id || this.generateId(parsed.name);\n\n // Use instructions directly if available, otherwise build from legacy fields\n let instructions = parsed.instructions || '';\n if (!instructions) {\n const instructionParts: string[] = [];\n if (parsed.problem) instructionParts.push(parsed.problem);\n if (parsed.solution) instructionParts.push(parsed.solution);\n if (parsed.verification) instructionParts.push(parsed.verification);\n if (parsed.notes) instructionParts.push(parsed.notes);\n instructions = instructionParts.length > 0\n ? instructionParts.join('\\n\\n')\n : '';\n }\n\n return {\n id,\n name: parsed.name,\n version: parsed.version || '1.0.0',\n description: parsed.description || '',\n instructions,\n author: defaults?.author || 'imported',\n tags: parsed.tags || [],\n createdAt: defaults?.createdAt || now,\n updatedAt: now,\n status: 'active',\n metrics: defaults?.metrics || {\n usageCount: 0,\n successRate: 0,\n feedbackScores: [],\n },\n source: {\n type: 'imported',\n location: 'AGENTS.md',\n importedAt: now,\n },\n ...defaults,\n };\n }\n\n /**\n * Parse XML format skills\n */\n private parseXmlSkills(content: string): ParsedAgentSkill[] {\n const skills: ParsedAgentSkill[] = [];\n\n // Match <skill> tags\n const skillRegex = /<skill([^>]*)>([\\s\\S]*?)<\\/skill>/gi;\n let match;\n\n while ((match = skillRegex.exec(content)) !== null) {\n const attrs = match[1];\n const body = match[2];\n\n const skill: ParsedAgentSkill = {\n rawContent: match[0],\n name: this.extractXmlTag(body, 'name') || 'Unnamed Skill',\n description: this.extractXmlTag(body, 'description') || '',\n };\n\n // Extract ID from attributes\n const idMatch = /id=\"([^\"]+)\"/.exec(attrs);\n if (idMatch) {\n skill.id = idMatch[1];\n }\n\n // Extract version from attributes\n const versionMatch = /version=\"([^\"]+)\"/.exec(attrs);\n if (versionMatch) {\n skill.version = versionMatch[1];\n }\n\n // Extract instructions from <content> tag (new format) or legacy fields\n const contentTag = this.extractXmlTag(body, 'content');\n if (contentTag) {\n skill.instructions = contentTag;\n } else {\n // Legacy format: extract structured fields and combine\n skill.problem = this.extractXmlTag(body, 'problem');\n skill.solution = this.extractXmlTag(body, 'solution');\n skill.verification = this.extractXmlTag(body, 'verification');\n skill.notes = this.extractXmlTag(body, 'notes');\n }\n\n // Extract tags\n const tagsStr = this.extractXmlTag(body, 'tags');\n if (tagsStr) {\n skill.tags = tagsStr.split(',').map((t) => t.trim()).filter((t) => t);\n }\n\n skills.push(skill);\n }\n\n return skills;\n }\n\n /**\n * Parse Markdown format skills\n */\n private parseMarkdownSkills(content: string, existingSkills: ParsedAgentSkill[]): ParsedAgentSkill[] {\n const skills: ParsedAgentSkill[] = [];\n\n // Match ### headers as skill names\n const sections = content.split(/(?=^###\\s)/m);\n\n for (const section of sections) {\n const headerMatch = /^###\\s+(.+?)(?:\\s+\\(v([\\d.]+)\\))?(?:\\s+\\{#([^}]+)\\})?\\s*$/m.exec(section);\n if (!headerMatch) continue;\n\n const name = headerMatch[1].trim();\n const version = headerMatch[2];\n const id = headerMatch[3];\n\n // Skip if already found in XML\n if (existingSkills.some((s) => s.name.toLowerCase() === name.toLowerCase())) {\n continue;\n }\n\n const skill: ParsedAgentSkill = {\n rawContent: section,\n name,\n description: '',\n };\n\n if (version) skill.version = version;\n if (id) skill.id = id;\n\n // Extract description (first italic line)\n const descMatch = /^\\*([^*]+)\\*$/m.exec(section);\n if (descMatch) {\n skill.description = descMatch[1];\n }\n\n // Extract content as instructions (everything after description and before Tags)\n const bodyStart = section.indexOf('\\n', section.indexOf(headerMatch[0]) + headerMatch[0].length);\n if (bodyStart >= 0) {\n let bodyContent = section.slice(bodyStart).trim();\n // Remove leading description italic\n bodyContent = bodyContent.replace(/^\\*[^*]+\\*\\s*\\n?/, '').trim();\n // Remove trailing Tags line\n bodyContent = bodyContent.replace(/\\nTags:\\s*.+$/m, '').trim();\n if (bodyContent) {\n skill.instructions = bodyContent;\n }\n }\n\n // Also try legacy format extraction for backwards compat\n if (!skill.instructions) {\n skill.problem = this.extractMarkdownSection(section, 'Problem');\n skill.solution = this.extractMarkdownSection(section, 'Solution');\n skill.verification = this.extractMarkdownSection(section, 'Verification');\n skill.notes = this.extractMarkdownSection(section, 'Notes');\n }\n\n // Extract tags\n const tagsMatch = /Tags:\\s*(.+)$/m.exec(section);\n if (tagsMatch) {\n skill.tags = tagsMatch[1]\n .split(',')\n .map((t) => t.replace(/`/g, '').trim())\n .filter((t) => t);\n }\n\n skills.push(skill);\n }\n\n return skills;\n }\n\n /**\n * Extract content from XML tag\n */\n private extractXmlTag(body: string, tagName: string): string | undefined {\n const regex = new RegExp(`<${tagName}>([\\\\s\\\\S]*?)<\\\\/${tagName}>`, 'i');\n const match = regex.exec(body);\n if (match) {\n return this.unescapeXml(match[1].trim());\n }\n return undefined;\n }\n\n /**\n * Extract CDATA content\n */\n private extractCData(body: string, tagName: string): string | undefined {\n const regex = new RegExp(`<${tagName}><!\\\\[CDATA\\\\[([\\\\s\\\\S]*?)\\\\]\\\\]><\\\\/${tagName}>`, 'i');\n const match = regex.exec(body);\n if (match) {\n return match[1];\n }\n return undefined;\n }\n\n /**\n * Unescape XML entities\n */\n private unescapeXml(str: string): string {\n return str\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\")\n .replace(/&amp;/g, '&');\n }\n\n /**\n * Extract a markdown section by header\n */\n private extractMarkdownSection(content: string, header: string): string | undefined {\n const regex = new RegExp(`\\\\*\\\\*${header}:\\\\*\\\\*\\\\s*([\\\\s\\\\S]*?)(?=\\\\*\\\\*|Tags:|$)`, 'i');\n const match = regex.exec(content);\n if (match) {\n return match[1].trim();\n }\n return undefined;\n }\n\n /**\n * Generate ID from skill name\n */\n private generateId(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n }\n\n /**\n * Extract header content\n */\n private extractHeader(content: string, skills: ParsedAgentSkill[]): string | undefined {\n if (skills.length === 0) return content.trim() || undefined;\n\n const firstSkill = skills[0];\n const idx = content.indexOf(firstSkill.rawContent);\n if (idx > 0) {\n return content.slice(0, idx).trim() || undefined;\n }\n return undefined;\n }\n\n /**\n * Extract footer content\n */\n private extractFooter(content: string, skills: ParsedAgentSkill[]): string | undefined {\n if (skills.length === 0) return undefined;\n\n const lastSkill = skills[skills.length - 1];\n const idx = content.indexOf(lastSkill.rawContent);\n if (idx >= 0) {\n const afterIdx = idx + lastSkill.rawContent.length;\n const footer = content.slice(afterIdx).trim();\n return footer || undefined;\n }\n return undefined;\n }\n}\n\n/**\n * Create an AGENTS.md parser\n */\nexport function createAgentsParser(): AgentsParser {\n return new AgentsParser();\n}\n","/**\n * AGENTS.md Sync\n *\n * Synchronize skills between AGENTS.md and skill bank.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { Skill, StorageAdapter } from '../types.js';\nimport type { AgentsGeneratorConfig, SyncResult } from './types.js';\nimport { AgentsGenerator } from './generator.js';\nimport { AgentsParser } from './parser.js';\n\n/**\n * Sync options\n */\nexport interface SyncOptions {\n /** Sync direction */\n direction: 'import' | 'export' | 'bidirectional';\n /** How to handle conflicts (when skill exists in both) */\n conflictStrategy?: 'bank-wins' | 'agents-wins' | 'newer-wins' | 'skip';\n /** Delete skills in bank that are not in AGENTS.md (only for import) */\n removeOrphans?: boolean;\n /** Generator config for export */\n generatorConfig?: AgentsGeneratorConfig;\n /** Dry run - don't make changes, just report */\n dryRun?: boolean;\n}\n\n/**\n * Synchronize AGENTS.md with skill bank\n */\nexport class AgentsSync {\n private generator: AgentsGenerator;\n private parser: AgentsParser;\n\n constructor() {\n this.generator = new AgentsGenerator();\n this.parser = new AgentsParser();\n }\n\n /**\n * Sync AGENTS.md with skill bank\n */\n async sync(\n agentsPath: string,\n storage: StorageAdapter,\n options: SyncOptions\n ): Promise<SyncResult> {\n const result: SyncResult = {\n added: [],\n updated: [],\n removed: [],\n unchanged: [],\n warnings: [],\n };\n\n switch (options.direction) {\n case 'import':\n await this.importFromAgents(agentsPath, storage, options, result);\n break;\n case 'export':\n await this.exportToAgents(agentsPath, storage, options, result);\n break;\n case 'bidirectional':\n await this.bidirectionalSync(agentsPath, storage, options, result);\n break;\n }\n\n return result;\n }\n\n /**\n * Import skills from AGENTS.md to skill bank\n */\n async importFromAgents(\n agentsPath: string,\n storage: StorageAdapter,\n options: SyncOptions,\n result: SyncResult\n ): Promise<void> {\n // Read AGENTS.md\n if (!fs.existsSync(agentsPath)) {\n result.warnings.push(`AGENTS.md not found at ${agentsPath}`);\n return;\n }\n\n const content = fs.readFileSync(agentsPath, 'utf-8');\n const parsed = this.parser.parse(content);\n\n result.warnings.push(...parsed.warnings);\n\n // Get existing skills\n const existingSkills = await storage.listSkills();\n const existingById = new Map(existingSkills.map((s) => [s.id, s]));\n const existingByName = new Map(existingSkills.map((s) => [s.name.toLowerCase(), s]));\n\n // Track which skills were processed\n const processedIds = new Set<string>();\n\n // Process parsed skills\n for (const parsedSkill of parsed.skills) {\n const skill = this.parser.toSkill(parsedSkill);\n processedIds.add(skill.id);\n\n // Check for existing skill\n let existing = existingById.get(skill.id);\n if (!existing) {\n existing = existingByName.get(skill.name.toLowerCase());\n }\n\n if (existing) {\n // Handle conflict\n const shouldUpdate = this.resolveConflict(existing, skill, options.conflictStrategy);\n if (shouldUpdate) {\n if (!options.dryRun) {\n const merged = this.mergeSkills(existing, skill);\n await storage.saveSkill(merged);\n }\n result.updated.push(skill.id);\n } else {\n result.unchanged.push(skill.id);\n }\n } else {\n // New skill\n if (!options.dryRun) {\n await storage.saveSkill(skill);\n }\n result.added.push(skill.id);\n }\n }\n\n // Remove orphans if requested\n if (options.removeOrphans) {\n for (const existing of existingSkills) {\n if (!processedIds.has(existing.id)) {\n if (!options.dryRun) {\n await storage.deleteSkill(existing.id);\n }\n result.removed.push(existing.id);\n }\n }\n }\n }\n\n /**\n * Export skills from skill bank to AGENTS.md\n */\n async exportToAgents(\n agentsPath: string,\n storage: StorageAdapter,\n options: SyncOptions,\n result: SyncResult\n ): Promise<void> {\n // Create generator with config\n const generator = new AgentsGenerator(options.generatorConfig);\n\n // Generate content\n const content = await generator.generate(storage);\n\n // Check for existing file\n let existingContent = '';\n if (fs.existsSync(agentsPath)) {\n existingContent = fs.readFileSync(agentsPath, 'utf-8');\n }\n\n // Parse existing to track changes\n const existingParsed = this.parser.parse(existingContent);\n const existingIds = new Set(existingParsed.skills.map((s) => s.id || s.name.toLowerCase()));\n\n // Get skills being exported\n const skills = await storage.listSkills({\n status: options.generatorConfig?.filter?.status || ['active'],\n });\n\n for (const skill of skills) {\n if (existingIds.has(skill.id) || existingIds.has(skill.name.toLowerCase())) {\n result.updated.push(skill.id);\n } else {\n result.added.push(skill.id);\n }\n }\n\n // Write file\n if (!options.dryRun) {\n const dir = path.dirname(agentsPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(agentsPath, content);\n }\n }\n\n /**\n * Bidirectional sync\n */\n async bidirectionalSync(\n agentsPath: string,\n storage: StorageAdapter,\n options: SyncOptions,\n result: SyncResult\n ): Promise<void> {\n // First import from AGENTS.md\n await this.importFromAgents(agentsPath, storage, { ...options, removeOrphans: false }, result);\n\n // Then export back (to include any bank-only skills)\n const exportResult: SyncResult = {\n added: [],\n updated: [],\n removed: [],\n unchanged: [],\n warnings: [],\n };\n await this.exportToAgents(agentsPath, storage, options, exportResult);\n\n // Merge export additions (these are skills only in bank)\n for (const id of exportResult.added) {\n if (!result.added.includes(id) && !result.updated.includes(id)) {\n result.added.push(id);\n }\n }\n }\n\n /**\n * Resolve conflict between existing and new skill\n */\n private resolveConflict(\n existing: Skill,\n incoming: Skill,\n strategy?: SyncOptions['conflictStrategy']\n ): boolean {\n switch (strategy) {\n case 'bank-wins':\n return false;\n case 'agents-wins':\n return true;\n case 'newer-wins':\n return incoming.updatedAt > existing.updatedAt;\n case 'skip':\n default:\n return false;\n }\n }\n\n /**\n * Merge skills, preserving important data from existing\n */\n private mergeSkills(existing: Skill, incoming: Skill): Skill {\n return {\n ...incoming,\n id: existing.id, // Keep existing ID\n createdAt: existing.createdAt, // Preserve creation date\n metrics: existing.metrics, // Preserve usage metrics\n source: incoming.source || existing.source,\n parentVersion: existing.version, // Track update lineage\n };\n }\n}\n\n/**\n * Create an AGENTS.md sync manager\n */\nexport function createAgentsSync(): AgentsSync {\n return new AgentsSync();\n}\n\n/**\n * Convenience function to generate AGENTS.md\n */\nexport async function generateAgentsMd(\n storage: StorageAdapter,\n config?: AgentsGeneratorConfig\n): Promise<string> {\n const generator = new AgentsGenerator(config);\n return generator.generate(storage);\n}\n\n/**\n * Convenience function to write AGENTS.md to file\n */\nexport async function writeAgentsMd(\n storage: StorageAdapter,\n filePath: string,\n config?: AgentsGeneratorConfig\n): Promise<void> {\n const content = await generateAgentsMd(storage, config);\n const dir = path.dirname(filePath);\n if (dir && !fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, content);\n}\n\n/**\n * Convenience function to import from AGENTS.md\n */\nexport async function importFromAgentsMd(\n filePath: string,\n storage: StorageAdapter,\n options?: { dryRun?: boolean; conflictStrategy?: SyncOptions['conflictStrategy'] }\n): Promise<SyncResult> {\n const sync = new AgentsSync();\n return sync.sync(filePath, storage, {\n direction: 'import',\n conflictStrategy: options?.conflictStrategy || 'skip',\n dryRun: options?.dryRun,\n });\n}\n","/**\n * skill-tree - A library for managing agent skill versions and evolution\n *\n * This library provides:\n * - Versioned skill storage (OpenSkills-compatible)\n * - Lineage tracking and skill evolution\n * - Serving layer with dynamic loadouts\n * - Multi-agent sync and federation\n *\n * @packageDocumentation\n */\n\nexport const VERSION = \"0.1.0\";\n\n// Main orchestrator\nexport {\n SkillBank,\n createSkillBank,\n type SkillBankConfig,\n type SkillBankStats,\n} from \"./skill-bank.js\";\n\n// Types\nexport type {\n // Core skill types\n Skill,\n SkillStatus,\n SkillMetrics,\n SkillSource,\n\n // Version types\n SkillVersion,\n SkillLineage,\n SkillFork,\n\n // Storage types\n StorageAdapter,\n SkillFilter,\n StorageConfig,\n\n // Event types\n SkillTreeEvent,\n SkillTreeEventHandler,\n\n // Serving metadata (defined in types.ts for Skill interface)\n SkillServingMetadata,\n ExpandTriggerConfig,\n\n // Namespace types (for multi-tier skill trees)\n SkillScope,\n SkillVisibility,\n SkillNamespace,\n SkillAccessControl,\n\n // Federation types\n SkillUpstream,\n\n // Materialization types\n MaterializationConfig,\n} from \"./types.js\";\n\n// Storage\nexport {\n MemoryStorageAdapter,\n CachedStorageAdapter,\n migrateStorage,\n type CachedStorageConfig,\n type MigrationOptions,\n type MigrationResult,\n type MigrationProgressItem,\n} from \"./storage/index.js\";\n\n// Federation\nexport {\n FederationManager,\n createFederationManager,\n type FederationManagerOptions,\n RemoteStore,\n RemoteManager,\n discoverSkills,\n hasSkilltreeDir,\n type FederatedRemoteConfig,\n type RemoteState,\n type ImportMode,\n type ImportOptions,\n type ImportResult,\n type ShareOptions,\n type ShareResult,\n type UpstreamUpdate,\n type PullUpstreamOptions,\n type PullUpstreamResult,\n type FederationEvent,\n type FederationEventHandler,\n type DiscoveredSkill,\n} from \"./federation/index.js\";\n\n// Versioning\nexport {\n // Semver utilities\n parseVersion,\n formatVersion,\n isValidVersion,\n compareVersions,\n bumpVersion,\n satisfiesRange,\n getLatestVersion,\n sortVersions,\n inferBumpType,\n type ParsedVersion,\n type BumpType,\n type VersionChanges,\n\n // Lineage tracking\n LineageTracker,\n type NewVersionOptions,\n type ForkOptions,\n type RollbackOptions,\n type LineageTree,\n type VersionDiff,\n type SkillDiffChanges,\n\n // Skill merging\n SkillMerger,\n createSkillMerger,\n type MergeStrategy,\n type MergeConfig,\n type MergeConflict,\n type ConflictResolution,\n type MergePreview,\n type MergeResult,\n type MergeSuggestion,\n} from \"./versioning/index.js\";\n\n// AGENTS.md Integration\nexport {\n AgentsGenerator,\n createAgentsGenerator,\n AgentsParser,\n createAgentsParser,\n AgentsSync,\n createAgentsSync,\n generateAgentsMd,\n writeAgentsMd,\n importFromAgentsMd,\n type SkillFormat,\n type AgentsGeneratorConfig,\n type SkillSelector,\n type ParsedAgentSkill,\n type ParsedAgentsFile,\n type SyncResult,\n type SyncOptions,\n DEFAULT_AGENTS_CONFIG,\n} from \"./agents/index.js\";\n\n// Hooks\nexport {\n // Types\n type HookEvent,\n type HookPriority,\n type BaseHookContext,\n type StorageHookContext,\n type SkillCrudHookContext,\n type HookContext,\n type HookResult,\n type HookHandler,\n type RegisteredHook,\n\n // Registry\n HookRegistry,\n hookRegistry,\n type RegisterHookOptions,\n type HookExecutionResult,\n\n // Built-in hooks\n createLoggingHook,\n createBackupHook,\n createSaveValidationHook,\n combineHandlers,\n conditionalHook,\n} from \"./hooks/index.js\";\n\n// Serving\nexport {\n LoadoutCompiler,\n ViewRenderer,\n ProjectDetector,\n SkillGraphServer,\n CatalogRenderer,\n builtInProfiles,\n getBuiltInProfile,\n listBuiltInProfiles,\n codeReviewProfile,\n implementationProfile,\n debuggingProfile,\n securityProfile,\n testingProfile,\n refactoringProfile,\n documentationProfile,\n devopsProfile,\n type SkillState,\n type ExpandTrigger,\n type LoadoutCriteria,\n type LoadoutSource,\n type LoadoutState,\n type SkillSummary,\n type LoadoutView,\n type ProjectContext,\n type LoadoutCompilerConfig,\n type CatalogRendererConfig,\n type EvictionStrategy,\n type GraphServerConfig,\n type ServingEvent,\n type ServingEventHandler,\n type ViewRendererConfig,\n} from \"./serving/index.js\";\n\n// Materialization\nexport {\n Materializer,\n} from \"./materialization/index.js\";\n\n// MCP Integration\nexport {\n // Adapter\n GitSyncAdapter,\n createGitSyncAdapter,\n type GitSyncAdapterOptions,\n\n // Sync Manager\n SyncManager,\n createSyncManager,\n type SyncManagerOptions,\n\n // Conflict Store\n ConflictStore,\n createConflictStore,\n\n // Config Helper\n createDefaultSyncConfig,\n\n // Types\n type SyncConfig,\n type RemoteConfig,\n type AgentConfig,\n type SyncBehaviorConfig,\n type ConflictConfig,\n type ConflictStrategy,\n type PullOptions,\n type PushOptions,\n type SyncResult as GitSyncResult,\n type SkillChange,\n type SkillMergeResult,\n type SyncError,\n type SkillConflict,\n type ConflictResolution as SyncConflictResolution,\n type SyncStatus,\n type FetchResult,\n type SyncState,\n type SkillSyncState,\n} from \"./sync/index.js\";\n\n// Indexer Service\nexport {\n IndexerService,\n type IndexerServiceConfig,\n type SkillSource as IndexerSkillSource,\n type ScrapeResult,\n type IndexResult,\n type RelationshipResult,\n type TaxonomyNode,\n type IndexerStats,\n} from \"./services/indexer.js\";\n","/**\n * Core types for skill-tree\n * @packageDocumentation\n */\n\n// =============================================================================\n// SKILL TYPES\n// =============================================================================\n\n/**\n * Core skill representation combining OpenSkills format with versioning\n */\nexport interface Skill {\n /** Unique identifier (kebab-case) */\n id: string;\n /** Human-readable name */\n name: string;\n /** Semantic version (e.g., \"1.0.0\") */\n version: string;\n /** Short description optimized for semantic matching (1-2 sentences) */\n description: string;\n\n // Content\n /** Free-form markdown instructions (the SKILL.md body) */\n instructions: string;\n /** Related skill IDs */\n related?: string[];\n\n // Metadata\n author: string;\n tags: string[];\n createdAt: Date;\n updatedAt: Date;\n\n // Versioning & Evolution\n /** Status in the skill lifecycle */\n status: SkillStatus;\n /** Previous version this was derived from */\n parentVersion?: string;\n /** Skills this was composed from */\n derivedFrom?: string[];\n /** Skills forked from this one (source → child tracking) */\n forks?: string[];\n /** Performance metrics */\n metrics: SkillMetrics;\n\n // Federation (for linked/imported skills)\n /** Upstream tracking for skills imported with 'link' mode */\n upstream?: SkillUpstream;\n\n // Source tracking (OpenSkills-inspired)\n source?: SkillSource;\n\n // Extended fields for indexed/imported skills\n /** Taxonomy classification (from skill indexer) */\n taxonomy?: SkillTaxonomy;\n /** External source information (for imported skills) */\n externalSource?: ExternalSource;\n /** Relationships to other skills */\n relationships?: SkillRelationship[];\n\n /** Namespace and scope information for multi-tier skill trees */\n namespace?: SkillNamespace;\n\n // Serving layer metadata\n /** Serving-specific configuration for loadout/expansion behavior */\n serving?: SkillServingMetadata;\n\n}\n\n/**\n * Serving-specific metadata for a skill\n */\nexport interface SkillServingMetadata {\n /** Short summary for collapsed view (defaults to description) */\n summary?: string;\n /** Estimated token count for context budgeting */\n tokenEstimate?: number;\n /** Auto-expand triggers */\n autoExpand?: ExpandTriggerConfig[];\n /** Group ID for batch expansion */\n expansionGroup?: string;\n}\n\n/**\n * Trigger conditions for auto-expanding a skill\n */\nexport interface ExpandTriggerConfig {\n /** What event triggers expansion */\n on: 'use' | 'mention' | 'error-match' | 'file-match' | 'explicit';\n /** Optional conditions for the trigger */\n conditions?: {\n /** Keywords that trigger expansion */\n keywords?: string[];\n /** Error patterns that trigger expansion */\n errorPatterns?: string[];\n /** File patterns that trigger expansion */\n filePatterns?: string[];\n };\n}\n\nexport type SkillStatus = 'draft' | 'active' | 'deprecated' | 'experimental';\n\n\nexport interface SkillMetrics {\n /** Number of times this skill was used */\n usageCount: number;\n /** Success rate (0-1) */\n successRate: number;\n /** When was this skill last used */\n lastUsed?: Date;\n /** User feedback scores */\n feedbackScores: number[];\n /** Average execution time in ms */\n avgExecutionTime?: number;\n /** Average confidence from matching */\n averageConfidence?: number;\n}\n\nexport interface SkillSource {\n /** Where the skill came from */\n type: 'extracted' | 'manual' | 'imported' | 'composed';\n /** Original source location (git URL, local path, etc.) */\n location?: string;\n /** For extracted skills: the session it came from */\n sessionId?: string;\n /** Timestamp of import/extraction */\n importedAt: Date;\n /** Agent that created/extracted this skill */\n agentId?: string;\n /** Human-readable agent name */\n agentName?: string;\n}\n\n/**\n * Upstream tracking for skills imported from a remote with 'link' mode.\n * Enables checking for updates and pulling changes from the source.\n */\nexport interface SkillUpstream {\n /** Name of the remote this skill was imported from */\n remote: string;\n /** Original skill ID in the remote repository */\n skillId: string;\n /** Version of the skill when last synced */\n version: string;\n /** When the skill was last synced with upstream */\n syncedAt: Date;\n}\n\n/**\n * Taxonomy classification for indexed skills\n */\nexport interface SkillTaxonomy {\n /** Primary taxonomy path (e.g., [\"Development\", \"Python\", \"Testing\"]) */\n primaryPath: string[];\n /** Secondary taxonomy placements */\n secondaryPaths?: string[][];\n /** Classification confidence (0-1) */\n confidence?: number;\n}\n\n/**\n * External source information for imported skills\n */\nexport interface ExternalSource {\n /** Source URL */\n url: string;\n /** Source repository */\n repo: string;\n /** When the skill was scraped */\n scrapedAt: Date;\n /** ETag for change detection */\n etag?: string;\n}\n\n/**\n * Relationship between skills\n */\nexport interface SkillRelationship {\n /** Target skill ID */\n targetSkillId: string;\n /** Relationship type */\n type: 'depends_on' | 'extends' | 'alternative' | 'related';\n /** Confidence score (0-1) */\n confidence: number;\n /** Reasoning for the relationship */\n reasoning?: string;\n}\n\n// =============================================================================\n// NAMESPACE & SCOPE TYPES (for multi-tier skill trees)\n// =============================================================================\n\n/**\n * Scope level for a skill\n * - personal: Private to a single agent\n * - team: Shared within a team/organization\n * - global: Shared across all teams (public)\n */\nexport type SkillScope = 'personal' | 'team' | 'global';\n\n/**\n * Visibility level for skills\n * - private: Only owner can see\n * - team-only: Only team members can see\n * - public: Everyone can see\n */\nexport type SkillVisibility = 'private' | 'team-only' | 'public';\n\n/**\n * Namespace configuration for scoped skills\n */\nexport interface SkillNamespace {\n /** Scope level (personal, team, global) */\n scope: SkillScope;\n\n /** Owner identifier (agent ID for personal, team name for team) */\n owner: string;\n\n /** Team name (for team-scoped skills) */\n team?: string;\n\n /** Visibility setting */\n visibility: SkillVisibility;\n\n /** Whether this skill can be promoted to a higher scope */\n promotable?: boolean;\n\n /** If promoted from a personal skill, the original ID */\n promotedFrom?: {\n originalId: string;\n originalOwner: string;\n promotedAt: Date;\n };\n}\n\n/**\n * Access control for fine-grained permissions\n */\nexport interface SkillAccessControl {\n /** Agent IDs that can read this skill */\n canRead: string[];\n /** Agent IDs that can modify this skill */\n canWrite: string[];\n /** Agent IDs that can delete this skill */\n canDelete: string[];\n}\n\n// =============================================================================\n// SKILL VERSION TYPES\n// =============================================================================\n\nexport interface SkillVersion {\n /** Skill ID this version belongs to */\n skillId: string;\n /** Version string (semver) */\n version: string;\n /** Full skill snapshot at this version */\n skill: Skill;\n /** What changed in this version */\n changelog: string;\n /** When this version was created */\n createdAt: Date;\n /** Hash of skill content for integrity checks */\n contentHash: string;\n}\n\nexport interface SkillLineage {\n /** Root skill ID */\n rootId: string;\n /** Version history in chronological order */\n versions: SkillVersion[];\n /** Branches/forks from this skill */\n forks: SkillFork[];\n}\n\nexport interface SkillFork {\n /** New skill ID that forked */\n forkedSkillId: string;\n /** Version it forked from */\n fromVersion: string;\n /** Reason for forking */\n reason: string;\n /** When the fork happened */\n forkedAt: Date;\n}\n\n// =============================================================================\n// STORAGE TYPES\n// =============================================================================\n\nexport interface StorageAdapter {\n /** Initialize the storage */\n initialize(): Promise<void>;\n\n // Skill operations\n saveSkill(skill: Skill): Promise<void>;\n getSkill(id: string, version?: string): Promise<Skill | null>;\n listSkills(filter?: SkillFilter): Promise<Skill[]>;\n deleteSkill(id: string, version?: string): Promise<boolean>;\n\n // Version operations\n getVersionHistory(skillId: string): Promise<SkillVersion[]>;\n getLineage(skillId: string): Promise<SkillLineage | null>;\n\n // Search\n searchSkills(query: string): Promise<Skill[]>;\n\n // Taxonomy operations (optional - for indexed skills)\n /** Place a skill in the taxonomy tree */\n placeInTaxonomy?(skillId: string, taxonomy: SkillTaxonomy): Promise<void>;\n\n // Sync operations (optional - for synchronized storage)\n /** Get sync states for all remotes */\n getSyncStates?(): Promise<Array<{ remote: string; syncedAt: Date; commitHash?: string }>>;\n /** Save sync state for a remote */\n saveSyncState?(state: { remote: string; syncedAt: Date; commitHash?: string }): Promise<void>;\n\n // Fork tracking (optional - for lineage-aware storage)\n /** Record a fork relationship on the source skill's lineage */\n recordFork?(sourceSkillId: string, fork: SkillFork): Promise<void>;\n}\n\n/**\n * Type guard for storage adapters with taxonomy support\n */\nexport function hasTaxonomySupport(\n storage: StorageAdapter\n): storage is StorageAdapter & { placeInTaxonomy: NonNullable<StorageAdapter['placeInTaxonomy']> } {\n return typeof (storage as StorageAdapter).placeInTaxonomy === 'function';\n}\n\n/**\n * Type guard for storage adapters with sync support\n */\nexport function hasSyncSupport(\n storage: StorageAdapter\n): storage is StorageAdapter & {\n getSyncStates: NonNullable<StorageAdapter['getSyncStates']>;\n saveSyncState: NonNullable<StorageAdapter['saveSyncState']>;\n} {\n return (\n typeof (storage as StorageAdapter).getSyncStates === 'function' &&\n typeof (storage as StorageAdapter).saveSyncState === 'function'\n );\n}\n\n/**\n * Type guard for storage adapters with fork tracking support\n */\nexport function hasForkSupport(\n storage: StorageAdapter\n): storage is StorageAdapter & { recordFork: NonNullable<StorageAdapter['recordFork']> } {\n return typeof (storage as StorageAdapter).recordFork === 'function';\n}\n\nexport interface SkillFilter {\n status?: SkillStatus[];\n tags?: string[];\n author?: string;\n minSuccessRate?: number;\n createdAfter?: Date;\n createdBefore?: Date;\n\n // Namespace filtering (for multi-tier skill trees)\n /** Filter by scope */\n scope?: SkillScope | SkillScope[];\n /** Filter by owner (agent ID or team name) */\n owner?: string;\n /** Filter by team */\n team?: string;\n /** Filter by visibility */\n visibility?: SkillVisibility | SkillVisibility[];\n /** Filter to skills accessible by this agent ID */\n accessibleBy?: string;\n /** The team of the agent specified in accessibleBy (for team-only visibility checks) */\n accessibleByTeam?: string;\n}\n\nexport interface StorageConfig {\n /** Base path for skill storage */\n basePath?: string;\n /** Whether to use OpenSkills-compatible format */\n openSkillsCompatible?: boolean;\n}\n\n// =============================================================================\n// EVENT TYPES (for hooks/observers)\n// =============================================================================\n\nexport type SkillTreeEvent =\n | { type: 'skill:created'; skill: Skill }\n | { type: 'skill:updated'; skill: Skill; previousVersion: string }\n | { type: 'skill:deprecated'; skillId: string }\n | { type: 'skill:deleted'; skillId: string };\n\nexport type SkillTreeEventHandler = (event: SkillTreeEvent) => void | Promise<void>;\n\n// =============================================================================\n// MATERIALIZATION TYPES\n// =============================================================================\n\n/**\n * Configuration for materializing skills to agent-discoverable locations\n */\nexport interface MaterializationConfig {\n /** Enable automatic materialization on skill changes (default: false) */\n enabled: boolean;\n /** Materialization mode: 'symlink' creates symlinks, 'copy' copies directories (default: 'symlink') */\n mode?: 'symlink' | 'copy';\n /** Additional directories to symlink/copy skill dirs into (e.g. ['.claude/skills', '.agent/skills']) */\n symlinkPaths?: string[];\n /** Path to write AGENTS.md (e.g. './AGENTS.md'). If set, auto-regenerates on changes */\n agentsMdPath?: string;\n /** Format for AGENTS.md generation (default: 'xml') */\n agentsMdFormat?: 'xml' | 'markdown' | 'json';\n /** Debounce interval in ms for batch updates (default: 500) */\n debounceMs?: number;\n}\n","/**\n * Git Sync Adapter\n *\n * Git-based skill synchronization for multi-agent collaboration.\n * Wraps FilesystemStorageAdapter with git operations.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { Skill, SkillStatus } from '../types.js';\nimport type { MergeConflict } from '../versioning/merge.js';\nimport { ConflictStore } from './conflict-store.js';\nimport type {\n SyncConfig,\n SyncResult,\n SyncStatus,\n FetchResult,\n PullOptions,\n PushOptions,\n SkillConflict,\n ConflictResolution,\n SkillChange,\n SkillMergeResult,\n SyncError,\n SyncState,\n RemoteSkillChange,\n MergeAttempt,\n ConflictStrategy,\n} from './types.js';\n\n// Use the actual SimpleGit type from the library\nimport type { SimpleGit as SimpleGitType } from 'simple-git';\n\n/**\n * Options for creating a GitSyncAdapter\n */\nexport interface GitSyncAdapterOptions {\n /** Path to the git repository */\n repoPath: string;\n\n /** Sync configuration */\n config: SyncConfig;\n}\n\n/**\n * Git-based sync adapter for multi-agent skill synchronization\n */\nconst VALID_STATUSES: Set<string> = new Set(['draft', 'active', 'deprecated', 'experimental']);\nfunction isValidStatus(value: unknown): value is SkillStatus {\n return typeof value === 'string' && VALID_STATUSES.has(value);\n}\n\nexport class GitSyncAdapter {\n private repoPath: string;\n private config: SyncConfig;\n private conflictStore: ConflictStore;\n private git: SimpleGitType | null = null;\n private initialized = false;\n\n constructor(options: GitSyncAdapterOptions) {\n this.repoPath = options.repoPath;\n this.config = options.config;\n this.conflictStore = new ConflictStore(options.repoPath);\n }\n\n /**\n * Initialize the adapter\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Dynamically import simple-git\n const { simpleGit } = await import('simple-git');\n this.git = simpleGit(this.repoPath);\n\n // Verify this is a git repo\n const isRepo = await this.git.checkIsRepo();\n if (!isRepo) {\n throw new Error(`Not a git repository: ${this.repoPath}`);\n }\n\n // Initialize conflict store\n await this.conflictStore.initialize();\n\n this.initialized = true;\n }\n\n /**\n * Ensure adapter is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized || !this.git) {\n throw new Error('GitSyncAdapter not initialized. Call initialize() first.');\n }\n }\n\n // ===========================================================================\n // Core Sync Operations\n // ===========================================================================\n\n /**\n * Fetch remote changes without applying them\n */\n async fetch(): Promise<FetchResult> {\n this.ensureInitialized();\n\n const branch = this.config.remote.branch || 'main';\n\n // Fetch from remote\n await this.git!.fetch('origin', branch);\n\n // Get status to see ahead/behind\n const status = await this.git!.status();\n\n // Get list of changed files\n const diffOutput = await this.git!.diff([\n `HEAD...origin/${branch}`,\n '--name-only',\n '--',\n this.getSkillsPath(),\n ]);\n\n const changedFiles = diffOutput\n .split('\\n')\n .filter((f) => f.trim() && f.endsWith('.md'));\n\n // Categorize changes\n const changedSkills: string[] = [];\n const newSkills: string[] = [];\n const deletedSkills: string[] = [];\n\n for (const file of changedFiles) {\n const skillId = this.extractSkillIdFromPath(file);\n if (!skillId) continue;\n\n // Check if file exists locally\n const localPath = path.join(this.repoPath, file);\n const existsLocally = fs.existsSync(localPath);\n\n // Check if file exists on remote (by trying to show it)\n let existsRemotely = true;\n try {\n await this.git!.show([`origin/${branch}:${file}`]);\n } catch {\n existsRemotely = false;\n }\n\n if (!existsLocally && existsRemotely) {\n newSkills.push(skillId);\n } else if (existsLocally && !existsRemotely) {\n deletedSkills.push(skillId);\n } else {\n changedSkills.push(skillId);\n }\n }\n\n return {\n ahead: status.ahead,\n behind: status.behind,\n changedSkills,\n newSkills,\n deletedSkills,\n };\n }\n\n /**\n * Pull remote changes and merge into local\n */\n async pull(options: PullOptions = {}): Promise<SyncResult> {\n this.ensureInitialized();\n\n const result: SyncResult = {\n pulled: [],\n pushed: [],\n conflicts: [],\n autoMerged: [],\n errors: [],\n };\n\n const branch = this.config.remote.branch || 'main';\n\n try {\n // Fetch first to see what changed\n const fetchResult = await this.fetch();\n\n if (fetchResult.behind === 0 && fetchResult.newSkills.length === 0) {\n // Already up to date\n return result;\n }\n\n // Get current sync state\n const syncState = await this.conflictStore.loadState();\n\n // Process each changed skill\n const skillsToProcess = options.skillIds\n ? [...fetchResult.changedSkills, ...fetchResult.newSkills].filter((id) =>\n options.skillIds!.includes(id)\n )\n : [...fetchResult.changedSkills, ...fetchResult.newSkills];\n\n for (const skillId of skillsToProcess) {\n try {\n const pullResult = await this.pullSkill(\n skillId,\n branch,\n syncState,\n options\n );\n\n if (pullResult.conflict) {\n result.conflicts.push(pullResult.conflict);\n } else if (pullResult.merged) {\n result.autoMerged.push(pullResult.merged);\n result.pulled.push({\n skillId,\n changeType: 'modified',\n newVersion: pullResult.merged.mergedSkill.version,\n skill: pullResult.merged.mergedSkill,\n });\n } else if (pullResult.change) {\n result.pulled.push(pullResult.change);\n }\n } catch (err) {\n result.errors.push({\n skillId,\n message: (err as Error).message,\n type: 'unknown',\n cause: err as Error,\n });\n }\n }\n\n // Handle deleted skills\n for (const skillId of fetchResult.deletedSkills) {\n if (options.skillIds && !options.skillIds.includes(skillId)) {\n continue;\n }\n\n result.pulled.push({\n skillId,\n changeType: 'deleted',\n });\n }\n\n // If no conflicts and not dry run, actually merge\n if (!options.dryRun && result.conflicts.length === 0) {\n await this.git!.pull('origin', branch);\n\n // Update sync state\n await this.updateSyncState();\n }\n\n // Save any conflicts\n for (const conflict of result.conflicts) {\n await this.conflictStore.saveConflict(conflict);\n }\n\n return result;\n } catch (err) {\n result.errors.push({\n message: (err as Error).message,\n type: 'network',\n cause: err as Error,\n });\n return result;\n }\n }\n\n /**\n * Push local changes to remote\n */\n async push(options: PushOptions = {}): Promise<SyncResult> {\n this.ensureInitialized();\n\n const result: SyncResult = {\n pulled: [],\n pushed: [],\n conflicts: [],\n autoMerged: [],\n errors: [],\n };\n\n const branch = this.config.remote.branch || 'main';\n\n try {\n // Get locally modified skills\n const status = await this.git!.status();\n const modifiedFiles = [\n ...status.modified,\n ...status.created,\n ...status.not_added,\n ].filter((f) => f.startsWith(this.getSkillsPath()) && f.endsWith('.md'));\n\n // Filter to requested skills\n const filesToPush = options.skillIds\n ? modifiedFiles.filter((f) => {\n const skillId = this.extractSkillIdFromPath(f);\n return skillId && options.skillIds!.includes(skillId);\n })\n : modifiedFiles;\n\n if (filesToPush.length === 0) {\n return result;\n }\n\n // Stage files\n await this.git!.add(filesToPush);\n\n // Build commit message\n const commitMessage = this.buildCommitMessage(\n options.message,\n filesToPush\n );\n\n // Commit\n await this.git!.commit(commitMessage);\n\n // Try to push\n try {\n await this.git!.push('origin', branch);\n\n // Record pushed changes\n for (const file of filesToPush) {\n const skillId = this.extractSkillIdFromPath(file);\n if (skillId) {\n result.pushed.push({\n skillId,\n changeType: status.created.includes(file) ? 'added' : 'modified',\n });\n }\n }\n\n // Update sync state\n await this.updateSyncState();\n } catch (pushErr) {\n // Check if it's a non-fast-forward error\n const errMessage = (pushErr as Error).message || '';\n if (\n errMessage.includes('non-fast-forward') ||\n errMessage.includes('fetch first')\n ) {\n // Need to pull first\n if (!options.force) {\n result.errors.push({\n message:\n 'Push rejected: remote has changes. Pull first or use --force.',\n type: 'conflict',\n cause: pushErr as Error,\n });\n } else {\n // Force push (dangerous!)\n await this.git!.push('origin', branch, ['--force']);\n for (const file of filesToPush) {\n const skillId = this.extractSkillIdFromPath(file);\n if (skillId) {\n result.pushed.push({\n skillId,\n changeType: status.created.includes(file)\n ? 'added'\n : 'modified',\n });\n }\n }\n }\n } else {\n throw pushErr;\n }\n }\n\n return result;\n } catch (err) {\n result.errors.push({\n message: (err as Error).message,\n type: 'unknown',\n cause: err as Error,\n });\n return result;\n }\n }\n\n /**\n * Get current sync status\n */\n async status(): Promise<SyncStatus> {\n this.ensureInitialized();\n\n const branch = this.config.remote.branch || 'main';\n\n try {\n // Fetch to get accurate status\n await this.git!.fetch('origin', branch);\n\n const gitStatus = await this.git!.status();\n const syncState = await this.conflictStore.loadState();\n const conflictCount = await this.conflictStore.getConflictCount();\n\n // Get modified skill files\n const modifiedSkills = [\n ...gitStatus.modified,\n ...gitStatus.created,\n ...gitStatus.not_added,\n ]\n .filter((f) => f.startsWith(this.getSkillsPath()) && f.endsWith('.md'))\n .map((f) => this.extractSkillIdFromPath(f))\n .filter((id): id is string => id !== null);\n\n // Get staged skill files\n const stagedSkills = gitStatus.staged\n .filter((f) => f.startsWith(this.getSkillsPath()) && f.endsWith('.md'))\n .map((f) => this.extractSkillIdFromPath(f))\n .filter((id): id is string => id !== null);\n\n return {\n configured: true,\n connected: true,\n lastSync: syncState?.lastSyncTime,\n localAhead: gitStatus.ahead,\n remoteBehind: gitStatus.behind,\n pendingConflicts: conflictCount,\n modifiedSkills,\n stagedSkills,\n branch: gitStatus.current || branch,\n remoteUrl: this.config.remote.url,\n };\n } catch (err) {\n return {\n configured: true,\n connected: false,\n localAhead: 0,\n remoteBehind: 0,\n pendingConflicts: 0,\n modifiedSkills: [],\n stagedSkills: [],\n branch: branch,\n remoteUrl: this.config.remote.url,\n };\n }\n }\n\n // ===========================================================================\n // Conflict Resolution\n // ===========================================================================\n\n /**\n * List all pending conflicts\n */\n async listConflicts(): Promise<SkillConflict[]> {\n return this.conflictStore.listConflicts();\n }\n\n /**\n * Resolve a conflict\n */\n async resolveConflict(\n skillId: string,\n resolution: ConflictResolution\n ): Promise<void> {\n this.ensureInitialized();\n\n const conflict = await this.conflictStore.getConflict(skillId);\n if (!conflict) {\n throw new Error(`No conflict found for skill: ${skillId}`);\n }\n\n let resolvedSkill: Skill;\n\n switch (resolution.strategy) {\n case 'accept-local':\n resolvedSkill = conflict.localVersion;\n break;\n\n case 'accept-remote':\n resolvedSkill = conflict.remoteVersion;\n break;\n\n case 'accept-merged':\n if (!conflict.suggestedResolution) {\n throw new Error('No suggested resolution available');\n }\n resolvedSkill = conflict.suggestedResolution;\n break;\n\n case 'custom':\n if (!resolution.customSkill) {\n throw new Error('Custom skill required for custom resolution');\n }\n resolvedSkill = resolution.customSkill;\n break;\n\n default:\n throw new Error(`Unknown resolution strategy: ${resolution.strategy}`);\n }\n\n // Apply field overrides if provided\n if (resolution.fieldOverrides) {\n const overrides: Partial<Skill> = {};\n for (const [field, source] of Object.entries(resolution.fieldOverrides)) {\n const typedField = field as keyof Skill;\n const sourceSkill = source === 'local' ? conflict.localVersion : conflict.remoteVersion;\n Object.assign(overrides, { [typedField]: sourceSkill[typedField] });\n }\n Object.assign(resolvedSkill, overrides);\n }\n\n // Write resolved skill back to filesystem\n await this.writeSkill(resolvedSkill);\n\n // Stage the resolved file\n const skillPath = this.getSkillFilePath(skillId);\n await this.git!.add(skillPath);\n\n // Remove conflict from store\n await this.conflictStore.removeConflict(skillId);\n }\n\n // ===========================================================================\n // Private Helpers\n // ===========================================================================\n\n private getSkillsPath(): string {\n return this.config.remote.skillsPath || 'skills/';\n }\n\n private getSkillFilePath(skillId: string): string {\n return path.join(this.getSkillsPath(), skillId, 'SKILL.md');\n }\n\n private extractSkillIdFromPath(filePath: string): string | null {\n // Extract skill ID from path like \"skills/my-skill/SKILL.md\"\n const skillsPath = this.getSkillsPath();\n if (!filePath.startsWith(skillsPath)) return null;\n\n const relativePath = filePath.slice(skillsPath.length);\n const parts = relativePath.split('/');\n if (parts.length >= 1) {\n return parts[0];\n }\n return null;\n }\n\n private async pullSkill(\n skillId: string,\n branch: string,\n syncState: SyncState | null,\n options: PullOptions\n ): Promise<{\n change?: SkillChange;\n merged?: SkillMergeResult;\n conflict?: SkillConflict;\n }> {\n const skillPath = this.getSkillFilePath(skillId);\n const fullPath = path.join(this.repoPath, skillPath);\n\n // Get remote version\n let remoteContent: string;\n try {\n remoteContent = await this.git!.show([`origin/${branch}:${skillPath}`]);\n } catch {\n // Skill doesn't exist on remote (deleted?)\n return {};\n }\n\n const remoteSkill = this.parseSkillContent(remoteContent, skillId);\n\n // Check if local version exists\n const localExists = fs.existsSync(fullPath);\n\n if (!localExists) {\n // New skill from remote\n return {\n change: {\n skillId,\n changeType: 'added',\n newVersion: remoteSkill.version,\n skill: remoteSkill,\n },\n };\n }\n\n // Get local version\n const localContent = await fs.promises.readFile(fullPath, 'utf-8');\n const localSkill = this.parseSkillContent(localContent, skillId);\n\n // Check if local was modified since last sync\n const skillSyncState = syncState?.skills[skillId];\n const localModified = this.isLocallyModified(localSkill, skillSyncState);\n\n if (!localModified || options.force) {\n // No local changes, safe to accept remote\n return {\n change: {\n skillId,\n changeType: 'modified',\n previousVersion: localSkill.version,\n newVersion: remoteSkill.version,\n skill: remoteSkill,\n },\n };\n }\n\n // Both modified - need to merge or create conflict\n const mergeAttempt = this.attemptAutoMerge(localSkill, remoteSkill);\n\n if (mergeAttempt.success && mergeAttempt.merged) {\n return {\n merged: {\n skillId,\n mergedSkill: mergeAttempt.merged,\n mergedFields: [],\n strategies: {},\n },\n };\n }\n\n // Create conflict\n return {\n conflict: {\n skillId,\n localVersion: localSkill,\n remoteVersion: remoteSkill,\n conflictingFields: this.getConflictingFields(localSkill, remoteSkill),\n fieldConflicts: mergeAttempt.conflicts || [],\n suggestedResolution: mergeAttempt.merged,\n confidence: mergeAttempt.confidence,\n detectedAt: new Date(),\n },\n };\n }\n\n private isLocallyModified(\n skill: Skill,\n syncState: { localHash: string; syncedVersion: string } | undefined\n ): boolean {\n if (!syncState) {\n // Never synced, consider it modified\n return true;\n }\n\n // Check if version changed\n if (skill.version !== syncState.syncedVersion) {\n return true;\n }\n\n // Check if content hash changed\n const currentHash = this.hashSkill(skill);\n return currentHash !== syncState.localHash;\n }\n\n private attemptAutoMerge(local: Skill, remote: Skill): MergeAttempt {\n const conflictingFields = this.getConflictingFields(local, remote);\n\n if (conflictingFields.length === 0) {\n // No conflicts, can merge\n return {\n success: true,\n merged: { ...local, ...remote, updatedAt: new Date() },\n confidence: 1.0,\n };\n }\n\n // Check if we can auto-resolve using configured strategies\n const fieldStrategies = this.config.conflicts.fieldStrategies || {};\n const defaultStrategy = this.config.conflicts.defaultStrategy;\n const conflicts: MergeConflict[] = [];\n const merged = { ...local };\n let canAutoMerge = true;\n\n for (const field of conflictingFields) {\n const strategy = fieldStrategies[field] || defaultStrategy;\n\n if (strategy === 'manual') {\n canAutoMerge = false;\n conflicts.push({\n field,\n targetValue: local[field],\n sourceValue: remote[field],\n suggestion: 'target',\n reason: 'Manual resolution required',\n });\n continue;\n }\n\n // Apply strategy\n const resolvedValue = this.applyStrategy(\n strategy,\n local[field],\n remote[field],\n local,\n remote\n );\n\n Object.assign(merged, { [field]: resolvedValue });\n }\n\n if (canAutoMerge) {\n merged.updatedAt = new Date();\n return {\n success: true,\n merged,\n confidence: 0.8,\n };\n }\n\n return {\n success: false,\n merged, // Partial merge as suggestion\n conflicts,\n confidence: 0.5,\n };\n }\n\n private applyStrategy(\n strategy: ConflictStrategy,\n localValue: any,\n remoteValue: any,\n local: Skill,\n remote: Skill\n ): any {\n switch (strategy) {\n case 'prefer-local':\n return localValue;\n\n case 'prefer-remote':\n return remoteValue;\n\n case 'prefer-newer':\n return local.updatedAt > remote.updatedAt ? localValue : remoteValue;\n\n case 'union':\n if (Array.isArray(localValue) && Array.isArray(remoteValue)) {\n const combined = [...localValue];\n for (const item of remoteValue) {\n const key = JSON.stringify(item);\n if (!localValue.some((i: any) => JSON.stringify(i) === key)) {\n combined.push(item);\n }\n }\n return combined;\n }\n return localValue;\n\n case 'combine':\n if (typeof localValue === 'string' && typeof remoteValue === 'string') {\n if (!localValue.trim()) return remoteValue;\n if (!remoteValue.trim()) return localValue;\n return `${localValue}\\n\\n---\\n\\n${remoteValue}`;\n }\n return localValue;\n\n default:\n return localValue;\n }\n }\n\n private getConflictingFields(local: Skill, remote: Skill): (keyof Skill)[] {\n const fields: (keyof Skill)[] = [\n 'instructions',\n 'tags',\n ];\n\n return fields.filter((field) => {\n const localValue = local[field];\n const remoteValue = remote[field];\n\n if (localValue === undefined || remoteValue === undefined) return false;\n if (localValue === null || remoteValue === null) return false;\n\n return JSON.stringify(localValue) !== JSON.stringify(remoteValue);\n });\n }\n\n private parseSkillContent(content: string, skillId: string): Skill {\n // Parse YAML frontmatter and markdown\n // This is a simplified parser - the real one is in FilesystemStorageAdapter\n\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n\n if (!frontmatterMatch) {\n throw new Error(`Invalid skill file format for ${skillId}`);\n }\n\n const [, frontmatter, body] = frontmatterMatch;\n\n // Simple YAML parsing (for common fields)\n const metadata: Record<string, any> = {};\n for (const line of frontmatter.split('\\n')) {\n const match = line.match(/^(\\w+):\\s*(.+)$/);\n if (match) {\n const [, key, value] = match;\n // Handle quoted strings\n if (value.startsWith('\"') && value.endsWith('\"')) {\n metadata[key] = value.slice(1, -1);\n } else if (value.startsWith(\"'\") && value.endsWith(\"'\")) {\n metadata[key] = value.slice(1, -1);\n } else {\n metadata[key] = value;\n }\n }\n }\n\n // Build skill object\n return {\n id: skillId,\n name: metadata.name || skillId,\n version: metadata.version || '1.0.0',\n description: metadata.description || '',\n instructions: body.trim(),\n author: metadata.author || 'unknown',\n tags: metadata.tags ? metadata.tags.split(',').map((t: string) => t.trim()) : [],\n createdAt: metadata.created ? new Date(metadata.created) : new Date(),\n updatedAt: metadata.updated ? new Date(metadata.updated) : new Date(),\n status: isValidStatus(metadata.status) ? metadata.status : 'active',\n metrics: {\n usageCount: 0,\n successRate: 0,\n feedbackScores: [],\n },\n };\n }\n\n private async writeSkill(skill: Skill): Promise<void> {\n const skillPath = this.getSkillFilePath(skill.id);\n const fullPath = path.join(this.repoPath, skillPath);\n\n // Ensure directory exists\n await fs.promises.mkdir(path.dirname(fullPath), { recursive: true });\n\n // Build content\n const content = this.buildSkillContent(skill);\n await fs.promises.writeFile(fullPath, content, 'utf-8');\n }\n\n private buildSkillContent(skill: Skill): string {\n const frontmatter = [\n '---',\n `name: \"${skill.name}\"`,\n `version: \"${skill.version}\"`,\n `status: ${skill.status}`,\n `author: \"${skill.author}\"`,\n `tags: ${skill.tags.join(', ')}`,\n `created: ${skill.createdAt.toISOString()}`,\n `updated: ${skill.updatedAt.toISOString()}`,\n '---',\n ].join('\\n');\n\n const body = [\n `# ${skill.name}`,\n '',\n skill.description,\n '',\n skill.instructions,\n ];\n\n return `${frontmatter}\\n\\n${body.join('\\n')}\\n`;\n }\n\n private buildCommitMessage(\n customMessage: string | undefined,\n files: string[]\n ): string {\n const skillIds = files\n .map((f) => this.extractSkillIdFromPath(f))\n .filter((id): id is string => id !== null);\n\n const defaultMessage =\n skillIds.length === 1\n ? `Update skill: ${skillIds[0]}`\n : `Update ${skillIds.length} skills: ${skillIds.join(', ')}`;\n\n const header = customMessage || defaultMessage;\n const agentId = this.config.agent.id;\n const environment = this.config.agent.environment || 'default';\n\n return [\n `[agent:${agentId}] ${header}`,\n '',\n `---`,\n `Agent: ${agentId}`,\n `Environment: ${environment}`,\n `Sync-Version: 1.0.0`,\n ].join('\\n');\n }\n\n private async updateSyncState(): Promise<void> {\n const commitHash = await this.git!.revparse(['HEAD']);\n\n const state: SyncState = {\n lastSyncCommit: commitHash.trim(),\n lastSyncTime: new Date(),\n agent: this.config.agent,\n skills: {},\n };\n\n // Update state for all skills in the repo\n const skillsPath = path.join(this.repoPath, this.getSkillsPath());\n if (fs.existsSync(skillsPath)) {\n const dirs = await fs.promises.readdir(skillsPath);\n for (const dir of dirs) {\n const skillPath = path.join(skillsPath, dir, 'SKILL.md');\n if (fs.existsSync(skillPath)) {\n try {\n const content = await fs.promises.readFile(skillPath, 'utf-8');\n const skill = this.parseSkillContent(content, dir);\n state.skills[dir] = {\n localHash: this.hashSkill(skill),\n syncedAt: new Date(),\n syncedVersion: skill.version,\n };\n } catch {\n // Skip invalid skills\n }\n }\n }\n }\n\n await this.conflictStore.saveState(state);\n }\n\n private hashSkill(skill: Skill): string {\n const content = JSON.stringify({\n instructions: skill.instructions,\n tags: skill.tags,\n });\n\n let hash = 0;\n for (let i = 0; i < content.length; i++) {\n const char = content.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(16);\n }\n}\n\n/**\n * Create a GitSyncAdapter instance\n */\nexport function createGitSyncAdapter(\n options: GitSyncAdapterOptions\n): GitSyncAdapter {\n return new GitSyncAdapter(options);\n}\n","/**\n * Conflict Store\n *\n * Persists skill conflicts to .skillbank/conflicts/ for resolution workflow\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { SkillConflict, ConflictResolution, SyncState, SkillSyncState } from './types.js';\n\n/**\n * Store for persisting sync conflicts and state\n */\nexport class ConflictStore {\n private conflictsDir: string;\n private stateFile: string;\n\n constructor(basePath: string) {\n const skillbankDir = path.join(basePath, '.skillbank');\n this.conflictsDir = path.join(skillbankDir, 'conflicts');\n this.stateFile = path.join(skillbankDir, 'sync-state.json');\n }\n\n /**\n * Initialize the store (create directories if needed)\n */\n async initialize(): Promise<void> {\n await fs.promises.mkdir(this.conflictsDir, { recursive: true });\n }\n\n // ===========================================================================\n // Conflict Operations\n // ===========================================================================\n\n /**\n * Save a conflict for later resolution\n */\n async saveConflict(conflict: SkillConflict): Promise<void> {\n await this.initialize();\n\n const filename = this.getConflictFilename(conflict.skillId);\n const filepath = path.join(this.conflictsDir, filename);\n\n // Serialize conflict with dates as ISO strings\n const data = JSON.stringify(this.serializeConflict(conflict), null, 2);\n await fs.promises.writeFile(filepath, data, 'utf-8');\n }\n\n /**\n * Get a conflict by skill ID\n */\n async getConflict(skillId: string): Promise<SkillConflict | null> {\n const filename = this.getConflictFilename(skillId);\n const filepath = path.join(this.conflictsDir, filename);\n\n try {\n const data = await fs.promises.readFile(filepath, 'utf-8');\n return this.deserializeConflict(JSON.parse(data));\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw err;\n }\n }\n\n /**\n * List all pending conflicts\n */\n async listConflicts(): Promise<SkillConflict[]> {\n try {\n await this.initialize();\n const files = await fs.promises.readdir(this.conflictsDir);\n const conflicts: SkillConflict[] = [];\n\n for (const file of files) {\n if (file.endsWith('.json')) {\n const filepath = path.join(this.conflictsDir, file);\n try {\n const data = await fs.promises.readFile(filepath, 'utf-8');\n conflicts.push(this.deserializeConflict(JSON.parse(data)));\n } catch {\n // Skip invalid files\n }\n }\n }\n\n // Sort by detected time (newest first)\n return conflicts.sort(\n (a, b) => b.detectedAt.getTime() - a.detectedAt.getTime()\n );\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw err;\n }\n }\n\n /**\n * Remove a conflict (after resolution)\n */\n async removeConflict(skillId: string): Promise<boolean> {\n const filename = this.getConflictFilename(skillId);\n const filepath = path.join(this.conflictsDir, filename);\n\n try {\n await fs.promises.unlink(filepath);\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return false;\n }\n throw err;\n }\n }\n\n /**\n * Check if a skill has a pending conflict\n */\n async hasConflict(skillId: string): Promise<boolean> {\n const conflict = await this.getConflict(skillId);\n return conflict !== null;\n }\n\n /**\n * Get count of pending conflicts\n */\n async getConflictCount(): Promise<number> {\n const conflicts = await this.listConflicts();\n return conflicts.length;\n }\n\n // ===========================================================================\n // Sync State Operations\n // ===========================================================================\n\n /**\n * Load sync state\n */\n async loadState(): Promise<SyncState | null> {\n try {\n const data = await fs.promises.readFile(this.stateFile, 'utf-8');\n const raw = JSON.parse(data);\n\n return {\n ...raw,\n lastSyncTime: new Date(raw.lastSyncTime),\n skills: Object.fromEntries(\n Object.entries(raw.skills || {}).map(([id, state]: [string, any]) => [\n id,\n {\n ...state,\n syncedAt: new Date(state.syncedAt),\n } as SkillSyncState,\n ])\n ),\n };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw err;\n }\n }\n\n /**\n * Save sync state\n */\n async saveState(state: SyncState): Promise<void> {\n await this.initialize();\n\n const data = JSON.stringify(\n {\n ...state,\n lastSyncTime: state.lastSyncTime.toISOString(),\n skills: Object.fromEntries(\n Object.entries(state.skills).map(([id, skillState]) => [\n id,\n {\n ...skillState,\n syncedAt: skillState.syncedAt.toISOString(),\n },\n ])\n ),\n },\n null,\n 2\n );\n\n await fs.promises.writeFile(this.stateFile, data, 'utf-8');\n }\n\n /**\n * Update state for a single skill\n */\n async updateSkillState(\n skillId: string,\n skillState: SkillSyncState\n ): Promise<void> {\n const state = await this.loadState();\n if (!state) {\n throw new Error('Sync state not initialized. Run pull or push first.');\n }\n\n state.skills[skillId] = skillState;\n await this.saveState(state);\n }\n\n /**\n * Get state for a single skill\n */\n async getSkillState(skillId: string): Promise<SkillSyncState | null> {\n const state = await this.loadState();\n return state?.skills[skillId] || null;\n }\n\n /**\n * Remove skill from state (when deleted)\n */\n async removeSkillState(skillId: string): Promise<void> {\n const state = await this.loadState();\n if (state && state.skills[skillId]) {\n delete state.skills[skillId];\n await this.saveState(state);\n }\n }\n\n // ===========================================================================\n // Private Helpers\n // ===========================================================================\n\n private getConflictFilename(skillId: string): string {\n // Sanitize skill ID for use as filename\n const safeId = skillId.replace(/[^a-zA-Z0-9-_]/g, '_');\n return `${safeId}.json`;\n }\n\n private serializeConflict(conflict: SkillConflict): object {\n return {\n ...conflict,\n detectedAt: conflict.detectedAt.toISOString(),\n localVersion: this.serializeSkillDates(conflict.localVersion),\n remoteVersion: this.serializeSkillDates(conflict.remoteVersion),\n baseVersion: conflict.baseVersion\n ? this.serializeSkillDates(conflict.baseVersion)\n : undefined,\n suggestedResolution: conflict.suggestedResolution\n ? this.serializeSkillDates(conflict.suggestedResolution)\n : undefined,\n };\n }\n\n private deserializeConflict(data: any): SkillConflict {\n return {\n ...data,\n detectedAt: new Date(data.detectedAt),\n localVersion: this.deserializeSkillDates(data.localVersion),\n remoteVersion: this.deserializeSkillDates(data.remoteVersion),\n baseVersion: data.baseVersion\n ? this.deserializeSkillDates(data.baseVersion)\n : undefined,\n suggestedResolution: data.suggestedResolution\n ? this.deserializeSkillDates(data.suggestedResolution)\n : undefined,\n };\n }\n\n private serializeSkillDates(skill: any): object {\n return {\n ...skill,\n createdAt: skill.createdAt instanceof Date\n ? skill.createdAt.toISOString()\n : skill.createdAt,\n updatedAt: skill.updatedAt instanceof Date\n ? skill.updatedAt.toISOString()\n : skill.updatedAt,\n metrics: {\n ...skill.metrics,\n lastUsed: skill.metrics?.lastUsed instanceof Date\n ? skill.metrics.lastUsed.toISOString()\n : skill.metrics?.lastUsed,\n },\n source: skill.source\n ? {\n ...skill.source,\n importedAt: skill.source.importedAt instanceof Date\n ? skill.source.importedAt.toISOString()\n : skill.source.importedAt,\n }\n : undefined,\n };\n }\n\n private deserializeSkillDates(data: any): any {\n return {\n ...data,\n createdAt: new Date(data.createdAt),\n updatedAt: new Date(data.updatedAt),\n metrics: {\n ...data.metrics,\n lastUsed: data.metrics?.lastUsed\n ? new Date(data.metrics.lastUsed)\n : undefined,\n },\n source: data.source\n ? {\n ...data.source,\n importedAt: new Date(data.source.importedAt),\n }\n : undefined,\n };\n }\n}\n\n/**\n * Create a conflict store instance\n */\nexport function createConflictStore(basePath: string): ConflictStore {\n return new ConflictStore(basePath);\n}\n","/**\n * SyncManager - Orchestrates sync within SkillBank\n *\n * Bridges GitSyncAdapter with SkillBank's hook system to enable\n * automatic change tracking and configurable push/pull behavior.\n */\n\nimport { GitSyncAdapter } from './git-sync-adapter.js';\nimport type {\n SyncConfig,\n SyncResult,\n SyncStatus,\n FetchResult,\n PullOptions,\n PushOptions,\n SkillConflict,\n ConflictResolution,\n} from './types.js';\nimport type { HookRegistry } from '../hooks/registry.js';\nimport type { StorageHookContext } from '../hooks/types.js';\n\n/**\n * Options for creating a SyncManager\n */\nexport interface SyncManagerOptions {\n /** Path to the git repository (same as filesystem storage basePath) */\n repoPath: string;\n\n /** Full sync configuration */\n config: SyncConfig;\n\n /** Hook registry for listening to storage events */\n hookRegistry: HookRegistry;\n}\n\n/**\n * Orchestrates git-based sync within SkillBank.\n *\n * Listens to storage hooks to track local changes and manages\n * push behavior based on the configured sync mode.\n */\nexport class SyncManager {\n private adapter: GitSyncAdapter;\n private hookRegistry: HookRegistry;\n private config: SyncConfig;\n private periodicTimer?: ReturnType<typeof setInterval>;\n private pendingChanges = new Set<string>();\n private hookIds: string[] = [];\n private initialized = false;\n private pushDebounceTimer?: ReturnType<typeof setTimeout>;\n private readonly DEBOUNCE_MS = 500;\n\n constructor(options: SyncManagerOptions) {\n this.config = options.config;\n this.hookRegistry = options.hookRegistry;\n this.adapter = new GitSyncAdapter({\n repoPath: options.repoPath,\n config: options.config,\n });\n }\n\n /**\n * Initialize the sync adapter and register hooks.\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await this.adapter.initialize();\n this.registerHooks();\n\n // Start periodic timer if configured\n if (this.config.sync.mode === 'periodic' && this.config.sync.intervalMs) {\n this.periodicTimer = setInterval(() => {\n this.pushIfPending().catch((err) => {\n console.error('[SyncManager] Periodic push error:', err);\n });\n }, this.config.sync.intervalMs);\n }\n\n this.initialized = true;\n }\n\n /**\n * Shutdown: clear timers and unregister hooks.\n */\n async shutdown(): Promise<void> {\n if (this.periodicTimer) {\n clearInterval(this.periodicTimer);\n this.periodicTimer = undefined;\n }\n if (this.pushDebounceTimer) {\n clearTimeout(this.pushDebounceTimer);\n this.pushDebounceTimer = undefined;\n }\n\n for (const hookId of this.hookIds) {\n this.hookRegistry.unregister(hookId);\n }\n this.hookIds = [];\n this.pendingChanges.clear();\n this.initialized = false;\n }\n\n // ===========================================================================\n // Public API (delegated to GitSyncAdapter)\n // ===========================================================================\n\n /**\n * Fetch remote changes without applying them.\n */\n async fetch(): Promise<FetchResult> {\n this.ensureInitialized();\n return this.adapter.fetch();\n }\n\n /**\n * Pull remote changes and merge into local storage.\n */\n async pull(options?: PullOptions): Promise<SyncResult> {\n this.ensureInitialized();\n return this.adapter.pull(options);\n }\n\n /**\n * Push local changes to the remote.\n */\n async push(options?: PushOptions): Promise<SyncResult> {\n this.ensureInitialized();\n const result = await this.adapter.push(options);\n this.pendingChanges.clear();\n return result;\n }\n\n /**\n * Get current sync status.\n */\n async status(): Promise<SyncStatus> {\n this.ensureInitialized();\n return this.adapter.status();\n }\n\n /**\n * List pending merge conflicts.\n */\n async listConflicts(): Promise<SkillConflict[]> {\n this.ensureInitialized();\n return this.adapter.listConflicts();\n }\n\n /**\n * Resolve a merge conflict for a specific skill.\n */\n async resolveConflict(skillId: string, resolution: ConflictResolution): Promise<void> {\n this.ensureInitialized();\n return this.adapter.resolveConflict(skillId, resolution);\n }\n\n /**\n * Get the set of skill IDs modified since the last push.\n */\n getPendingChanges(): ReadonlySet<string> {\n return this.pendingChanges;\n }\n\n // ===========================================================================\n // Internal\n // ===========================================================================\n\n private ensureInitialized(): void {\n if (!this.initialized) {\n throw new Error('SyncManager not initialized. Call initialize() first.');\n }\n }\n\n private registerHooks(): void {\n // Track saves\n const saveHookId = this.hookRegistry.register({\n name: 'sync-change-tracker-save',\n events: ['storage:after-save'],\n priority: 'low',\n handler: (context) => {\n const ctx = context as StorageHookContext;\n if (ctx.skill?.id) {\n this.trackChange(ctx.skill.id);\n }\n return { continue: true };\n },\n });\n this.hookIds.push(saveHookId);\n\n // Track deletes\n const deleteHookId = this.hookRegistry.register({\n name: 'sync-change-tracker-delete',\n events: ['storage:after-delete'],\n priority: 'low',\n handler: (context) => {\n const ctx = context as StorageHookContext;\n if (ctx.skill?.id) {\n this.trackChange(ctx.skill.id);\n }\n return { continue: true };\n },\n });\n this.hookIds.push(deleteHookId);\n }\n\n private trackChange(skillId: string): void {\n this.pendingChanges.add(skillId);\n\n if (this.config.sync.mode === 'on-change') {\n this.debouncedPush();\n }\n }\n\n private debouncedPush(): void {\n if (this.pushDebounceTimer) {\n clearTimeout(this.pushDebounceTimer);\n }\n this.pushDebounceTimer = setTimeout(() => {\n this.pushDebounceTimer = undefined;\n this.pushIfPending().catch((err) => {\n console.error('[SyncManager] On-change push error:', err);\n });\n }, this.DEBOUNCE_MS);\n }\n\n private async pushIfPending(): Promise<void> {\n if (this.pendingChanges.size > 0) {\n await this.push();\n }\n }\n}\n\n/**\n * Factory function for creating a SyncManager.\n */\nexport function createSyncManager(options: SyncManagerOptions): SyncManager {\n return new SyncManager(options);\n}\n","/**\n * Shared XML utilities for the serving layer\n * @packageDocumentation\n */\n\nimport type { Skill } from '../types.js';\n\n/**\n * Escape special XML characters\n */\nexport function escapeXml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n\n/**\n * Get a short summary for a skill, respecting serving metadata.\n * Checks serving.summary first, then extracts the first sentence,\n * then truncates as a last resort.\n */\nexport function getSkillSummary(skill: Skill, maxLength: number = 150): string {\n if (skill.serving?.summary) {\n return skill.serving.summary;\n }\n\n const firstSentence = skill.description.split(/[.!?]/)[0];\n if (firstSentence.length <= maxLength) {\n return firstSentence;\n }\n\n return skill.description.substring(0, maxLength - 3) + '...';\n}\n","/**\n * CatalogRenderer - Renders compressed, browsable skill catalog views\n *\n * Provides hierarchical discovery for large skill libraries by rendering\n * taxonomy trees or tag-based groupings at minimal token cost. Agents can\n * browse categories level by level instead of seeing a flat list.\n *\n * Two strategies:\n * 1. Taxonomy-based: Uses taxonomy_nodes from SQLite (preferred)\n * 2. Tag-based fallback: Groups skills by primary tag when no taxonomy exists\n *\n * @packageDocumentation\n */\n\nimport type { Skill, StorageAdapter } from '../types.js';\nimport type { CatalogRendererConfig } from './types.js';\nimport { escapeXml, getSkillSummary } from './xml-utils.js';\n\n/**\n * Taxonomy tree node shape (compatible with SQLiteStorageAdapter.getTaxonomyTree)\n */\nexport interface TaxonomyTreeNode {\n id: string;\n name: string;\n path: string[];\n skillCount: number;\n children: TaxonomyTreeNode[];\n}\n\n/**\n * Extended storage interface for catalog operations.\n * Only SQLiteStorageAdapter implements these; other adapters fall back to tag grouping.\n */\ninterface CatalogStorage extends StorageAdapter {\n getTaxonomyTree(rootPath?: string[]): Promise<TaxonomyTreeNode[]>;\n getSkillsInTaxonomyNode(nodeId: string): Promise<Skill[]>;\n}\n\n/**\n * Check if a storage adapter supports taxonomy operations\n */\nfunction hasCatalogSupport(storage: StorageAdapter): storage is CatalogStorage {\n const s = storage as unknown as Record<string, unknown>;\n return typeof s.getTaxonomyTree === 'function' && typeof s.getSkillsInTaxonomyNode === 'function';\n}\n\nconst UNTAGGED_CATEGORY = 'other';\n\nconst CATALOG_USAGE_LINES = [\n ' Use skill_browse to explore categories.',\n ' Use skill_search to find by keyword.',\n ' Use skill_expand to load a skill into your context.',\n];\n\n/**\n * Default configuration\n */\nconst DEFAULT_CONFIG: Omit<CatalogRendererConfig, 'format'> & { format: string } = {\n maxCategoriesPerLevel: 12,\n maxSkillsAtLeaf: 8,\n maxSummaryLength: 80,\n format: 'xml',\n};\n\n/**\n * Renders compressed, browsable skill catalog views for agent consumption\n */\nexport class CatalogRenderer {\n private config: CatalogRendererConfig;\n private overviewCache: { value: string; timestamp: number } | null = null;\n private static readonly CACHE_TTL_MS = 60_000;\n\n constructor(\n private storage: StorageAdapter,\n config?: Partial<CatalogRendererConfig>,\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Render level-0 catalog overview for system prompt injection.\n * Shows top-level categories with counts. ~200 tokens.\n * Returns empty string if no skills exist.\n * Results are cached for 60 seconds to avoid repeated storage queries.\n */\n async renderOverview(): Promise<string> {\n // Return cached overview if fresh\n if (this.overviewCache && (Date.now() - this.overviewCache.timestamp) < CatalogRenderer.CACHE_TTL_MS) {\n return this.overviewCache.value;\n }\n\n let result: string;\n\n if (hasCatalogSupport(this.storage)) {\n const tree = await this.storage.getTaxonomyTree();\n if (tree.length > 0) {\n result = this.renderOverviewFromNodes(tree);\n this.overviewCache = { value: result, timestamp: Date.now() };\n return result;\n }\n }\n\n result = await this.renderOverviewFromTags();\n this.overviewCache = { value: result, timestamp: Date.now() };\n return result;\n }\n\n /**\n * Render a specific category path for browse drill-down.\n * Shows subcategories at intermediate nodes, or skill summaries at leaf nodes.\n */\n async renderCategory(path: string[]): Promise<string> {\n if (hasCatalogSupport(this.storage)) {\n return this.renderCategoryFromTaxonomy(this.storage, path);\n }\n\n return this.renderCategoryFromTags(path);\n }\n\n /**\n * Invalidate the overview cache (e.g., after skill changes).\n */\n invalidateCache(): void {\n this.overviewCache = null;\n }\n\n // ===========================================================================\n // OVERVIEW RENDERING (shared structure)\n // ===========================================================================\n\n /**\n * Render the overview XML shell with a list of categories.\n * Used by both taxonomy-based and tag-based paths.\n */\n private renderOverviewXml(totalSkills: number, categories: Array<{ name: string; count: number }>): string {\n const lines: string[] = [];\n lines.push(`<skill_catalog total=\"${totalSkills}\">`);\n lines.push(' <usage>');\n lines.push(...CATALOG_USAGE_LINES);\n lines.push(' </usage>');\n lines.push(' <categories>');\n\n for (const cat of categories) {\n lines.push(` <category path=\"${escapeXml(cat.name)}\" count=\"${cat.count}\" />`);\n }\n\n lines.push(' </categories>');\n lines.push('</skill_catalog>');\n return lines.join('\\n');\n }\n\n // ===========================================================================\n // TAXONOMY-BASED RENDERING\n // ===========================================================================\n\n private renderOverviewFromNodes(roots: TaxonomyTreeNode[]): string {\n const counted = this.withCounts(roots);\n const totalSkills = counted.reduce((sum, c) => sum + c.count, 0);\n const categories = counted\n .sort((a, b) => b.count - a.count)\n .slice(0, this.config.maxCategoriesPerLevel)\n .map(c => ({ name: c.node.name, count: c.count }));\n\n return this.renderOverviewXml(totalSkills, categories);\n }\n\n private async renderCategoryFromTaxonomy(storage: CatalogStorage, path: string[]): Promise<string> {\n const tree = await storage.getTaxonomyTree(path);\n const pathStr = path.join('/');\n\n // If tree has nodes with children, render as subcategories\n if (tree.length > 0 && tree.some(n => n.children.length > 0)) {\n const root = tree[0];\n const rootCount = this.countNodeSkills(root);\n const counted = this.withCounts(root.children);\n const children = counted\n .sort((a, b) => b.count - a.count)\n .slice(0, this.config.maxCategoriesPerLevel);\n\n const lines: string[] = [];\n lines.push(`<catalog_browse path=\"${escapeXml(pathStr)}\" count=\"${rootCount}\">`);\n lines.push(' <subcategories>');\n\n for (const { node: child, count } of children) {\n const childPath = [...path, child.name].join('/');\n lines.push(` <category path=\"${escapeXml(childPath)}\" count=\"${count}\" />`);\n }\n\n lines.push(' </subcategories>');\n lines.push('</catalog_browse>');\n return lines.join('\\n');\n }\n\n // Leaf node — get skills placed in this taxonomy node\n if (tree.length > 0) {\n const nodeId = tree[0].id;\n const skills = await storage.getSkillsInTaxonomyNode(nodeId);\n return this.renderLeafSkills(skills, pathStr, tree[0].skillCount);\n }\n\n // No results\n return `<catalog_browse path=\"${escapeXml(pathStr)}\" count=\"0\" />`;\n }\n\n // ===========================================================================\n // TAG-BASED FALLBACK\n // ===========================================================================\n\n private async renderOverviewFromTags(): Promise<string> {\n const skills = await this.storage.listSkills({ status: ['active'] });\n if (skills.length === 0) return '';\n\n const tagCounts = this.groupByPrimaryTag(skills);\n const categories = Array.from(tagCounts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, this.config.maxCategoriesPerLevel)\n .map(([name, count]) => ({ name, count }));\n\n return this.renderOverviewXml(skills.length, categories);\n }\n\n private async renderCategoryFromTags(path: string[]): Promise<string> {\n if (path.length === 0) {\n return this.renderOverviewFromTags();\n }\n\n const tag = path[0];\n // Use storage-level tag filtering instead of loading all skills\n const matching = await this.storage.listSkills({ status: ['active'], tags: [tag] });\n\n const pathStr = path.join('/');\n return this.renderLeafSkills(matching, pathStr, matching.length);\n }\n\n // ===========================================================================\n // SHARED RENDERING HELPERS\n // ===========================================================================\n\n private renderLeafSkills(skills: Skill[], pathStr: string, totalCount: number): string {\n const displayed = skills.slice(0, this.config.maxSkillsAtLeaf);\n const remaining = totalCount - displayed.length;\n\n const lines: string[] = [];\n lines.push(`<catalog_browse path=\"${escapeXml(pathStr)}\" count=\"${totalCount}\">`);\n lines.push(' <skills>');\n\n for (const skill of displayed) {\n const tags = skill.tags.length > 0 ? ` tags=\"${escapeXml(skill.tags.join(', '))}\"` : '';\n const desc = getSkillSummary(skill, this.config.maxSummaryLength);\n lines.push(` <skill id=\"${escapeXml(skill.id)}\"${tags}>`);\n lines.push(` ${escapeXml(desc)}`);\n lines.push(' </skill>');\n }\n\n lines.push(' </skills>');\n\n if (remaining > 0) {\n lines.push(` <more remaining=\"${remaining}\">`);\n lines.push(' Use skill_search for more, or skill_expand {id} to load.');\n lines.push(' </more>');\n }\n\n lines.push('</catalog_browse>');\n return lines.join('\\n');\n }\n\n // ===========================================================================\n // UTILITIES\n // ===========================================================================\n\n private groupByPrimaryTag(skills: Skill[]): Map<string, number> {\n const tagCounts = new Map<string, number>();\n for (const skill of skills) {\n const tag = skill.tags[0] || UNTAGGED_CATEGORY;\n tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1);\n }\n return tagCounts;\n }\n\n /**\n * Pre-compute counts for a list of nodes, avoiding redundant recursive walks.\n */\n private withCounts(nodes: TaxonomyTreeNode[]): Array<{ node: TaxonomyTreeNode; count: number }> {\n return nodes.map(node => ({ node, count: this.countNodeSkills(node) }));\n }\n\n private countNodeSkills(node: TaxonomyTreeNode): number {\n let count = node.skillCount;\n for (const child of node.children) {\n count += this.countNodeSkills(child);\n }\n return count;\n }\n}\n","/**\n * LoadoutCompiler - Compiles skills from flexible criteria\n *\n * Supports multiple selection strategies:\n * - Explicit include/exclude\n * - Tag-based filtering\n * - Quality/status filtering\n * - Semantic matching\n * - Relationship traversal\n *\n * @packageDocumentation\n */\n\nimport type { Skill, SkillStatus, StorageAdapter } from '../types.js';\nimport type { LoadoutCriteria, LoadoutCompilerConfig } from './types.js';\n\n/**\n * Default configuration for LoadoutCompiler\n */\nconst DEFAULT_CONFIG: Required<LoadoutCompilerConfig> = {\n defaultMaxSkills: 15,\n defaultStatus: ['active'],\n semanticThreshold: 0.6,\n};\n\n/**\n * Compiles skills from flexible criteria\n */\nexport class LoadoutCompiler {\n private config: Required<LoadoutCompilerConfig>;\n\n constructor(\n private storage: StorageAdapter,\n config?: LoadoutCompilerConfig\n ) {\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n };\n }\n\n /**\n * Main entry point - compile skills from criteria\n */\n async compile(criteria: LoadoutCriteria): Promise<Skill[]> {\n // Start with all skills matching status filter\n const status = criteria.status ?? this.config.defaultStatus;\n let candidates = await this.storage.listSkills({ status });\n\n // Apply filters in order\n candidates = this.applyExplicitFilters(candidates, criteria);\n candidates = this.applyTagFilters(candidates, criteria);\n candidates = this.applyQualityFilters(candidates, criteria);\n candidates = await this.applySemanticFilters(candidates, criteria);\n candidates = await this.applyRelationshipFilters(candidates, criteria);\n candidates = this.applyLimits(candidates, criteria);\n\n return candidates;\n }\n\n /**\n * Compile based on a task description (semantic matching)\n */\n async compileForTask(taskDescription: string): Promise<Skill[]> {\n return this.compile({\n taskDescription,\n priorityOrder: 'relevance',\n maxSkills: this.config.defaultMaxSkills,\n });\n }\n\n /**\n * Compile from a named profile\n */\n async compileFromProfile(\n profileName: string,\n profiles: Record<string, LoadoutCriteria>\n ): Promise<Skill[]> {\n const profile = profiles[profileName];\n if (!profile) {\n throw new Error(`Profile not found: ${profileName}`);\n }\n return this.compile(profile);\n }\n\n /**\n * Merge two loadouts based on mode\n */\n mergeLoadouts(\n current: Skill[],\n additions: Skill[],\n mode: 'replace' | 'merge' | 'subtract' = 'merge'\n ): Skill[] {\n switch (mode) {\n case 'replace':\n return additions;\n\n case 'merge': {\n const currentIds = new Set(current.map((s) => s.id));\n const newSkills = additions.filter((s) => !currentIds.has(s.id));\n return [...current, ...newSkills];\n }\n\n case 'subtract': {\n const removeIds = new Set(additions.map((s) => s.id));\n return current.filter((s) => !removeIds.has(s.id));\n }\n }\n }\n\n // ===========================================================================\n // Filter Methods\n // ===========================================================================\n\n /**\n * Apply explicit include/exclude filters\n */\n applyExplicitFilters(skills: Skill[], criteria: LoadoutCriteria): Skill[] {\n let result = skills;\n\n // Exclude specific IDs\n if (criteria.exclude && criteria.exclude.length > 0) {\n const excludeSet = new Set(criteria.exclude);\n result = result.filter((s) => !excludeSet.has(s.id));\n }\n\n // If include is specified, only keep those (but we already filtered from all skills)\n // Include acts as an additive filter - ensure these are present\n if (criteria.include && criteria.include.length > 0) {\n const includeSet = new Set(criteria.include);\n const currentIds = new Set(result.map((s) => s.id));\n\n // Keep skills that are either already included OR in the include list\n // We need to fetch any missing included skills\n const includedSkills = result.filter((s) => includeSet.has(s.id));\n const otherSkills = result.filter((s) => !includeSet.has(s.id));\n\n // For now, just filter to include list if provided\n // In a full implementation, we might fetch missing skills\n if (includedSkills.length > 0) {\n result = [...includedSkills, ...otherSkills];\n }\n }\n\n return result;\n }\n\n /**\n * Apply tag-based filters\n */\n applyTagFilters(skills: Skill[], criteria: LoadoutCriteria): Skill[] {\n let result = skills;\n\n // Match any of these tags\n if (criteria.tags && criteria.tags.length > 0) {\n const tagSet = new Set(criteria.tags);\n result = result.filter((s) => s.tags.some((t) => tagSet.has(t)));\n }\n\n // Must have all of these tags\n if (criteria.tagsAll && criteria.tagsAll.length > 0) {\n result = result.filter((s) =>\n criteria.tagsAll!.every((t) => s.tags.includes(t))\n );\n }\n\n return result;\n }\n\n /**\n * Apply quality/status filters\n */\n applyQualityFilters(skills: Skill[], criteria: LoadoutCriteria): Skill[] {\n let result = skills;\n\n // Filter by minimum success rate\n if (criteria.minSuccessRate !== undefined) {\n result = result.filter(\n (s) => s.metrics.successRate >= criteria.minSuccessRate!\n );\n }\n\n // Filter by author\n if (criteria.author) {\n result = result.filter((s) => s.author === criteria.author);\n }\n\n return result;\n }\n\n /**\n * Apply semantic filters (task description, problem context, etc.)\n *\n * Currently returns skills unchanged. Semantic matching was removed;\n * use SQLite FTS via storage.searchSkills() for keyword-based search.\n */\n async applySemanticFilters(\n skills: Skill[],\n _criteria: LoadoutCriteria\n ): Promise<Skill[]> {\n return skills;\n }\n\n /**\n * Apply relationship-based filters (root skills, dependencies)\n */\n async applyRelationshipFilters(\n skills: Skill[],\n criteria: LoadoutCriteria\n ): Promise<Skill[]> {\n // Skip if no relationship criteria\n if (!criteria.rootSkills || criteria.rootSkills.length === 0) {\n return skills;\n }\n\n const skillMap = new Map(skills.map((s) => [s.id, s]));\n const result = new Set<string>();\n const maxDepth = criteria.depth ?? 2;\n\n // Start with root skills\n for (const rootId of criteria.rootSkills) {\n if (skillMap.has(rootId)) {\n result.add(rootId);\n }\n }\n\n // Traverse relationships\n if (criteria.includeDependencies || criteria.includeRelated) {\n const toVisit = [...criteria.rootSkills];\n const visited = new Set<string>();\n let currentDepth = 0;\n\n // depth=1 means: include roots (depth 0) + their immediate deps (depth 1)\n // So we continue while currentDepth <= maxDepth\n while (toVisit.length > 0 && currentDepth <= maxDepth) {\n const currentBatch = [...toVisit];\n toVisit.length = 0;\n\n for (const skillId of currentBatch) {\n if (visited.has(skillId)) continue;\n visited.add(skillId);\n\n const skill = skillMap.get(skillId);\n if (!skill) continue;\n\n // Always add the skill to result\n result.add(skillId);\n\n // Only process relationships if they exist\n if (!skill.relationships) continue;\n\n for (const rel of skill.relationships) {\n const targetId = rel.targetSkillId;\n if (!skillMap.has(targetId) || visited.has(targetId)) continue;\n\n const shouldInclude =\n (criteria.includeDependencies && rel.type === 'depends_on') ||\n (criteria.includeRelated && rel.type === 'related');\n\n if (shouldInclude) {\n toVisit.push(targetId);\n }\n }\n }\n\n currentDepth++;\n }\n }\n\n // Return skills in result set, preserving order from original skills array\n return skills.filter((s) => result.has(s.id));\n }\n\n /**\n * Apply limits and sorting\n */\n applyLimits(skills: Skill[], criteria: LoadoutCriteria): Skill[] {\n let result = skills;\n\n // Sort by priority order\n if (criteria.priorityOrder) {\n result = [...result].sort((a, b) => {\n switch (criteria.priorityOrder) {\n case 'usage':\n return b.metrics.usageCount - a.metrics.usageCount;\n case 'successRate':\n return b.metrics.successRate - a.metrics.successRate;\n case 'recent':\n const aDate = a.metrics.lastUsed?.getTime() ?? 0;\n const bDate = b.metrics.lastUsed?.getTime() ?? 0;\n return bDate - aDate;\n case 'relevance':\n default:\n // Already sorted by relevance from semantic filter\n return 0;\n }\n });\n }\n\n // Apply max skills limit\n const maxSkills = criteria.maxSkills ?? this.config.defaultMaxSkills;\n if (result.length > maxSkills) {\n result = result.slice(0, maxSkills);\n }\n\n // Apply token budget (if skills have token estimates)\n if (criteria.maxTokens !== undefined) {\n let totalTokens = 0;\n const withinBudget: Skill[] = [];\n\n for (const skill of result) {\n const estimate = skill.serving?.tokenEstimate ?? this.estimateTokens(skill);\n if (totalTokens + estimate <= criteria.maxTokens) {\n withinBudget.push(skill);\n totalTokens += estimate;\n }\n }\n\n result = withinBudget;\n }\n\n return result;\n }\n\n // ===========================================================================\n // Helpers\n // ===========================================================================\n\n /**\n * Estimate token count for a skill (rough approximation)\n */\n private estimateTokens(skill: Skill): number {\n const text = [\n skill.name,\n skill.description,\n skill.instructions,\n ].join(' ');\n\n // Rough estimate: 1 token ≈ 4 characters\n return Math.ceil(text.length / 4);\n }\n}\n","/**\n * ProjectDetector - Analyzes project directories to infer skill requirements\n *\n * Detects:\n * - Project type (Node.js, Python, Rust, Go, Java)\n * - Frameworks (React, Express, FastAPI, etc.)\n * - Patterns (CI/CD, Docker, etc.)\n * - Package manager\n *\n * @packageDocumentation\n */\n\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport type { ProjectContext, LoadoutCriteria } from './types.js';\n\n/**\n * Framework detection patterns\n */\ninterface FrameworkPattern {\n /** Framework name */\n name: string;\n /** Package name to look for in dependencies */\n packageName: string;\n /** Tags to add when detected */\n tags: string[];\n}\n\n/**\n * Project type patterns\n */\ninterface ProjectTypePattern {\n /** Manifest file to check for */\n manifestFile: string;\n /** Project type name */\n type: string;\n /** Tags to add when detected */\n tags: string[];\n /** Package manager */\n packageManager?: string;\n}\n\n/**\n * Directory patterns\n */\ninterface DirectoryPattern {\n /** Pattern to check (file or directory) */\n pattern: string;\n /** Feature name */\n feature: string;\n /** Tags to add when detected */\n tags: string[];\n}\n\n/**\n * Detects project context from file system\n */\nexport class ProjectDetector {\n /** Cache for project context */\n private cache = new Map<string, ProjectContext>();\n\n /** Project type patterns */\n private static PROJECT_TYPES: ProjectTypePattern[] = [\n { manifestFile: 'package.json', type: 'nodejs', tags: ['nodejs', 'javascript'], packageManager: 'npm' },\n { manifestFile: 'pyproject.toml', type: 'python', tags: ['python'], packageManager: 'pip' },\n { manifestFile: 'requirements.txt', type: 'python', tags: ['python'], packageManager: 'pip' },\n { manifestFile: 'Cargo.toml', type: 'rust', tags: ['rust'], packageManager: 'cargo' },\n { manifestFile: 'go.mod', type: 'go', tags: ['go', 'golang'] },\n { manifestFile: 'pom.xml', type: 'java', tags: ['java', 'maven'], packageManager: 'maven' },\n { manifestFile: 'build.gradle', type: 'java', tags: ['java', 'gradle'], packageManager: 'gradle' },\n { manifestFile: 'build.gradle.kts', type: 'kotlin', tags: ['kotlin', 'gradle'], packageManager: 'gradle' },\n ];\n\n /** TypeScript detection */\n private static TYPESCRIPT_FILES = ['tsconfig.json', 'tsconfig.base.json'];\n\n /** Node.js framework patterns */\n private static NODE_FRAMEWORKS: FrameworkPattern[] = [\n { name: 'react', packageName: 'react', tags: ['react', 'frontend'] },\n { name: 'next', packageName: 'next', tags: ['nextjs', 'react', 'fullstack'] },\n { name: 'vue', packageName: 'vue', tags: ['vue', 'frontend'] },\n { name: 'nuxt', packageName: 'nuxt', tags: ['nuxt', 'vue', 'fullstack'] },\n { name: 'angular', packageName: '@angular/core', tags: ['angular', 'frontend'] },\n { name: 'svelte', packageName: 'svelte', tags: ['svelte', 'frontend'] },\n { name: 'express', packageName: 'express', tags: ['express', 'backend', 'api'] },\n { name: 'fastify', packageName: 'fastify', tags: ['fastify', 'backend', 'api'] },\n { name: 'nestjs', packageName: '@nestjs/core', tags: ['nestjs', 'backend', 'api'] },\n { name: 'hono', packageName: 'hono', tags: ['hono', 'backend', 'api'] },\n { name: 'prisma', packageName: '@prisma/client', tags: ['prisma', 'database', 'orm'] },\n { name: 'drizzle', packageName: 'drizzle-orm', tags: ['drizzle', 'database', 'orm'] },\n { name: 'typeorm', packageName: 'typeorm', tags: ['typeorm', 'database', 'orm'] },\n { name: 'jest', packageName: 'jest', tags: ['testing', 'jest'] },\n { name: 'vitest', packageName: 'vitest', tags: ['testing', 'vitest'] },\n { name: 'playwright', packageName: '@playwright/test', tags: ['testing', 'e2e', 'playwright'] },\n { name: 'cypress', packageName: 'cypress', tags: ['testing', 'e2e', 'cypress'] },\n ];\n\n /** Python framework patterns (from pyproject.toml or requirements.txt) */\n private static PYTHON_FRAMEWORKS: FrameworkPattern[] = [\n { name: 'fastapi', packageName: 'fastapi', tags: ['fastapi', 'backend', 'api'] },\n { name: 'django', packageName: 'django', tags: ['django', 'backend', 'fullstack'] },\n { name: 'flask', packageName: 'flask', tags: ['flask', 'backend', 'api'] },\n { name: 'sqlalchemy', packageName: 'sqlalchemy', tags: ['sqlalchemy', 'database', 'orm'] },\n { name: 'pytest', packageName: 'pytest', tags: ['testing', 'pytest'] },\n { name: 'pydantic', packageName: 'pydantic', tags: ['pydantic', 'validation'] },\n ];\n\n /** Directory patterns */\n private static DIRECTORY_PATTERNS: DirectoryPattern[] = [\n { pattern: '.github/workflows', feature: 'github-actions', tags: ['ci', 'github-actions'] },\n { pattern: '.gitlab-ci.yml', feature: 'gitlab-ci', tags: ['ci', 'gitlab'] },\n { pattern: 'Dockerfile', feature: 'docker', tags: ['docker', 'containers'] },\n { pattern: 'docker-compose.yml', feature: 'docker-compose', tags: ['docker', 'containers'] },\n { pattern: 'docker-compose.yaml', feature: 'docker-compose', tags: ['docker', 'containers'] },\n { pattern: 'terraform', feature: 'terraform', tags: ['terraform', 'infrastructure'] },\n { pattern: 'kubernetes', feature: 'kubernetes', tags: ['kubernetes', 'infrastructure'] },\n { pattern: 'k8s', feature: 'kubernetes', tags: ['kubernetes', 'infrastructure'] },\n { pattern: '.env.example', feature: 'env-config', tags: ['configuration'] },\n { pattern: 'prisma/schema.prisma', feature: 'prisma', tags: ['prisma', 'database'] },\n ];\n\n /**\n * Detect project context from a directory\n */\n async detectProjectContext(projectPath: string): Promise<ProjectContext> {\n // Check cache first\n const cached = this.cache.get(projectPath);\n if (cached) {\n return cached;\n }\n\n const context: ProjectContext = {\n type: 'unknown',\n frameworks: [],\n patterns: [],\n packageManager: undefined,\n };\n\n // Detect project type\n this.detectProjectType(projectPath, context);\n\n // Detect TypeScript\n if (this.hasTypeScript(projectPath)) {\n if (!context.patterns.includes('typescript')) {\n context.patterns.push('typescript');\n }\n }\n\n // Detect frameworks based on project type\n if (context.type === 'nodejs') {\n this.detectNodeFrameworks(projectPath, context);\n } else if (context.type === 'python') {\n this.detectPythonFrameworks(projectPath, context);\n }\n\n // Detect directory patterns\n this.detectDirectoryPatterns(projectPath, context);\n\n // Cache the result\n this.cache.set(projectPath, context);\n\n return context;\n }\n\n /**\n * Convert project context to loadout criteria\n */\n contextToCriteria(context: ProjectContext): LoadoutCriteria {\n const tags = new Set<string>();\n\n // Add project type tags\n if (context.type !== 'unknown') {\n tags.add(context.type);\n }\n\n // Add framework tags\n for (const framework of context.frameworks) {\n // Find framework pattern and add its tags\n const nodePattern = ProjectDetector.NODE_FRAMEWORKS.find(f => f.name === framework);\n if (nodePattern) {\n nodePattern.tags.forEach(t => tags.add(t));\n }\n const pythonPattern = ProjectDetector.PYTHON_FRAMEWORKS.find(f => f.name === framework);\n if (pythonPattern) {\n pythonPattern.tags.forEach(t => tags.add(t));\n }\n }\n\n // Add pattern tags\n for (const pattern of context.patterns) {\n const dirPattern = ProjectDetector.DIRECTORY_PATTERNS.find(p => p.feature === pattern);\n if (dirPattern) {\n dirPattern.tags.forEach(t => tags.add(t));\n }\n // Also add the pattern itself\n tags.add(pattern);\n }\n\n return {\n tags: Array.from(tags),\n priorityOrder: 'relevance',\n };\n }\n\n /**\n * Clear the detection cache\n */\n clearCache(): void {\n this.cache.clear();\n }\n\n // ===========================================================================\n // Private detection methods\n // ===========================================================================\n\n /**\n * Detect project type from manifest files\n */\n private detectProjectType(projectPath: string, context: ProjectContext): void {\n for (const pattern of ProjectDetector.PROJECT_TYPES) {\n if (existsSync(join(projectPath, pattern.manifestFile))) {\n context.type = pattern.type;\n context.packageManager = pattern.packageManager;\n context.patterns.push(...pattern.tags);\n return;\n }\n }\n }\n\n /**\n * Check for TypeScript\n */\n private hasTypeScript(projectPath: string): boolean {\n return ProjectDetector.TYPESCRIPT_FILES.some(file =>\n existsSync(join(projectPath, file))\n );\n }\n\n /**\n * Detect Node.js frameworks from package.json\n */\n private detectNodeFrameworks(projectPath: string, context: ProjectContext): void {\n const packageJsonPath = join(projectPath, 'package.json');\n if (!existsSync(packageJsonPath)) return;\n\n try {\n const content = readFileSync(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n\n for (const framework of ProjectDetector.NODE_FRAMEWORKS) {\n if (allDeps[framework.packageName]) {\n context.frameworks.push(framework.name);\n }\n }\n\n // Detect package manager from lock files\n if (existsSync(join(projectPath, 'pnpm-lock.yaml'))) {\n context.packageManager = 'pnpm';\n } else if (existsSync(join(projectPath, 'yarn.lock'))) {\n context.packageManager = 'yarn';\n } else if (existsSync(join(projectPath, 'bun.lockb'))) {\n context.packageManager = 'bun';\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n /**\n * Detect Python frameworks from dependencies\n */\n private detectPythonFrameworks(projectPath: string, context: ProjectContext): void {\n // Check pyproject.toml\n const pyprojectPath = join(projectPath, 'pyproject.toml');\n if (existsSync(pyprojectPath)) {\n try {\n const content = readFileSync(pyprojectPath, 'utf-8');\n for (const framework of ProjectDetector.PYTHON_FRAMEWORKS) {\n if (content.includes(framework.packageName)) {\n context.frameworks.push(framework.name);\n }\n }\n } catch {\n // Ignore read errors\n }\n }\n\n // Check requirements.txt\n const requirementsPath = join(projectPath, 'requirements.txt');\n if (existsSync(requirementsPath)) {\n try {\n const content = readFileSync(requirementsPath, 'utf-8');\n for (const framework of ProjectDetector.PYTHON_FRAMEWORKS) {\n if (content.includes(framework.packageName)) {\n if (!context.frameworks.includes(framework.name)) {\n context.frameworks.push(framework.name);\n }\n }\n }\n } catch {\n // Ignore read errors\n }\n }\n }\n\n /**\n * Detect patterns from directory structure\n */\n private detectDirectoryPatterns(projectPath: string, context: ProjectContext): void {\n for (const pattern of ProjectDetector.DIRECTORY_PATTERNS) {\n if (existsSync(join(projectPath, pattern.pattern))) {\n if (!context.patterns.includes(pattern.feature)) {\n context.patterns.push(pattern.feature);\n }\n }\n }\n }\n}\n","/**\n * ViewRenderer - Renders loadout state for agent consumption\n *\n * Supports multiple output formats:\n * - XML (OpenSkills-compatible)\n * - Markdown (debugging/display)\n * - SKILL.md format\n *\n * @packageDocumentation\n */\n\nimport type { Skill } from '../types.js';\nimport type { LoadoutState, SkillSummary } from './types.js';\nimport { escapeXml, getSkillSummary } from './xml-utils.js';\n\n/**\n * Configuration for ViewRenderer\n */\nexport interface ViewRendererConfig {\n /** Include token estimates in output */\n includeTokenEstimates?: boolean;\n /** Maximum summary length (characters) */\n maxSummaryLength?: number;\n}\n\n/**\n * Default configuration\n */\nconst DEFAULT_CONFIG: Required<ViewRendererConfig> = {\n includeTokenEstimates: false,\n maxSummaryLength: 150,\n};\n\n/**\n * Renders loadout state for agent consumption\n */\nexport class ViewRenderer {\n private config: Required<ViewRendererConfig>;\n\n constructor(config?: ViewRendererConfig) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Render loadout state as OpenSkills-compatible XML\n */\n renderXml(state: LoadoutState): string {\n const lines: string[] = [];\n\n lines.push('<skills_system>');\n lines.push('<usage>');\n lines.push('Skills in your current loadout. Use skill_expand to see full content.');\n lines.push('Use loadout_search to find additional skills. Use loadout_add to request them.');\n lines.push('</usage>');\n lines.push('');\n lines.push('<available_skills>');\n\n // Render each skill\n for (const [id, skill] of state.available) {\n const isExpanded = state.expanded.has(id);\n\n if (isExpanded) {\n lines.push(`<skill id=\"${this.escapeXml(id)}\" state=\"expanded\">`);\n lines.push(` <name>${this.escapeXml(skill.name)}</name>`);\n lines.push(` <description>${this.escapeXml(skill.description)}</description>`);\n if (this.config.includeTokenEstimates) {\n const tokens = this.estimateSkillTokens(skill);\n lines.push(` <tokens>${tokens}</tokens>`);\n }\n lines.push(' <content>');\n lines.push(skill.instructions.split('\\n').map(line => ' ' + line).join('\\n'));\n lines.push(' </content>');\n\n // Relationship hints for expanded skills\n if (skill.relationships && skill.relationships.length > 0) {\n const hints = skill.relationships\n .filter(r => r.confidence >= 0.5)\n .sort((a, b) => b.confidence - a.confidence)\n .slice(0, 5);\n\n if (hints.length > 0) {\n lines.push(' <related>');\n for (const rel of hints) {\n const relatedSkill = state.available.get(rel.targetSkillId);\n const desc = relatedSkill\n ? this.getSummary(relatedSkill)\n : rel.targetSkillId;\n lines.push(` <see_also id=\"${this.escapeXml(rel.targetSkillId)}\" type=\"${rel.type}\">${this.escapeXml(desc)}</see_also>`);\n }\n lines.push(' </related>');\n }\n }\n\n lines.push('</skill>');\n } else {\n const summary = this.getSummary(skill);\n lines.push(`<skill id=\"${this.escapeXml(id)}\" state=\"available\">`);\n lines.push(` <name>${this.escapeXml(skill.name)}</name>`);\n lines.push(` <description>${this.escapeXml(summary)}</description>`);\n if (skill.tags.length > 0) {\n lines.push(` <tags>${skill.tags.map(t => this.escapeXml(t)).join(', ')}</tags>`);\n }\n lines.push('</skill>');\n }\n lines.push('');\n }\n\n lines.push('</available_skills>');\n\n // Render pending requests if any\n if (state.pending.size > 0) {\n lines.push('');\n lines.push('<pending_requests>');\n for (const skillId of state.pending) {\n lines.push(` <skill id=\"${this.escapeXml(skillId)}\">Awaiting approval</skill>`);\n }\n lines.push('</pending_requests>');\n }\n\n lines.push('</skills_system>');\n\n return lines.join('\\n');\n }\n\n /**\n * Render loadout state as Markdown (for debugging)\n */\n renderMarkdown(state: LoadoutState): string {\n const lines: string[] = [];\n\n lines.push('# Current Skill Loadout');\n lines.push('');\n\n // Summary table\n lines.push('| Skill | Status | Tags |');\n lines.push('|-------|--------|------|');\n\n for (const [id, skill] of state.available) {\n const status = state.expanded.has(id) ? '🔓 Expanded' : '📦 Available';\n const tags = skill.tags.slice(0, 3).join(', ');\n lines.push(`| ${skill.name} | ${status} | ${tags} |`);\n }\n\n if (state.pending.size > 0) {\n for (const skillId of state.pending) {\n lines.push(`| ${skillId} | ⏳ Pending | - |`);\n }\n }\n\n lines.push('');\n\n // Expanded skill details\n const expandedSkills = Array.from(state.available.entries())\n .filter(([id]) => state.expanded.has(id));\n\n if (expandedSkills.length > 0) {\n lines.push('## Expanded Skills');\n lines.push('');\n\n for (const [, skill] of expandedSkills) {\n lines.push(`### ${skill.name}`);\n lines.push('');\n lines.push(skill.instructions);\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Render a skill in SKILL.md format\n */\n renderSkillMd(skill: Skill): string {\n const lines: string[] = [];\n\n // YAML frontmatter\n lines.push('---');\n lines.push(`name: ${skill.id}`);\n lines.push(`description: ${this.getSummary(skill)}`);\n if (skill.tags.length > 0) {\n lines.push(`tags: [${skill.tags.join(', ')}]`);\n }\n lines.push('---');\n lines.push('');\n\n // Content\n lines.push(skill.instructions);\n lines.push('');\n\n return lines.join('\\n');\n }\n\n /**\n * Estimate total tokens for a loadout state\n */\n estimateTokens(state: LoadoutState): number {\n let total = 0;\n\n // Base overhead for XML structure\n total += 200;\n\n for (const [id, skill] of state.available) {\n if (state.expanded.has(id)) {\n // Full content\n total += this.estimateSkillTokens(skill);\n } else {\n // Just summary\n total += this.estimateSummaryTokens(skill);\n }\n }\n\n return total;\n }\n\n /**\n * Convert loadout state to array of skill summaries\n */\n toSummaries(state: LoadoutState): SkillSummary[] {\n const summaries: SkillSummary[] = [];\n\n for (const [id, skill] of state.available) {\n summaries.push({\n id,\n name: skill.name,\n description: this.getSummary(skill),\n expanded: state.expanded.has(id),\n tags: skill.tags,\n });\n }\n\n return summaries;\n }\n\n // ===========================================================================\n // Private helpers\n // ===========================================================================\n\n /**\n * Get summary for a skill (short description).\n * Delegates to shared getSkillSummary utility.\n */\n private getSummary(skill: Skill): string {\n return getSkillSummary(skill, this.config.maxSummaryLength);\n }\n\n /**\n * Escape special XML characters.\n * Delegates to shared escapeXml utility.\n */\n private escapeXml(str: string): string {\n return escapeXml(str);\n }\n\n /**\n * Estimate tokens for a full skill\n */\n private estimateSkillTokens(skill: Skill): number {\n // Use explicit estimate if available\n if (skill.serving?.tokenEstimate) {\n return skill.serving.tokenEstimate;\n }\n\n // Estimate based on content length\n const content = [\n skill.name,\n skill.description,\n skill.instructions,\n ].join(' ');\n\n // Rough estimate: 1 token ≈ 4 characters\n return Math.ceil(content.length / 4);\n }\n\n /**\n * Estimate tokens for a skill summary\n */\n private estimateSummaryTokens(skill: Skill): number {\n const summary = this.getSummary(skill);\n const content = [skill.name, summary, skill.tags.join(' ')].join(' ');\n return Math.ceil(content.length / 4);\n }\n}\n","/**\n * Built-in Loadout Profiles\n *\n * Pre-configured loadout criteria for common use cases.\n * These can be used directly or as templates for custom profiles.\n *\n * @packageDocumentation\n */\n\nimport type { LoadoutCriteria } from '../types.js';\n\n/**\n * Code Review Profile\n *\n * Optimized for reviewing code quality, security, and best practices.\n * Focuses on skills related to code analysis, security patterns, and quality gates.\n */\nexport const codeReviewProfile: LoadoutCriteria = {\n tags: ['review', 'quality', 'security', 'best-practices'],\n taskDescription: 'review code for quality, security, and best practices',\n maxSkills: 6,\n priorityOrder: 'relevance',\n};\n\n/**\n * Implementation Profile\n *\n * Optimized for writing new code and features.\n * Focuses on TDD, coding standards, and development patterns.\n */\nexport const implementationProfile: LoadoutCriteria = {\n rootSkills: ['tdd-workflow', 'coding-standards'],\n includeDependencies: true,\n tags: ['development', 'testing', 'patterns'],\n maxSkills: 8,\n priorityOrder: 'relevance',\n};\n\n/**\n * Debugging Profile\n *\n * Optimized for diagnosing and fixing bugs.\n * Focuses on error analysis, logging, and debugging techniques.\n */\nexport const debuggingProfile: LoadoutCriteria = {\n taskDescription: 'diagnose and fix bugs, analyze errors, debug issues',\n tags: ['debugging', 'logging', 'error-handling', 'troubleshooting'],\n maxSkills: 5,\n priorityOrder: 'relevance',\n};\n\n/**\n * Security Profile\n *\n * Optimized for security-focused work.\n * Focuses on vulnerability detection, secure coding, and security reviews.\n */\nexport const securityProfile: LoadoutCriteria = {\n tags: ['security'],\n tagsAll: ['security'],\n taskDescription: 'security review, vulnerability detection, secure coding',\n maxSkills: 8,\n minSuccessRate: 0.7,\n priorityOrder: 'relevance',\n};\n\n/**\n * Testing Profile\n *\n * Optimized for writing and maintaining tests.\n * Focuses on test patterns, coverage, and test-driven development.\n */\nexport const testingProfile: LoadoutCriteria = {\n tags: ['testing', 'tdd', 'e2e', 'unit-test', 'integration-test'],\n taskDescription: 'write tests, improve coverage, test-driven development',\n maxSkills: 6,\n priorityOrder: 'relevance',\n};\n\n/**\n * Refactoring Profile\n *\n * Optimized for improving existing code.\n * Focuses on code quality, patterns, and safe refactoring techniques.\n */\nexport const refactoringProfile: LoadoutCriteria = {\n tags: ['refactoring', 'patterns', 'clean-code', 'quality'],\n taskDescription: 'refactor code, improve structure, apply design patterns',\n maxSkills: 6,\n priorityOrder: 'relevance',\n};\n\n/**\n * Documentation Profile\n *\n * Optimized for writing and maintaining documentation.\n * Focuses on technical writing, API docs, and code comments.\n */\nexport const documentationProfile: LoadoutCriteria = {\n tags: ['documentation', 'api-docs', 'comments', 'readme'],\n taskDescription: 'write documentation, API docs, technical guides',\n maxSkills: 4,\n priorityOrder: 'relevance',\n};\n\n/**\n * DevOps Profile\n *\n * Optimized for infrastructure and deployment work.\n * Focuses on CI/CD, Docker, Kubernetes, and cloud patterns.\n */\nexport const devopsProfile: LoadoutCriteria = {\n tags: ['devops', 'ci', 'docker', 'kubernetes', 'infrastructure', 'deployment'],\n taskDescription: 'CI/CD pipelines, containerization, infrastructure as code',\n maxSkills: 6,\n priorityOrder: 'relevance',\n};\n\n/**\n * All built-in profiles keyed by name\n */\nexport const builtInProfiles: Record<string, LoadoutCriteria> = {\n 'code-review': codeReviewProfile,\n 'implementation': implementationProfile,\n 'debugging': debuggingProfile,\n 'security': securityProfile,\n 'testing': testingProfile,\n 'refactoring': refactoringProfile,\n 'documentation': documentationProfile,\n 'devops': devopsProfile,\n};\n\n/**\n * Get a built-in profile by name\n */\nexport function getBuiltInProfile(name: string): LoadoutCriteria | undefined {\n return builtInProfiles[name];\n}\n\n/**\n * List all built-in profile names\n */\nexport function listBuiltInProfiles(): string[] {\n return Object.keys(builtInProfiles);\n}\n","/**\n * SkillGraphServer - Main orchestrator for skill loadouts\n *\n * Provides dual control: external orchestrators can set/manage loadouts,\n * while agents can request modifications (subject to approval settings).\n *\n * @packageDocumentation\n */\n\nimport type { Skill, StorageAdapter } from '../types.js';\nimport type {\n LoadoutCriteria,\n LoadoutState,\n LoadoutSource,\n LoadoutView,\n SkillSummary,\n GraphServerConfig,\n ServingEvent,\n ServingEventHandler,\n EvictionStrategy,\n CatalogRendererConfig,\n} from './types.js';\nimport { CatalogRenderer } from './catalog-renderer.js';\nimport { LoadoutCompiler } from './loadout-compiler.js';\nimport { ProjectDetector } from './project-detector.js';\nimport { ViewRenderer, type ViewRendererConfig } from './view-renderer.js';\nimport { builtInProfiles } from './profiles/index.js';\n\n/**\n * Default configuration for SkillGraphServer\n */\nconst DEFAULT_CONFIG: Required<Omit<GraphServerConfig, 'initialLoadout' | 'profiles' | 'defaultProfile' | 'catalogConfig'>> & {\n profiles: Record<string, LoadoutCriteria>;\n} = {\n agentCanModify: true,\n agentCanSetLoadout: false,\n agentCanSwitchProfile: true,\n requireApproval: false,\n autoExpandOnUse: true,\n autoExpandRelated: true,\n maxExpanded: 5,\n evictionStrategy: 'lru',\n persistState: false,\n outputFormat: 'xml',\n includeTokenEstimates: false,\n enableCatalog: true,\n profiles: {},\n};\n\n/**\n * Main orchestrator for managing skill loadouts\n *\n * Supports:\n * - External orchestrator API for setting loadouts\n * - Agent API for requesting modifications (with optional approval)\n * - Expansion state management with eviction strategies\n * - Event emission for state changes\n */\nexport class SkillGraphServer {\n private config: Required<Omit<GraphServerConfig, 'initialLoadout' | 'defaultProfile' | 'catalogConfig'>> & {\n profiles: Record<string, LoadoutCriteria>;\n defaultProfile?: string;\n catalogConfig?: Partial<CatalogRendererConfig>;\n };\n private compiler: LoadoutCompiler;\n private projectDetector: ProjectDetector;\n private viewRenderer: ViewRenderer;\n private catalogRenderer: CatalogRenderer | null = null;\n private state: LoadoutState;\n private handlers: Set<ServingEventHandler> = new Set();\n private lruOrder: string[] = []; // Track LRU for eviction\n\n constructor(\n private storage: StorageAdapter,\n config?: GraphServerConfig,\n ) {\n // Merge built-in profiles with user profiles (user profiles override built-ins)\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n profiles: { ...builtInProfiles, ...DEFAULT_CONFIG.profiles, ...config?.profiles },\n };\n\n this.compiler = new LoadoutCompiler(storage);\n this.projectDetector = new ProjectDetector();\n this.viewRenderer = new ViewRenderer({\n includeTokenEstimates: this.config.includeTokenEstimates,\n });\n\n // Initialize catalog renderer if enabled\n if (this.config.enableCatalog !== false) {\n this.catalogRenderer = new CatalogRenderer(storage, config?.catalogConfig);\n }\n\n // Initialize empty state\n this.state = {\n available: new Map(),\n expanded: new Set(),\n pending: new Set(),\n source: { type: 'manual' },\n updatedAt: new Date(),\n };\n }\n\n /**\n * Initialize the server, applying initial loadout if configured\n */\n async initialize(): Promise<void> {\n if (this.config.defaultProfile && this.config.profiles[this.config.defaultProfile]) {\n await this.setLoadoutFromProfile(this.config.defaultProfile);\n }\n }\n\n /**\n * Restore loadout state from persisted data\n */\n restoreState(state: LoadoutState): void {\n this.state = state;\n }\n\n // ===========================================================================\n // ORCHESTRATOR API - External control of loadout state\n // ===========================================================================\n\n /**\n * Set loadout from criteria (replaces current)\n */\n async setLoadout(criteria: LoadoutCriteria): Promise<LoadoutState> {\n const skills = await this.compiler.compile(criteria);\n return this.applyLoadout(skills, { type: 'criteria', criteria });\n }\n\n /**\n * Set loadout based on task description (semantic matching)\n */\n async setLoadoutForTask(taskDescription: string): Promise<LoadoutState> {\n const skills = await this.compiler.compileForTask(taskDescription);\n return this.applyLoadout(skills, { type: 'task', taskDescription });\n }\n\n /**\n * Set loadout based on detected project context\n */\n async setLoadoutForProject(projectPath: string): Promise<LoadoutState> {\n const context = await this.projectDetector.detectProjectContext(projectPath);\n const criteria = this.projectDetector.contextToCriteria(context);\n const skills = await this.compiler.compile(criteria);\n return this.applyLoadout(skills, { type: 'project', projectPath });\n }\n\n /**\n * Set loadout from a named profile\n */\n async setLoadoutFromProfile(profileName: string): Promise<LoadoutState> {\n const profile = this.config.profiles[profileName];\n if (!profile) {\n throw new Error(`Profile not found: ${profileName}`);\n }\n const skills = await this.compiler.compile(profile);\n return this.applyLoadout(skills, { type: 'profile', profileName });\n }\n\n /**\n * Add skills to current loadout (merge mode)\n */\n async addSkills(skillIds: string[]): Promise<void> {\n const skills = await Promise.all(\n skillIds.map((id) => this.storage.getSkill(id))\n );\n\n const validSkills = skills.filter((s): s is Skill => s !== null);\n\n for (const skill of validSkills) {\n this.state.available.set(skill.id, skill);\n }\n\n this.state.updatedAt = new Date();\n this.emit({ type: 'loadout:changed', state: this.state });\n }\n\n /**\n * Remove skills from current loadout\n */\n removeSkills(skillIds: string[]): void {\n for (const id of skillIds) {\n this.state.available.delete(id);\n this.state.expanded.delete(id);\n this.state.pending.delete(id);\n this.removeLru(id);\n }\n\n this.state.updatedAt = new Date();\n this.emit({ type: 'loadout:changed', state: this.state });\n }\n\n /**\n * Approve pending skill requests (adds to available)\n */\n async approvePending(skillIds: string[]): Promise<void> {\n const toApprove = skillIds.filter((id) => this.state.pending.has(id));\n if (toApprove.length === 0) return;\n\n const skills = await Promise.all(\n toApprove.map((id) => this.storage.getSkill(id))\n );\n\n for (const skill of skills) {\n if (skill) {\n this.state.available.set(skill.id, skill);\n this.state.pending.delete(skill.id);\n }\n }\n\n this.state.updatedAt = new Date();\n this.emit({ type: 'pending:approved', skillIds: toApprove });\n this.emit({ type: 'loadout:changed', state: this.state });\n }\n\n /**\n * Deny pending skill requests\n */\n denyPending(skillIds: string[]): void {\n const denied = skillIds.filter((id) => this.state.pending.has(id));\n if (denied.length === 0) return;\n\n for (const id of denied) {\n this.state.pending.delete(id);\n }\n\n this.state.updatedAt = new Date();\n this.emit({ type: 'pending:denied', skillIds: denied });\n }\n\n /**\n * Get current loadout state\n */\n getState(): LoadoutState {\n return this.state;\n }\n\n /**\n * Get available profile names\n */\n getProfiles(): string[] {\n return Object.keys(this.config.profiles);\n }\n\n /**\n * Add a profile at runtime\n */\n addProfile(name: string, criteria: LoadoutCriteria): void {\n this.config.profiles[name] = criteria;\n }\n\n // ===========================================================================\n // EXPANSION MANAGEMENT\n // ===========================================================================\n\n /**\n * Expand a skill (show full content)\n */\n expandSkill(skillId: string): boolean {\n // Must be in available\n if (!this.state.available.has(skillId)) {\n return false;\n }\n\n // Already expanded\n if (this.state.expanded.has(skillId)) {\n this.touchLru(skillId);\n return true;\n }\n\n // Check if we need to evict\n if (this.state.expanded.size >= this.config.maxExpanded) {\n this.evictSkill();\n }\n\n this.state.expanded.add(skillId);\n this.touchLru(skillId);\n this.state.updatedAt = new Date();\n this.emit({ type: 'skill:expanded', skillId });\n\n // Auto-expand related skills if configured\n if (this.config.autoExpandRelated) {\n this.expandRelated(skillId);\n }\n\n return true;\n }\n\n /**\n * Collapse a skill (hide full content)\n */\n collapseSkill(skillId: string): boolean {\n if (!this.state.expanded.has(skillId)) {\n return false;\n }\n\n this.state.expanded.delete(skillId);\n this.removeLru(skillId);\n this.state.updatedAt = new Date();\n this.emit({ type: 'skill:collapsed', skillId });\n return true;\n }\n\n /**\n * Record skill usage (for LRU tracking and auto-expansion)\n */\n recordUsage(skillId: string): void {\n if (!this.state.available.has(skillId)) return;\n\n this.touchLru(skillId);\n\n if (this.config.autoExpandOnUse && !this.state.expanded.has(skillId)) {\n this.expandSkill(skillId);\n }\n }\n\n // ===========================================================================\n // AGENT API - Methods for agent-side modifications\n // ===========================================================================\n\n /**\n * Agent requests to add skills\n * If requireApproval is true, adds to pending; otherwise directly adds\n */\n async agentRequestSkills(skillIds: string[]): Promise<{ added: string[]; pending: string[] }> {\n if (!this.config.agentCanModify) {\n return { added: [], pending: [] };\n }\n\n if (this.config.requireApproval) {\n // Add to pending for orchestrator approval\n const newPending: string[] = [];\n for (const id of skillIds) {\n if (!this.state.available.has(id) && !this.state.pending.has(id)) {\n this.state.pending.add(id);\n newPending.push(id);\n }\n }\n\n if (newPending.length > 0) {\n this.state.updatedAt = new Date();\n this.emit({ type: 'pending:added', skillIds: newPending });\n }\n\n return { added: [], pending: newPending };\n } else {\n // Direct add\n await this.addSkills(skillIds);\n return { added: skillIds, pending: [] };\n }\n }\n\n /**\n * Agent requests to remove skills\n */\n agentRemoveSkills(skillIds: string[]): { removed: string[] } {\n if (!this.config.agentCanModify) {\n return { removed: [] };\n }\n\n const toRemove = skillIds.filter((id) => this.state.available.has(id));\n this.removeSkills(toRemove);\n return { removed: toRemove };\n }\n\n /**\n * Agent requests to switch to a profile\n */\n async agentSwitchProfile(profileName: string): Promise<LoadoutState | null> {\n if (!this.config.agentCanSwitchProfile) {\n return null;\n }\n\n return this.setLoadoutFromProfile(profileName);\n }\n\n /**\n * Agent requests to set loadout (requires agentCanSetLoadout)\n */\n async agentSetLoadout(criteria: LoadoutCriteria): Promise<LoadoutState | null> {\n if (!this.config.agentCanSetLoadout) {\n return null;\n }\n\n return this.setLoadout(criteria);\n }\n\n /**\n * Agent searches for skills (searches all skills, not just loadout)\n * Returns skill summaries for display\n */\n async agentSearchSkills(query: string, limit: number = 5): Promise<SkillSummary[]> {\n // Get all active skills from storage\n const allSkills = await this.storage.listSkills({ status: ['active'] });\n\n // Simple text search (semantic matching would be used if available)\n const queryLower = query.toLowerCase();\n const matches = allSkills\n .filter(\n (skill) =>\n skill.name.toLowerCase().includes(queryLower) ||\n skill.description.toLowerCase().includes(queryLower) ||\n skill.instructions.toLowerCase().includes(queryLower) ||\n skill.tags.some((tag) => tag.toLowerCase().includes(queryLower))\n )\n .slice(0, limit);\n\n // Convert to summaries\n return matches.map((skill) => ({\n id: skill.id,\n name: skill.name,\n description: this.getSummary(skill),\n expanded: this.state.expanded.has(skill.id),\n tags: skill.tags,\n }));\n }\n\n /**\n * Agent expands a skill (returns the full skill if in loadout)\n */\n agentExpandSkill(skillId: string): Skill | null {\n const skill = this.state.available.get(skillId);\n if (!skill) {\n return null;\n }\n\n this.expandSkill(skillId);\n return skill;\n }\n\n /**\n * Agent collapses a skill\n */\n agentCollapseSkill(skillId: string): boolean {\n return this.collapseSkill(skillId);\n }\n\n /**\n * Agent lists current loadout (returns LoadoutView for display)\n */\n agentListLoadout(): LoadoutView {\n const summaries = this.viewRenderer.toSummaries(this.state);\n\n return {\n available: summaries,\n pending: Array.from(this.state.pending),\n profiles: this.getProfiles(),\n };\n }\n\n /**\n * Agent browses the skill catalog at a given path.\n * Returns rendered category view (subcategories or skill summaries at leaf).\n * Pass no path for the top-level overview.\n */\n async agentBrowseCatalog(path?: string[]): Promise<string> {\n if (!this.catalogRenderer) {\n return '<error>Catalog browsing is not enabled</error>';\n }\n\n if (!path || path.length === 0) {\n const result = await this.catalogRenderer.renderOverview();\n if (result) {\n this.emit({ type: 'catalog:browsed', path: [] });\n }\n return result;\n }\n\n const result = await this.catalogRenderer.renderCategory(path);\n this.emit({ type: 'catalog:browsed', path });\n return result;\n }\n\n /**\n * Agent adds a skill discovered via browsing directly to loadout and expands it.\n * Bridges browse → loadout: found it in catalog, now load it.\n */\n async agentAddFromCatalog(skillId: string): Promise<{ added: boolean; pending: boolean; expanded: boolean }> {\n if (!this.config.agentCanModify) {\n return { added: false, pending: false, expanded: false };\n }\n\n // Already in loadout — just expand it\n if (this.state.available.has(skillId)) {\n const expanded = this.expandSkill(skillId);\n return { added: false, pending: false, expanded };\n }\n\n // Request the skill via existing approval flow\n const result = await this.agentRequestSkills([skillId]);\n\n if (result.added.length > 0) {\n const expanded = this.expandSkill(skillId);\n this.emit({ type: 'catalog:added', skillId });\n return { added: true, pending: false, expanded };\n }\n\n if (result.pending.length > 0) {\n return { added: false, pending: true, expanded: false };\n }\n\n return { added: false, pending: false, expanded: false };\n }\n\n // ===========================================================================\n // RENDERING\n // ===========================================================================\n\n /**\n * Render current state as system prompt content.\n * Includes catalog overview when catalog is enabled.\n */\n async renderSystemPrompt(): Promise<string> {\n let prompt: string;\n if (this.config.outputFormat === 'markdown') {\n prompt = this.viewRenderer.renderMarkdown(this.state);\n } else {\n prompt = this.viewRenderer.renderXml(this.state);\n }\n\n if (this.catalogRenderer) {\n const overview = await this.catalogRenderer.renderOverview();\n if (overview) {\n prompt += '\\n' + overview;\n }\n }\n\n return prompt;\n }\n\n /**\n * Estimate total tokens for current loadout\n */\n estimateTokens(): number {\n return this.viewRenderer.estimateTokens(this.state);\n }\n\n // ===========================================================================\n // EVENTS\n // ===========================================================================\n\n /**\n * Subscribe to serving events\n */\n on(handler: ServingEventHandler): () => void {\n this.handlers.add(handler);\n return () => this.handlers.delete(handler);\n }\n\n /**\n * Emit an event to all handlers\n */\n private emit(event: ServingEvent): void {\n for (const handler of this.handlers) {\n handler(event);\n }\n }\n\n // ===========================================================================\n // PRIVATE HELPERS\n // ===========================================================================\n\n /**\n * Apply a new set of skills as the loadout\n */\n private applyLoadout(skills: Skill[], source: LoadoutSource): LoadoutState {\n // Clear current state\n this.state.available.clear();\n this.state.expanded.clear();\n this.state.pending.clear();\n this.lruOrder = [];\n\n // Add new skills\n for (const skill of skills) {\n this.state.available.set(skill.id, skill);\n }\n\n this.state.source = source;\n this.state.updatedAt = new Date();\n\n this.emit({ type: 'loadout:changed', state: this.state });\n return this.state;\n }\n\n /**\n * Evict a skill from expanded based on strategy\n */\n private evictSkill(): void {\n if (this.state.expanded.size === 0) return;\n\n let toEvict: string | undefined;\n\n switch (this.config.evictionStrategy) {\n case 'lru':\n // Remove least recently used\n toEvict = this.lruOrder.shift();\n break;\n\n case 'priority':\n // Remove lowest priority (based on serving metadata)\n let lowestPriority = Infinity;\n for (const id of this.state.expanded) {\n const skill = this.state.available.get(id);\n // Lower number = higher priority, so we want to evict highest number\n const priority = skill?.serving?.expansionGroup ? 1 : 0;\n if (priority < lowestPriority) {\n lowestPriority = priority;\n toEvict = id;\n }\n }\n break;\n\n case 'manual':\n // Don't auto-evict, just don't expand more\n return;\n }\n\n if (toEvict && this.state.expanded.has(toEvict)) {\n this.collapseSkill(toEvict);\n }\n }\n\n /**\n * Touch skill in LRU order (move to end)\n */\n private touchLru(skillId: string): void {\n this.removeLru(skillId);\n this.lruOrder.push(skillId);\n }\n\n /**\n * Remove skill from LRU tracking\n */\n private removeLru(skillId: string): void {\n const idx = this.lruOrder.indexOf(skillId);\n if (idx !== -1) {\n this.lruOrder.splice(idx, 1);\n }\n }\n\n /**\n * Get summary for a skill (short description)\n */\n private getSummary(skill: Skill): string {\n // Use explicit summary if available\n if (skill.serving?.summary) {\n return skill.serving.summary;\n }\n\n // Fall back to first sentence of description\n const firstSentence = skill.description.split(/[.!?]/)[0];\n if (firstSentence.length <= 150) {\n return firstSentence;\n }\n\n // Truncate if still too long\n return skill.description.substring(0, 147) + '...';\n }\n\n /**\n * Expand related skills (follows relationships)\n */\n private expandRelated(skillId: string): void {\n const skill = this.state.available.get(skillId);\n if (!skill?.relationships) return;\n\n for (const rel of skill.relationships) {\n if (rel.type === 'depends_on' || rel.type === 'related') {\n // Only expand if in available and not already expanded\n if (\n this.state.available.has(rel.targetSkillId) &&\n !this.state.expanded.has(rel.targetSkillId) &&\n this.state.expanded.size < this.config.maxExpanded\n ) {\n // Don't recurse, just one level of related\n this.state.expanded.add(rel.targetSkillId);\n this.touchLru(rel.targetSkillId);\n this.emit({ type: 'skill:expanded', skillId: rel.targetSkillId });\n }\n }\n }\n }\n}\n","/**\n * Interfaces for clean coupling between SkillBank and Serving Layer\n *\n * These interfaces provide:\n * - SkillStorageView: Read-only view for serving layer to access skills\n * - ServingEventBridge: Bidirectional event flow between SkillBank and Serving\n */\n\nimport type { Skill, SkillFilter } from '../types.js';\nimport type { ServingEvent, LoadoutState } from './types.js';\n\n/**\n * Read-only view of skill storage for the serving layer\n * This interface provides only the methods needed for serving,\n * without exposing mutation operations.\n */\nexport interface SkillStorageView {\n /**\n * Get a skill by ID (optionally a specific version)\n */\n getSkill(id: string, version?: string): Promise<Skill | null>;\n\n /**\n * List skills matching a filter\n */\n listSkills(filter?: SkillFilter): Promise<Skill[]>;\n\n /**\n * Search skills by query\n */\n searchSkills(query: string): Promise<Skill[]>;\n}\n\n/**\n * Events that flow from SkillBank to Serving Layer\n */\nexport type SkillBankToServingEvent =\n | { type: 'skill:created'; skill: Skill }\n | { type: 'skill:updated'; skill: Skill; previousVersion: string }\n | { type: 'skill:deleted'; skillId: string }\n | { type: 'skill:deprecated'; skillId: string };\n\n/**\n * Events that flow from Serving Layer to SkillBank\n */\nexport type ServingToSkillBankEvent =\n | { type: 'skill:used'; skillId: string; success: boolean }\n | { type: 'skill:feedback'; skillId: string; score: number; comment?: string }\n | { type: 'skill:requested'; skillId: string }\n | { type: 'loadout:changed'; state: LoadoutState };\n\n/**\n * Bidirectional event bridge between SkillBank and Serving Layer\n *\n * The serving layer registers to receive SkillBank events,\n * and the bridge forwards serving events back to SkillBank.\n */\nexport interface ServingEventBridge {\n /**\n * Register handler for SkillBank → Serving events\n */\n onSkillBankEvent(handler: (event: SkillBankToServingEvent) => void): () => void;\n\n /**\n * Emit event from Serving → SkillBank\n */\n emitToSkillBank(event: ServingToSkillBankEvent): void;\n\n /**\n * Cleanup and disconnect\n */\n disconnect(): void;\n}\n\n/**\n * Factory function type for creating serving layer components\n */\nexport interface ServingLayerFactory {\n /**\n * Create a SkillGraphServer wired to the SkillBank\n */\n createServer(): Promise<import('./graph-server.js').SkillGraphServer>;\n\n /**\n * Get the event bridge for this serving layer\n */\n getEventBridge(): ServingEventBridge;\n\n /**\n * Get the storage view\n */\n getStorageView(): SkillStorageView;\n}\n\n/**\n * Create a storage view from a full storage adapter\n * This wraps the storage to only expose read operations\n */\nexport function createStorageView(storage: {\n getSkill(id: string, version?: string): Promise<Skill | null>;\n listSkills(filter?: SkillFilter): Promise<Skill[]>;\n searchSkills(query: string): Promise<Skill[]>;\n}): SkillStorageView {\n return {\n getSkill: storage.getSkill.bind(storage),\n listSkills: storage.listSkills.bind(storage),\n searchSkills: storage.searchSkills.bind(storage),\n };\n}\n\n/**\n * Create an event bridge\n */\nexport function createServingEventBridge(): {\n bridge: ServingEventBridge;\n emitFromSkillBank: (event: SkillBankToServingEvent) => void;\n onServingEvent: (handler: (event: ServingToSkillBankEvent) => void) => () => void;\n} {\n const skillBankHandlers = new Set<(event: SkillBankToServingEvent) => void>();\n const servingHandlers = new Set<(event: ServingToSkillBankEvent) => void>();\n\n const bridge: ServingEventBridge = {\n onSkillBankEvent(handler) {\n skillBankHandlers.add(handler);\n return () => skillBankHandlers.delete(handler);\n },\n\n emitToSkillBank(event) {\n for (const handler of servingHandlers) {\n handler(event);\n }\n },\n\n disconnect() {\n skillBankHandlers.clear();\n servingHandlers.clear();\n },\n };\n\n return {\n bridge,\n emitFromSkillBank: (event) => {\n for (const handler of skillBankHandlers) {\n handler(event);\n }\n },\n onServingEvent: (handler) => {\n servingHandlers.add(handler);\n return () => servingHandlers.delete(handler);\n },\n };\n}\n","/**\n * Remote Store\n *\n * Persists remote configurations to disk in .skillbank/remotes.json.\n * Provides CRUD operations for managing federated remote repositories.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type {\n FederatedRemoteConfig,\n PersistedRemotes,\n RemoteState,\n} from './types.js';\n\n/**\n * Default file name for persisted remotes\n */\nconst REMOTES_FILE = 'remotes.json';\n\n/**\n * Options for creating a RemoteStore\n */\nexport interface RemoteStoreOptions {\n /** Base path for the skill bank (where .skillbank/ will be created) */\n basePath: string;\n}\n\n/**\n * RemoteStore manages persisted remote configurations.\n *\n * Storage location: {basePath}/.skillbank/remotes.json\n */\nexport class RemoteStore {\n private basePath: string;\n private configDir: string;\n private configPath: string;\n private remotes: Map<string, FederatedRemoteConfig> = new Map();\n private initialized = false;\n\n constructor(options: RemoteStoreOptions) {\n this.basePath = options.basePath;\n this.configDir = path.join(this.basePath, '.skillbank');\n this.configPath = path.join(this.configDir, REMOTES_FILE);\n }\n\n /**\n * Initialize the store, loading existing configuration\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Ensure .skillbank directory exists\n await fs.promises.mkdir(this.configDir, { recursive: true });\n\n // Load existing configuration if present\n if (fs.existsSync(this.configPath)) {\n await this.load();\n }\n\n this.initialized = true;\n }\n\n /**\n * Ensure store is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized) {\n throw new Error('RemoteStore not initialized. Call initialize() first.');\n }\n }\n\n /**\n * Load remotes from disk\n */\n private async load(): Promise<void> {\n try {\n const content = await fs.promises.readFile(this.configPath, 'utf-8');\n const data: PersistedRemotes = JSON.parse(content);\n\n // Validate version\n if (data.version !== 1) {\n throw new Error(`Unsupported remotes file version: ${data.version}`);\n }\n\n // Load remotes\n this.remotes.clear();\n for (const [name, config] of Object.entries(data.remotes)) {\n this.remotes.set(name, config);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n // File doesn't exist, start with empty remotes\n this.remotes.clear();\n }\n }\n\n /**\n * Save remotes to disk\n */\n private async save(): Promise<void> {\n const data: PersistedRemotes = {\n version: 1,\n remotes: Object.fromEntries(this.remotes),\n updatedAt: new Date().toISOString(),\n };\n\n const content = JSON.stringify(data, null, 2);\n await fs.promises.writeFile(this.configPath, content, 'utf-8');\n }\n\n /**\n * Add a remote\n */\n async addRemote(name: string, config: FederatedRemoteConfig): Promise<void> {\n this.ensureInitialized();\n\n // Validate name\n if (!this.isValidRemoteName(name)) {\n throw new Error(\n `Invalid remote name: ${name}. Use lowercase letters, numbers, and hyphens.`\n );\n }\n\n // Check for duplicates\n if (this.remotes.has(name)) {\n throw new Error(`Remote already exists: ${name}`);\n }\n\n // Validate config\n this.validateConfig(config);\n\n // Set defaults\n const normalizedConfig: FederatedRemoteConfig = {\n ...config,\n branch: config.branch || 'main',\n skillsPath: config.skillsPath || 'skills/',\n localCache: config.localCache || path.join(this.basePath, '.remotes', name),\n };\n\n this.remotes.set(name, normalizedConfig);\n await this.save();\n }\n\n /**\n * Remove a remote\n */\n async removeRemote(name: string): Promise<boolean> {\n this.ensureInitialized();\n\n if (!this.remotes.has(name)) {\n return false;\n }\n\n this.remotes.delete(name);\n await this.save();\n return true;\n }\n\n /**\n * Get a remote configuration\n */\n getRemote(name: string): FederatedRemoteConfig | undefined {\n this.ensureInitialized();\n return this.remotes.get(name);\n }\n\n /**\n * Check if a remote exists\n */\n hasRemote(name: string): boolean {\n this.ensureInitialized();\n return this.remotes.has(name);\n }\n\n /**\n * List all remote names\n */\n listRemotes(): string[] {\n this.ensureInitialized();\n return Array.from(this.remotes.keys());\n }\n\n /**\n * List all remotes with their configurations\n */\n listRemotesWithConfig(): Array<{ name: string; config: FederatedRemoteConfig }> {\n this.ensureInitialized();\n return Array.from(this.remotes.entries()).map(([name, config]) => ({\n name,\n config,\n }));\n }\n\n /**\n * Update a remote configuration\n */\n async updateRemote(\n name: string,\n updates: Partial<FederatedRemoteConfig>\n ): Promise<void> {\n this.ensureInitialized();\n\n const existing = this.remotes.get(name);\n if (!existing) {\n throw new Error(`Remote not found: ${name}`);\n }\n\n const updated: FederatedRemoteConfig = {\n ...existing,\n ...updates,\n };\n\n this.validateConfig(updated);\n this.remotes.set(name, updated);\n await this.save();\n }\n\n /**\n * Get the local cache path for a remote\n */\n getCachePath(name: string): string {\n this.ensureInitialized();\n\n const config = this.remotes.get(name);\n if (!config) {\n throw new Error(`Remote not found: ${name}`);\n }\n\n return config.localCache || path.join(this.basePath, '.remotes', name);\n }\n\n /**\n * Validate a remote name\n */\n private isValidRemoteName(name: string): boolean {\n return /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/.test(name);\n }\n\n /**\n * Validate remote configuration\n */\n private validateConfig(config: FederatedRemoteConfig): void {\n if (!config.url) {\n throw new Error('Remote URL is required');\n }\n\n if (!['read-only', 'read-write'].includes(config.access)) {\n throw new Error(`Invalid access level: ${config.access}`);\n }\n\n // Validate URL format (basic check)\n if (!this.isValidUrl(config.url)) {\n throw new Error(`Invalid remote URL: ${config.url}`);\n }\n }\n\n /**\n * Basic URL validation\n */\n private isValidUrl(url: string): boolean {\n // Git SSH URL\n if (url.match(/^git@[^:]+:.+\\.git$/)) {\n return true;\n }\n\n // HTTPS URL\n if (url.match(/^https?:\\/\\/.+/)) {\n return true;\n }\n\n // Local path\n if (url.startsWith('/') || url.startsWith('./') || url.startsWith('../')) {\n return true;\n }\n\n return false;\n }\n}\n\n/**\n * Create a RemoteStore instance\n */\nexport function createRemoteStore(options: RemoteStoreOptions): RemoteStore {\n return new RemoteStore(options);\n}\n","/**\n * Remote Manager\n *\n * Handles git operations for remote repositories:\n * - Cloning remote repos to local cache\n * - Fetching updates\n * - Reading skills from cached repos\n * - Writing skills to writable remotes\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { execSync, exec } from 'child_process';\nimport { promisify } from 'util';\nimport type { Skill, SkillFilter } from '../types.js';\nimport type {\n FederatedRemoteConfig,\n RemoteState,\n} from './types.js';\nimport { RemoteStore } from './remote-store.js';\nimport {\n SkilltreeConfig,\n loadSkilltreeConfig,\n hasSkilltreeDir,\n getSkilltreeDir,\n getSkillsDir,\n discoverSkills as discoverSkillsInRepo,\n deriveSkillId,\n type DiscoveredSkill,\n} from './skilltree-config.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Options for creating a RemoteManager\n */\nexport interface RemoteManagerOptions {\n /** Base path for the skill bank */\n basePath: string;\n\n /** Remote store instance */\n remoteStore: RemoteStore;\n\n /** Timeout for git operations in ms (default: 60000) */\n gitTimeout?: number;\n}\n\n/**\n * RemoteManager handles git operations for federated remotes.\n *\n * Directory structure:\n * {basePath}/\n * .remotes/\n * {remote-name}/ <- git clone of remote repo\n * skills/ <- skills directory in repo\n * skill-id/\n * SKILL.md\n */\nexport class RemoteManager {\n private basePath: string;\n private remotesDir: string;\n private remoteStore: RemoteStore;\n private gitTimeout: number;\n private initialized = false;\n\n /** Cache of remote states */\n private stateCache: Map<string, RemoteState> = new Map();\n\n /** Cache of skilltree configs per remote */\n private configCache: Map<string, SkilltreeConfig> = new Map();\n\n /** Cache of discovered skill locations per remote */\n private discoveryCache: Map<string, DiscoveredSkill[]> = new Map();\n\n constructor(options: RemoteManagerOptions) {\n this.basePath = options.basePath;\n this.remotesDir = path.join(this.basePath, '.remotes');\n this.remoteStore = options.remoteStore;\n this.gitTimeout = options.gitTimeout || 60000;\n }\n\n /**\n * Initialize the manager\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Ensure .remotes directory exists\n await fs.promises.mkdir(this.remotesDir, { recursive: true });\n\n this.initialized = true;\n }\n\n /**\n * Ensure manager is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized) {\n throw new Error('RemoteManager not initialized. Call initialize() first.');\n }\n }\n\n // ===========================================================================\n // Remote Operations\n // ===========================================================================\n\n /**\n * Refresh a remote (clone if not exists, fetch if exists)\n */\n async refreshRemote(name: string): Promise<RemoteState> {\n this.ensureInitialized();\n\n const config = this.remoteStore.getRemote(name);\n if (!config) {\n throw new Error(`Remote not found: ${name}`);\n }\n\n const cachePath = this.getCachePath(name);\n\n try {\n if (await this.isGitRepo(cachePath)) {\n // Fetch latest\n await this.gitFetch(cachePath, config);\n } else {\n // Clone fresh\n await this.gitClone(name, config);\n }\n\n // Invalidate caches after fetching new data\n this.invalidateCaches(name);\n\n // Count skills\n const skillCount = await this.countSkillsInCache(name);\n\n const state: RemoteState = {\n name,\n config,\n lastFetched: new Date(),\n status: 'connected',\n skillCount,\n };\n\n this.stateCache.set(name, state);\n return state;\n } catch (error) {\n const state: RemoteState = {\n name,\n config,\n status: 'error',\n error: error instanceof Error ? error.message : String(error),\n };\n\n this.stateCache.set(name, state);\n throw error;\n }\n }\n\n /**\n * Get the state of a remote\n */\n async getRemoteState(name: string): Promise<RemoteState> {\n this.ensureInitialized();\n\n const config = this.remoteStore.getRemote(name);\n if (!config) {\n throw new Error(`Remote not found: ${name}`);\n }\n\n // Return cached state if available\n const cached = this.stateCache.get(name);\n if (cached) {\n return cached;\n }\n\n const cachePath = this.getCachePath(name);\n\n // Check if we have a valid cache\n if (await this.isGitRepo(cachePath)) {\n const skillCount = await this.countSkillsInCache(name);\n const state: RemoteState = {\n name,\n config,\n status: 'connected',\n skillCount,\n };\n this.stateCache.set(name, state);\n return state;\n }\n\n return {\n name,\n config,\n status: 'unknown',\n };\n }\n\n /**\n * Delete the local cache for a remote\n */\n async deleteCache(name: string): Promise<void> {\n this.ensureInitialized();\n\n const cachePath = this.getCachePath(name);\n if (fs.existsSync(cachePath)) {\n await fs.promises.rm(cachePath, { recursive: true });\n }\n\n this.stateCache.delete(name);\n this.invalidateCaches(name);\n }\n\n // ===========================================================================\n // Skill Operations\n // ===========================================================================\n\n /**\n * List skills from a remote\n */\n async listSkills(name: string, filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n\n const remoteConfig = this.remoteStore.getRemote(name);\n if (!remoteConfig) {\n throw new Error(`Remote not found: ${name}`);\n }\n\n const cachePath = this.getCachePath(name);\n\n // Ensure cache exists\n if (!fs.existsSync(cachePath)) {\n await this.refreshRemote(name);\n }\n\n // Discover all skills in the repo\n const discovered = await this.discoverSkills(name);\n const skills: Skill[] = [];\n\n for (const location of discovered) {\n try {\n const content = await fs.promises.readFile(location.filePath, 'utf-8');\n const skill = this.parseSkillContent(content, location.id);\n skills.push(skill);\n } catch (error) {\n // Skip unreadable skills\n console.warn(`Failed to read skill at ${location.filePath}:`, error);\n }\n }\n\n return this.applyFilter(skills, filter);\n }\n\n /**\n * Get a single skill from a remote\n */\n async getSkill(remoteName: string, skillId: string): Promise<Skill | null> {\n this.ensureInitialized();\n\n const remoteConfig = this.remoteStore.getRemote(remoteName);\n if (!remoteConfig) {\n throw new Error(`Remote not found: ${remoteName}`);\n }\n\n const cachePath = this.getCachePath(remoteName);\n\n // Ensure cache exists\n if (!fs.existsSync(cachePath)) {\n await this.refreshRemote(remoteName);\n }\n\n // Find the skill in discovered locations\n const discovered = await this.discoverSkills(remoteName);\n const location = discovered.find(d => d.id === skillId);\n\n if (!location) {\n return null;\n }\n\n try {\n const content = await fs.promises.readFile(location.filePath, 'utf-8');\n return this.parseSkillContent(content, location.id);\n } catch {\n return null;\n }\n }\n\n /**\n * Write a skill to a writable remote\n */\n async writeSkill(remoteName: string, skill: Skill): Promise<string> {\n this.ensureInitialized();\n\n const remoteConfig = this.remoteStore.getRemote(remoteName);\n if (!remoteConfig) {\n throw new Error(`Remote not found: ${remoteName}`);\n }\n\n if (remoteConfig.access !== 'read-write') {\n throw new Error(`Remote ${remoteName} is read-only`);\n }\n\n // Determine where to write skills\n const skillsPath = await this.getWritePath(remoteName);\n const skillDir = path.join(skillsPath, skill.id);\n\n // Ensure skill directory exists\n await fs.promises.mkdir(skillDir, { recursive: true });\n\n // Write skill file\n const content = this.serializeSkill(skill);\n const skillPath = path.join(skillDir, 'SKILL.md');\n await fs.promises.writeFile(skillPath, content, 'utf-8');\n\n // Invalidate discovery cache since we added a new skill\n this.discoveryCache.delete(remoteName);\n\n return skillPath;\n }\n\n /**\n * Delete a skill from a writable remote\n */\n async deleteSkill(remoteName: string, skillId: string): Promise<boolean> {\n this.ensureInitialized();\n\n const remoteConfig = this.remoteStore.getRemote(remoteName);\n if (!remoteConfig) {\n throw new Error(`Remote not found: ${remoteName}`);\n }\n\n if (remoteConfig.access !== 'read-write') {\n throw new Error(`Remote ${remoteName} is read-only`);\n }\n\n // Find the skill location\n const discovered = await this.discoverSkills(remoteName);\n const location = discovered.find(d => d.id === skillId);\n\n if (!location) {\n return false;\n }\n\n await fs.promises.rm(location.directory, { recursive: true });\n\n // Invalidate discovery cache\n this.discoveryCache.delete(remoteName);\n\n return true;\n }\n\n /**\n * Commit and push changes to a remote\n */\n async commitAndPush(\n remoteName: string,\n message: string\n ): Promise<{ commitHash: string }> {\n this.ensureInitialized();\n\n const config = this.remoteStore.getRemote(remoteName);\n if (!config) {\n throw new Error(`Remote not found: ${remoteName}`);\n }\n\n if (config.access !== 'read-write') {\n throw new Error(`Remote ${remoteName} is read-only`);\n }\n\n const cachePath = this.getCachePath(remoteName);\n\n // Stage all changes\n await this.runGit(cachePath, ['add', '-A']);\n\n // Commit\n await this.runGit(cachePath, ['commit', '-m', message]);\n\n // Get commit hash\n const { stdout: hash } = await this.runGit(cachePath, ['rev-parse', 'HEAD']);\n\n // Push\n const branch = config.branch || 'main';\n await this.runGit(cachePath, ['push', 'origin', branch]);\n\n return { commitHash: hash.trim() };\n }\n\n // ===========================================================================\n // Private Helpers - Git Operations\n // ===========================================================================\n\n /**\n * Clone a remote repository\n */\n private async gitClone(name: string, config: FederatedRemoteConfig): Promise<void> {\n const cachePath = this.getCachePath(name);\n\n // Remove existing cache if corrupted\n if (fs.existsSync(cachePath)) {\n await fs.promises.rm(cachePath, { recursive: true });\n }\n\n const branch = config.branch || 'main';\n await this.runGit(this.remotesDir, [\n 'clone',\n '--branch', branch,\n '--single-branch',\n '--depth', '1',\n config.url,\n name,\n ]);\n }\n\n /**\n * Fetch latest from remote\n */\n private async gitFetch(cachePath: string, config: FederatedRemoteConfig): Promise<void> {\n const branch = config.branch || 'main';\n await this.runGit(cachePath, ['fetch', 'origin', branch]);\n await this.runGit(cachePath, ['reset', '--hard', `origin/${branch}`]);\n }\n\n /**\n * Check if a path is a git repository\n */\n private async isGitRepo(dir: string): Promise<boolean> {\n if (!fs.existsSync(dir)) {\n return false;\n }\n\n try {\n await this.runGit(dir, ['rev-parse', '--git-dir']);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Run a git command\n */\n private async runGit(\n cwd: string,\n args: string[]\n ): Promise<{ stdout: string; stderr: string }> {\n const command = `git ${args.map(a => `\"${a}\"`).join(' ')}`;\n\n try {\n const result = await execAsync(command, {\n cwd,\n timeout: this.gitTimeout,\n maxBuffer: 10 * 1024 * 1024, // 10MB\n });\n return result;\n } catch (error) {\n const err = error as Error & { stdout?: string; stderr?: string };\n throw new Error(\n `Git command failed: ${command}\\n${err.stderr || err.message}`\n );\n }\n }\n\n // ===========================================================================\n // Private Helpers - Skill Discovery\n // ===========================================================================\n\n /**\n * Get the cache path for a remote\n */\n private getCachePath(name: string): string {\n return path.join(this.remotesDir, name);\n }\n\n /**\n * Load and cache the .skilltree config for a remote\n */\n private async getSkilltreeConfig(remoteName: string): Promise<SkilltreeConfig> {\n const cached = this.configCache.get(remoteName);\n if (cached) {\n return cached;\n }\n\n const cachePath = this.getCachePath(remoteName);\n const config = await loadSkilltreeConfig(cachePath);\n this.configCache.set(remoteName, config);\n return config;\n }\n\n /**\n * Discover all skills in a remote repository's .skilltree directory\n */\n private async discoverSkills(remoteName: string): Promise<DiscoveredSkill[]> {\n // Check cache first\n const cached = this.discoveryCache.get(remoteName);\n if (cached) {\n return cached;\n }\n\n const cachePath = this.getCachePath(remoteName);\n\n // Check if repo has a .skilltree directory\n if (!(await hasSkilltreeDir(cachePath))) {\n // No .skilltree directory - return empty\n this.discoveryCache.set(remoteName, []);\n return [];\n }\n\n // Use the shared discovery function\n const discovered = await discoverSkillsInRepo(cachePath);\n\n this.discoveryCache.set(remoteName, discovered);\n return discovered;\n }\n\n /**\n * Get the path to write new skills to (.skilltree/skills/)\n */\n private async getWritePath(remoteName: string): Promise<string> {\n const cachePath = this.getCachePath(remoteName);\n const config = await this.getSkilltreeConfig(remoteName);\n\n // Get the skills directory from config (defaults to .skilltree/skills/)\n const skillsPath = getSkillsDir(cachePath, config);\n\n // Ensure it exists\n await fs.promises.mkdir(skillsPath, { recursive: true });\n\n return skillsPath;\n }\n\n /**\n * Count skills in a remote's cache\n */\n private async countSkillsInCache(name: string): Promise<number> {\n try {\n const discovered = await this.discoverSkills(name);\n return discovered.length;\n } catch {\n return 0;\n }\n }\n\n /**\n * Invalidate caches for a remote (call after fetch/clone)\n */\n private invalidateCaches(remoteName: string): void {\n this.configCache.delete(remoteName);\n this.discoveryCache.delete(remoteName);\n }\n\n /**\n * Parse skill content from SKILL.md format\n */\n private parseSkillContent(content: string, skillId: string): Skill {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n\n if (!frontmatterMatch) {\n throw new Error(`Invalid skill file format for ${skillId}`);\n }\n\n const [, frontmatter, body] = frontmatterMatch;\n\n // Parse YAML frontmatter (simple key: value parsing)\n const metadata = this.parseYamlFrontmatter(frontmatter);\n\n return {\n id: skillId,\n name: metadata.name || skillId,\n version: metadata.version || '1.0.0',\n description: metadata.description || '',\n instructions: body.trim(),\n author: metadata.author || 'unknown',\n tags: this.parseTags(metadata.tags),\n createdAt: metadata.created ? new Date(metadata.created) : new Date(),\n updatedAt: metadata.updated ? new Date(metadata.updated) : new Date(),\n status: (metadata.status as 'draft' | 'active' | 'deprecated' | 'experimental') || 'active',\n metrics: {\n usageCount: parseInt(metadata.usageCount) || 0,\n successRate: parseFloat(metadata.successRate) || 0,\n feedbackScores: [],\n },\n };\n }\n\n /**\n * Parse YAML frontmatter (simple implementation)\n */\n private parseYamlFrontmatter(frontmatter: string): Record<string, string> {\n const metadata: Record<string, string> = {};\n\n for (const line of frontmatter.split('\\n')) {\n const match = line.match(/^(\\w+):\\s*(.+)$/);\n if (match) {\n let [, key, value] = match;\n // Remove quotes\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n metadata[key] = value;\n }\n }\n\n return metadata;\n }\n\n /**\n * Parse tags from metadata\n */\n private parseTags(tags: string | undefined): string[] {\n if (!tags) return [];\n return tags.split(',').map(t => t.trim()).filter(Boolean);\n }\n\n /**\n * Serialize a skill to SKILL.md format\n */\n private serializeSkill(skill: Skill): string {\n const frontmatter = [\n '---',\n `name: \"${skill.name}\"`,\n `version: \"${skill.version}\"`,\n `status: ${skill.status}`,\n `author: \"${skill.author}\"`,\n `tags: ${skill.tags.join(', ')}`,\n `created: ${skill.createdAt.toISOString()}`,\n `updated: ${skill.updatedAt.toISOString()}`,\n '---',\n ].join('\\n');\n\n const body = [\n `# ${skill.name}`,\n '',\n skill.description,\n '',\n skill.instructions,\n ];\n\n return `${frontmatter}\\n\\n${body.join('\\n')}\\n`;\n }\n\n /**\n * Apply filter to skills list\n */\n private applyFilter(skills: Skill[], filter?: SkillFilter): Skill[] {\n if (!filter) return skills;\n\n return skills.filter(skill => {\n // Status filter\n if (filter.status && !filter.status.includes(skill.status)) {\n return false;\n }\n\n // Tags filter\n if (filter.tags && !filter.tags.some(tag => skill.tags.includes(tag))) {\n return false;\n }\n\n // Author filter\n if (filter.author && skill.author !== filter.author) {\n return false;\n }\n\n // Success rate filter\n if (\n filter.minSuccessRate !== undefined &&\n skill.metrics.successRate < filter.minSuccessRate\n ) {\n return false;\n }\n\n // Date filters\n if (filter.createdAfter && skill.createdAt < filter.createdAfter) {\n return false;\n }\n if (filter.createdBefore && skill.createdAt > filter.createdBefore) {\n return false;\n }\n\n return true;\n });\n }\n}\n\n/**\n * Create a RemoteManager instance\n */\nexport function createRemoteManager(options: RemoteManagerOptions): RemoteManager {\n return new RemoteManager(options);\n}\n","/**\n * .skilltree Directory Structure\n *\n * Defines the format for .skilltree directories that can exist\n * at the root of any repository to declare it as a skill repository.\n *\n * Structure:\n * .skilltree/\n * config.json <- optional configuration\n * skills/ <- default skills location (or custom paths in config)\n * skill-id/\n * SKILL.md\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * Resolve the skilltree directory name for a given repo root.\n * Priority: SKILL_TREE_PROJECT_DIR env var > .swarm/skilltree exists > .skilltree\n */\nexport function resolveSkilltreeDir(repoRoot: string): string {\n const envDir = process.env.SKILL_TREE_PROJECT_DIR;\n if (envDir) return path.join(repoRoot, envDir);\n const swarmDir = path.join(repoRoot, '.swarm', 'skilltree');\n if (fs.existsSync(swarmDir)) return swarmDir;\n return path.join(repoRoot, '.skilltree');\n}\n\n/**\n * .skilltree/config.json format\n */\nexport interface SkilltreeConfig {\n /** Config version (currently 1) */\n version: 1;\n\n /**\n * How to discover skills in this repo\n * - 'default': Look in .skilltree/skills/ only\n * - 'explicit': Use only the paths listed in `paths` (relative to .skilltree/)\n * - 'scan': Scan .skilltree/ directory for SKILL.md files\n */\n discovery?: 'default' | 'explicit' | 'scan';\n\n /**\n * Explicit paths to skill directories (relative to .skilltree/)\n * Default: ['skills']\n */\n paths?: string[];\n\n /**\n * Directories to exclude when scanning\n */\n exclude?: string[];\n\n /**\n * Namespace prefix for skills from this repo (optional)\n */\n namespace?: string;\n\n /**\n * Skill file patterns to recognize\n * Default: ['SKILL.md', 'skill.md']\n */\n skillFilePatterns?: string[];\n}\n\n/**\n * Default config when no config.json exists\n */\nexport const DEFAULT_CONFIG: SkilltreeConfig = {\n version: 1,\n discovery: 'default',\n paths: ['skills'],\n exclude: [\n 'node_modules',\n '.git',\n '.cache',\n 'dist',\n 'build',\n 'coverage',\n ],\n skillFilePatterns: ['SKILL.md', 'skill.md'],\n};\n\n/**\n * Check if a directory has a .skilltree directory\n */\nexport async function hasSkilltreeDir(repoRoot: string): Promise<boolean> {\n const skilltreeDir = resolveSkilltreeDir(repoRoot);\n try {\n const stat = await fs.promises.stat(skilltreeDir);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Get the .skilltree directory path\n */\nexport function getSkilltreeDir(repoRoot: string): string {\n return resolveSkilltreeDir(repoRoot);\n}\n\n/**\n * Get the skills directory path (where skills are stored)\n */\nexport function getSkillsDir(repoRoot: string, config?: SkilltreeConfig): string {\n const skilltreeDir = getSkilltreeDir(repoRoot);\n const paths = config?.paths || DEFAULT_CONFIG.paths!;\n return path.join(skilltreeDir, paths[0]);\n}\n\n/**\n * Parse a config.json file\n */\nexport function parseSkilltreeConfig(content: string): SkilltreeConfig {\n const parsed = JSON.parse(content);\n return validateConfig(parsed);\n}\n\n/**\n * Validate and normalize a config\n */\nfunction validateConfig(config: Partial<SkilltreeConfig>): SkilltreeConfig {\n if (config.version && config.version !== 1) {\n throw new Error(`Unsupported .skilltree config version: ${config.version}`);\n }\n\n return {\n version: 1,\n discovery: config.discovery || DEFAULT_CONFIG.discovery,\n paths: config.paths || DEFAULT_CONFIG.paths,\n exclude: [...(DEFAULT_CONFIG.exclude || []), ...(config.exclude || [])],\n skillFilePatterns: config.skillFilePatterns || DEFAULT_CONFIG.skillFilePatterns,\n namespace: config.namespace,\n };\n}\n\n/**\n * Load .skilltree/config.json from a repository root\n */\nexport async function loadSkilltreeConfig(repoRoot: string): Promise<SkilltreeConfig> {\n const configPath = path.join(getSkilltreeDir(repoRoot), 'config.json');\n\n try {\n const content = await fs.promises.readFile(configPath, 'utf-8');\n return parseSkilltreeConfig(content);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n // No config file, use defaults\n return { ...DEFAULT_CONFIG };\n }\n throw error;\n }\n}\n\n/**\n * Initialize a .skilltree directory structure\n */\nexport async function initSkilltreeDir(\n repoRoot: string,\n config?: Partial<SkilltreeConfig>\n): Promise<void> {\n const skilltreeDir = getSkilltreeDir(repoRoot);\n const fullConfig = validateConfig(config || {});\n\n // Create .skilltree directory\n await fs.promises.mkdir(skilltreeDir, { recursive: true });\n\n // Create skills directory\n const skillsDir = getSkillsDir(repoRoot, fullConfig);\n await fs.promises.mkdir(skillsDir, { recursive: true });\n\n // Create .cache directory for SQLite index\n const cacheDir = path.join(skilltreeDir, '.cache');\n await fs.promises.mkdir(cacheDir, { recursive: true });\n\n // Write .gitignore to exclude cache from version control\n const gitignorePath = path.join(skilltreeDir, '.gitignore');\n try {\n const existing = await fs.promises.readFile(gitignorePath, 'utf-8');\n if (!existing.includes('.cache')) {\n await fs.promises.writeFile(\n gitignorePath,\n existing.trimEnd() + '\\n.cache/\\n',\n 'utf-8'\n );\n }\n } catch {\n // No existing .gitignore — create one\n await fs.promises.writeFile(gitignorePath, '.cache/\\n', 'utf-8');\n }\n\n // Write config.json if custom config provided\n if (config && Object.keys(config).length > 0) {\n const configPath = path.join(skilltreeDir, 'config.json');\n await fs.promises.writeFile(\n configPath,\n JSON.stringify(fullConfig, null, 2),\n 'utf-8'\n );\n }\n}\n\n/**\n * Check if a file matches skill file patterns\n */\nexport function isSkillFile(\n filename: string,\n patterns: string[] = DEFAULT_CONFIG.skillFilePatterns!\n): boolean {\n const lower = filename.toLowerCase();\n\n for (const pattern of patterns) {\n if (pattern.includes('*')) {\n // Simple glob matching for *.skill.md pattern\n const regex = new RegExp(\n '^' + pattern.toLowerCase().replace(/\\*/g, '.*') + '$'\n );\n if (regex.test(lower)) return true;\n } else {\n if (lower === pattern.toLowerCase()) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if a path should be excluded\n */\nexport function shouldExclude(relativePath: string, excludePatterns: string[]): boolean {\n const parts = relativePath.split(path.sep);\n\n for (const part of parts) {\n if (excludePatterns.includes(part)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Discovered skill location\n */\nexport interface DiscoveredSkill {\n /** Skill ID (derived from path) */\n id: string;\n /** Full path to the SKILL.md file */\n filePath: string;\n /** Directory containing the skill */\n directory: string;\n}\n\n/**\n * Discover all skills in a .skilltree directory\n */\nexport async function discoverSkills(repoRoot: string): Promise<DiscoveredSkill[]> {\n const skilltreeDir = getSkilltreeDir(repoRoot);\n const config = await loadSkilltreeConfig(repoRoot);\n const discovered: DiscoveredSkill[] = [];\n\n // Check if .skilltree directory exists\n if (!(await hasSkilltreeDir(repoRoot))) {\n return discovered;\n }\n\n if (config.discovery === 'scan') {\n // Scan entire .skilltree directory\n await scanForSkills(skilltreeDir, skilltreeDir, config, discovered);\n } else {\n // Look in explicit paths (default or configured)\n const paths = config.paths || DEFAULT_CONFIG.paths!;\n for (const searchPath of paths) {\n const fullPath = path.join(skilltreeDir, searchPath);\n await scanForSkills(skilltreeDir, fullPath, config, discovered);\n }\n }\n\n return discovered;\n}\n\n/**\n * Recursively scan a directory for skill files\n */\nasync function scanForSkills(\n skilltreeDir: string,\n dir: string,\n config: SkilltreeConfig,\n discovered: DiscoveredSkill[]\n): Promise<void> {\n const relativePath = path.relative(skilltreeDir, dir);\n\n // Check exclusions\n if (relativePath && shouldExclude(relativePath, config.exclude || [])) {\n return;\n }\n\n try {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n\n // First, check for skill files in this directory\n for (const entry of entries) {\n if (entry.isFile() && isSkillFile(entry.name, config.skillFilePatterns)) {\n const filePath = path.join(dir, entry.name);\n const id = deriveSkillId(skilltreeDir, filePath);\n\n if (!discovered.some(d => d.id === id)) {\n discovered.push({\n id,\n filePath,\n directory: dir,\n });\n }\n }\n }\n\n // Then recurse into subdirectories\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.')) {\n await scanForSkills(\n skilltreeDir,\n path.join(dir, entry.name),\n config,\n discovered\n );\n }\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n}\n\n/**\n * Derive a skill ID from its file path\n *\n * Handles namespaced skills like @team/skill-id which create nested directories:\n * .skilltree/skills/@team/skill-id/SKILL.md -> @team/skill-id\n */\nexport function deriveSkillId(skilltreeDir: string, filePath: string): string {\n const dir = path.dirname(filePath);\n const filename = path.basename(filePath);\n const dirName = path.basename(dir);\n const parentDir = path.dirname(dir);\n const parentDirName = path.basename(parentDir);\n\n // If in a dedicated skill directory (not .skilltree root)\n if (dir !== skilltreeDir) {\n // Check if this is a pattern like \"skillname.skill.md\"\n const skillMatch = filename.match(/^(.+)\\.skill\\.md$/i);\n if (skillMatch) {\n // Check if in a namespace directory (starts with @)\n if (parentDirName.startsWith('@')) {\n return `${parentDirName}/${skillMatch[1]}`;\n }\n return skillMatch[1];\n }\n\n // Check if in a namespace directory (parent starts with @)\n // e.g., .skilltree/skills/@team/skill-id/SKILL.md\n if (parentDirName.startsWith('@')) {\n return `${parentDirName}/${dirName}`;\n }\n\n // Standard case: use directory name as skill ID\n // Unless it's a common directory name like \"skills\"\n const commonDirs = ['skills', 'skill', 'playbooks', 'recipes'];\n if (!commonDirs.includes(dirName.toLowerCase())) {\n return dirName;\n }\n }\n\n // Fall back to relative path-based ID\n const relativePath = path.relative(skilltreeDir, filePath);\n const withoutExt = relativePath.replace(/\\.(skill\\.)?md$/i, '');\n return withoutExt.replace(/[\\/\\\\]/g, '-');\n}\n","/**\n * Semantic versioning utilities\n */\n\n/**\n * Parsed semantic version\n */\nexport interface ParsedVersion {\n major: number;\n minor: number;\n patch: number;\n prerelease?: string;\n build?: string;\n}\n\n/**\n * Version bump type\n */\nexport type BumpType = 'major' | 'minor' | 'patch' | 'prerelease';\n\n/**\n * Parse a version string into components\n */\nexport function parseVersion(version: string): ParsedVersion {\n const match = version.match(\n /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([a-zA-Z0-9.-]+))?(?:\\+([a-zA-Z0-9.-]+))?$/\n );\n\n if (!match) {\n throw new Error(`Invalid version format: ${version}`);\n }\n\n return {\n major: parseInt(match[1], 10),\n minor: parseInt(match[2], 10),\n patch: parseInt(match[3], 10),\n prerelease: match[4],\n build: match[5],\n };\n}\n\n/**\n * Format a parsed version back to string\n */\nexport function formatVersion(parsed: ParsedVersion): string {\n let version = `${parsed.major}.${parsed.minor}.${parsed.patch}`;\n if (parsed.prerelease) {\n version += `-${parsed.prerelease}`;\n }\n if (parsed.build) {\n version += `+${parsed.build}`;\n }\n return version;\n}\n\n/**\n * Check if a version string is valid semver\n */\nexport function isValidVersion(version: string): boolean {\n try {\n parseVersion(version);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Compare two versions\n * Returns: -1 if a < b, 0 if a === b, 1 if a > b\n */\nexport function compareVersions(a: string, b: string): -1 | 0 | 1 {\n const parsedA = parseVersion(a);\n const parsedB = parseVersion(b);\n\n // Compare major\n if (parsedA.major !== parsedB.major) {\n return parsedA.major < parsedB.major ? -1 : 1;\n }\n\n // Compare minor\n if (parsedA.minor !== parsedB.minor) {\n return parsedA.minor < parsedB.minor ? -1 : 1;\n }\n\n // Compare patch\n if (parsedA.patch !== parsedB.patch) {\n return parsedA.patch < parsedB.patch ? -1 : 1;\n }\n\n // Compare prerelease (no prerelease > prerelease)\n if (!parsedA.prerelease && parsedB.prerelease) return 1;\n if (parsedA.prerelease && !parsedB.prerelease) return -1;\n if (parsedA.prerelease && parsedB.prerelease) {\n return parsedA.prerelease < parsedB.prerelease ? -1 : parsedA.prerelease > parsedB.prerelease ? 1 : 0;\n }\n\n return 0;\n}\n\n/**\n * Bump a version\n */\nexport function bumpVersion(version: string, type: BumpType): string {\n const parsed = parseVersion(version);\n\n switch (type) {\n case 'major':\n return formatVersion({\n major: parsed.major + 1,\n minor: 0,\n patch: 0,\n });\n\n case 'minor':\n return formatVersion({\n major: parsed.major,\n minor: parsed.minor + 1,\n patch: 0,\n });\n\n case 'patch':\n return formatVersion({\n major: parsed.major,\n minor: parsed.minor,\n patch: parsed.patch + 1,\n });\n\n case 'prerelease':\n if (parsed.prerelease) {\n // Increment prerelease number if exists\n const match = parsed.prerelease.match(/^(.+?)(\\d+)$/);\n if (match) {\n return formatVersion({\n ...parsed,\n prerelease: `${match[1]}${parseInt(match[2], 10) + 1}`,\n });\n }\n return formatVersion({\n ...parsed,\n prerelease: `${parsed.prerelease}.1`,\n });\n }\n // Add new prerelease\n return formatVersion({\n ...parsed,\n prerelease: 'alpha.1',\n });\n\n default:\n throw new Error(`Unknown bump type: ${type}`);\n }\n}\n\n/**\n * Check if version a satisfies version range b\n * Supports: exact, ^, ~, >=, >, <=, <, x ranges\n */\nexport function satisfiesRange(version: string, range: string): boolean {\n const parsed = parseVersion(version);\n\n // Exact match\n if (isValidVersion(range)) {\n return compareVersions(version, range) === 0;\n }\n\n // Caret range (^): allows changes that do not modify the left-most non-zero digit\n if (range.startsWith('^')) {\n const rangeVersion = parseVersion(range.slice(1));\n if (parsed.major !== rangeVersion.major) return false;\n if (rangeVersion.major === 0) {\n if (parsed.minor !== rangeVersion.minor) return false;\n if (rangeVersion.minor === 0) {\n return parsed.patch >= rangeVersion.patch;\n }\n return parsed.patch >= rangeVersion.patch;\n }\n return compareVersions(version, range.slice(1)) >= 0;\n }\n\n // Tilde range (~): allows patch-level changes\n if (range.startsWith('~')) {\n const rangeVersion = parseVersion(range.slice(1));\n return (\n parsed.major === rangeVersion.major &&\n parsed.minor === rangeVersion.minor &&\n parsed.patch >= rangeVersion.patch\n );\n }\n\n // Greater than or equal\n if (range.startsWith('>=')) {\n return compareVersions(version, range.slice(2)) >= 0;\n }\n\n // Greater than\n if (range.startsWith('>')) {\n return compareVersions(version, range.slice(1)) > 0;\n }\n\n // Less than or equal\n if (range.startsWith('<=')) {\n return compareVersions(version, range.slice(2)) <= 0;\n }\n\n // Less than\n if (range.startsWith('<')) {\n return compareVersions(version, range.slice(1)) < 0;\n }\n\n // X-range (e.g., 1.x, 1.2.x)\n if (range.includes('x') || range.includes('*')) {\n const parts = range.split('.');\n if (parts[0] === 'x' || parts[0] === '*') return true;\n if (parsed.major !== parseInt(parts[0], 10)) return false;\n if (parts[1] === 'x' || parts[1] === '*' || parts.length === 1) return true;\n if (parsed.minor !== parseInt(parts[1], 10)) return false;\n if (parts[2] === 'x' || parts[2] === '*' || parts.length === 2) return true;\n return parsed.patch === parseInt(parts[2], 10);\n }\n\n return false;\n}\n\n/**\n * Get the latest version from a list\n */\nexport function getLatestVersion(versions: string[]): string | null {\n if (versions.length === 0) return null;\n\n return versions.reduce((latest, current) => {\n return compareVersions(current, latest) > 0 ? current : latest;\n });\n}\n\n/**\n * Sort versions in ascending order\n */\nexport function sortVersions(versions: string[]): string[] {\n return [...versions].sort((a, b) => compareVersions(a, b));\n}\n\n/**\n * Determine bump type based on changes\n */\nexport function inferBumpType(changes: VersionChanges): BumpType {\n if (changes.breakingChanges && changes.breakingChanges.length > 0) {\n return 'major';\n }\n if (changes.newFeatures && changes.newFeatures.length > 0) {\n return 'minor';\n }\n return 'patch';\n}\n\n/**\n * Changes between versions\n */\nexport interface VersionChanges {\n /** Breaking changes that require major bump */\n breakingChanges?: string[];\n /** New features that require minor bump */\n newFeatures?: string[];\n /** Bug fixes and patches */\n bugFixes?: string[];\n /** Other changes */\n other?: string[];\n}\n","/**\n * Federation Manager\n *\n * Main orchestrator for federated skill operations:\n * - Remote management (add, remove, refresh)\n * - Browse remote skills\n * - Import skills (link/fork modes)\n * - Share skills to remotes\n * - Upstream sync for linked skills\n */\n\nimport type { Skill, SkillFilter, StorageAdapter, SkillUpstream } from '../types.js';\nimport type {\n FederatedRemoteConfig,\n RemoteState,\n ImportOptions,\n ImportResult,\n ShareOptions,\n ShareResult,\n UpstreamUpdate,\n PullUpstreamOptions,\n PullUpstreamResult,\n FederationEvent,\n FederationEventHandler,\n ImportMode,\n} from './types.js';\nimport { RemoteStore } from './remote-store.js';\nimport { RemoteManager } from './remote-manager.js';\nimport { compareVersions } from '../versioning/semver.js';\n\n/**\n * Options for creating a FederationManager\n */\nexport interface FederationManagerOptions {\n /** Base path for skill storage */\n basePath: string;\n\n /** Storage adapter for local skills */\n storage: StorageAdapter;\n}\n\n/**\n * FederationManager orchestrates all federation operations.\n *\n * Usage:\n * ```typescript\n * const federation = new FederationManager({ basePath: './skills', storage });\n * await federation.initialize();\n *\n * // Add a remote\n * await federation.addRemote('team', {\n * url: 'git@github.com:org/skills.git',\n * access: 'read-write',\n * });\n *\n * // Browse and import\n * const skills = await federation.browse('team');\n * await federation.import('team', 'useful-pattern');\n *\n * // Check for updates\n * const updates = await federation.checkUpstream();\n * ```\n */\nexport class FederationManager {\n private basePath: string;\n private storage: StorageAdapter;\n private remoteStore: RemoteStore;\n private remoteManager: RemoteManager;\n private eventHandlers: FederationEventHandler[] = [];\n private initialized = false;\n\n constructor(options: FederationManagerOptions) {\n this.basePath = options.basePath;\n this.storage = options.storage;\n\n this.remoteStore = new RemoteStore({ basePath: options.basePath });\n this.remoteManager = new RemoteManager({\n basePath: options.basePath,\n remoteStore: this.remoteStore,\n });\n }\n\n /**\n * Initialize the federation manager\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await this.remoteStore.initialize();\n await this.remoteManager.initialize();\n\n this.initialized = true;\n }\n\n /**\n * Ensure manager is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized) {\n throw new Error('FederationManager not initialized. Call initialize() first.');\n }\n }\n\n // ===========================================================================\n // Remote Management\n // ===========================================================================\n\n /**\n * Add a remote repository\n */\n async addRemote(name: string, config: FederatedRemoteConfig): Promise<void> {\n this.ensureInitialized();\n\n await this.remoteStore.addRemote(name, config);\n this.emit({ type: 'remote:added', name, config });\n }\n\n /**\n * Remove a remote repository\n */\n async removeRemote(name: string): Promise<boolean> {\n this.ensureInitialized();\n\n // Delete the cache first\n await this.remoteManager.deleteCache(name);\n\n // Remove from store\n const removed = await this.remoteStore.removeRemote(name);\n if (removed) {\n this.emit({ type: 'remote:removed', name });\n }\n\n return removed;\n }\n\n /**\n * List configured remotes\n */\n listRemotes(): string[] {\n this.ensureInitialized();\n return this.remoteStore.listRemotes();\n }\n\n /**\n * Check if a remote exists\n */\n hasRemote(name: string): boolean {\n this.ensureInitialized();\n return this.remoteStore.hasRemote(name);\n }\n\n /**\n * Get the state of a remote\n */\n async getRemoteState(name: string): Promise<RemoteState> {\n this.ensureInitialized();\n return this.remoteManager.getRemoteState(name);\n }\n\n /**\n * Refresh a remote (fetch latest)\n */\n async refreshRemote(name: string): Promise<RemoteState> {\n this.ensureInitialized();\n\n const state = await this.remoteManager.refreshRemote(name);\n this.emit({ type: 'remote:refreshed', name, skillCount: state.skillCount || 0 });\n\n return state;\n }\n\n // ===========================================================================\n // Browse Operations\n // ===========================================================================\n\n /**\n * Browse skills in a remote repository\n */\n async browse(remote: string, filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n\n if (!this.remoteStore.hasRemote(remote)) {\n throw new Error(`Remote not found: ${remote}`);\n }\n\n return this.remoteManager.listSkills(remote, filter);\n }\n\n /**\n * Get a specific skill from a remote\n */\n async browseSkill(remote: string, skillId: string): Promise<Skill | null> {\n this.ensureInitialized();\n\n if (!this.remoteStore.hasRemote(remote)) {\n throw new Error(`Remote not found: ${remote}`);\n }\n\n return this.remoteManager.getSkill(remote, skillId);\n }\n\n // ===========================================================================\n // Import Operations\n // ===========================================================================\n\n /**\n * Import a skill from a remote repository\n */\n async import(\n remote: string,\n skillId: string,\n options: ImportOptions = {}\n ): Promise<ImportResult> {\n this.ensureInitialized();\n\n const mode = options.mode || 'link';\n\n // Get the skill from remote\n const remoteSkill = await this.remoteManager.getSkill(remote, skillId);\n if (!remoteSkill) {\n return {\n success: false,\n localId: '',\n mode,\n error: `Skill not found in remote: ${skillId}`,\n };\n }\n\n // Determine local ID\n const localId = options.as || this.getDefaultLocalId(remote, skillId, mode);\n\n // Check for collision\n const existing = await this.storage.getSkill(localId);\n if (existing && !options.overwrite) {\n return {\n success: false,\n localId,\n mode,\n error: `Skill already exists locally: ${localId}. Use 'as' option or 'overwrite: true'.`,\n };\n }\n\n // Create local skill\n const localSkill: Skill = {\n ...remoteSkill,\n id: localId,\n source: {\n type: 'imported',\n location: `${remote}/${skillId}`,\n importedAt: new Date(),\n },\n };\n\n // Set upstream tracking for link mode\n if (mode === 'link') {\n localSkill.upstream = {\n remote,\n skillId,\n version: remoteSkill.version,\n syncedAt: new Date(),\n };\n } else {\n // Fork mode - record in derivedFrom\n localSkill.derivedFrom = [\n ...(localSkill.derivedFrom || []),\n `${remote}/${skillId}@${remoteSkill.version}`,\n ];\n // Clear any upstream from original\n delete localSkill.upstream;\n }\n\n // Save locally\n await this.storage.saveSkill(localSkill);\n\n this.emit({ type: 'skill:imported', localId, remote, mode });\n\n return {\n success: true,\n skill: localSkill,\n localId,\n mode,\n };\n }\n\n /**\n * Get the default local ID for an imported skill\n */\n private getDefaultLocalId(\n remote: string,\n skillId: string,\n mode: ImportMode\n ): string {\n if (mode === 'link') {\n return `@${remote}/${skillId}`;\n }\n return skillId;\n }\n\n // ===========================================================================\n // Share Operations\n // ===========================================================================\n\n /**\n * Share a local skill to a remote repository\n */\n async share(\n localId: string,\n remote: string,\n options: ShareOptions = {}\n ): Promise<ShareResult> {\n this.ensureInitialized();\n\n // Check remote exists and is writable\n const config = this.remoteStore.getRemote(remote);\n if (!config) {\n return {\n success: false,\n remoteId: '',\n error: `Remote not found: ${remote}`,\n };\n }\n\n if (config.access !== 'read-write') {\n return {\n success: false,\n remoteId: '',\n error: `Remote ${remote} is read-only`,\n };\n }\n\n // Get local skill\n const skill = await this.storage.getSkill(localId);\n if (!skill) {\n return {\n success: false,\n remoteId: '',\n error: `Local skill not found: ${localId}`,\n };\n }\n\n // Determine remote ID\n const remoteId = options.as || this.stripPrefix(localId);\n\n // Check for collision in remote\n if (!options.overwrite) {\n const existingRemote = await this.remoteManager.getSkill(remote, remoteId);\n if (existingRemote) {\n return {\n success: false,\n remoteId,\n error: `Skill already exists in remote: ${remoteId}. Use 'as' option or 'overwrite: true'.`,\n };\n }\n }\n\n // Create skill for remote (remove local-specific fields)\n const remoteSkill: Skill = {\n ...skill,\n id: remoteId,\n upstream: undefined, // Don't copy upstream tracking\n };\n\n // Write to remote\n await this.remoteManager.writeSkill(remote, remoteSkill);\n\n // Commit and push\n const message = options.message || `Add skill: ${remoteSkill.name}`;\n const { commitHash } = await this.remoteManager.commitAndPush(remote, message);\n\n this.emit({ type: 'skill:shared', localId, remote, remoteId });\n\n return {\n success: true,\n remoteId,\n commitHash,\n };\n }\n\n /**\n * Strip @remote/ prefix from skill ID\n */\n private stripPrefix(id: string): string {\n const match = id.match(/^@[^/]+\\/(.+)$/);\n return match ? match[1] : id;\n }\n\n // ===========================================================================\n // Upstream Sync Operations\n // ===========================================================================\n\n /**\n * Check for upstream updates to linked skills\n */\n async checkUpstream(): Promise<UpstreamUpdate[]> {\n this.ensureInitialized();\n\n const updates: UpstreamUpdate[] = [];\n\n // Get all local skills\n const localSkills = await this.storage.listSkills();\n\n // Filter to linked skills\n const linkedSkills = localSkills.filter(s => s.upstream);\n\n for (const skill of linkedSkills) {\n const upstream = skill.upstream!;\n\n // Get the remote skill\n try {\n const remoteSkill = await this.remoteManager.getSkill(\n upstream.remote,\n upstream.skillId\n );\n\n if (!remoteSkill) {\n // Skill was deleted upstream\n updates.push({\n localId: skill.id,\n remote: upstream.remote,\n remoteId: upstream.skillId,\n localVersion: skill.version,\n remoteVersion: 'deleted',\n behind: -1,\n hasLocalChanges: skill.updatedAt > upstream.syncedAt,\n });\n continue;\n }\n\n // Compare versions\n const comparison = compareVersions(skill.version, remoteSkill.version);\n if (comparison < 0) {\n // Local is behind\n updates.push({\n localId: skill.id,\n remote: upstream.remote,\n remoteId: upstream.skillId,\n localVersion: skill.version,\n remoteVersion: remoteSkill.version,\n behind: this.calculateVersionsBehind(skill.version, remoteSkill.version),\n hasLocalChanges: skill.updatedAt > upstream.syncedAt,\n });\n }\n } catch {\n // Remote not available - skip\n continue;\n }\n }\n\n return updates;\n }\n\n /**\n * Calculate how many versions behind\n */\n private calculateVersionsBehind(local: string, remote: string): number {\n const [localMajor, localMinor, localPatch] = local.split('.').map(Number);\n const [remoteMajor, remoteMinor, remotePatch] = remote.split('.').map(Number);\n\n if (remoteMajor > localMajor) {\n return remoteMajor - localMajor;\n }\n if (remoteMinor > localMinor) {\n return remoteMinor - localMinor;\n }\n return remotePatch - localPatch;\n }\n\n /**\n * Pull upstream changes for a linked skill\n */\n async pullUpstream(\n localId: string,\n options: PullUpstreamOptions = {}\n ): Promise<PullUpstreamResult> {\n this.ensureInitialized();\n\n const strategy = options.strategy || 'merge';\n\n // Get local skill\n const localSkill = await this.storage.getSkill(localId);\n if (!localSkill) {\n throw new Error(`Local skill not found: ${localId}`);\n }\n\n if (!localSkill.upstream) {\n throw new Error(`Skill ${localId} is not linked to an upstream`);\n }\n\n const upstream = localSkill.upstream;\n const previousVersion = localSkill.version;\n\n // Get remote skill\n const remoteSkill = await this.remoteManager.getSkill(\n upstream.remote,\n upstream.skillId\n );\n\n if (!remoteSkill) {\n throw new Error(\n `Upstream skill not found: ${upstream.remote}/${upstream.skillId}`\n );\n }\n\n // Handle based on strategy\n let updatedSkill: Skill;\n let hadConflicts = false;\n\n if (strategy === 'overwrite') {\n // Replace with remote version\n updatedSkill = {\n ...remoteSkill,\n id: localId,\n upstream: {\n remote: upstream.remote,\n skillId: upstream.skillId,\n version: remoteSkill.version,\n syncedAt: new Date(),\n },\n };\n } else {\n // Merge strategy - try to preserve local changes\n const hasLocalChanges = localSkill.updatedAt > upstream.syncedAt;\n\n if (!hasLocalChanges) {\n // No local changes, just update\n updatedSkill = {\n ...remoteSkill,\n id: localId,\n upstream: {\n remote: upstream.remote,\n skillId: upstream.skillId,\n version: remoteSkill.version,\n syncedAt: new Date(),\n },\n };\n } else {\n // Merge changes (simple field-level merge)\n updatedSkill = this.mergeSkills(localSkill, remoteSkill);\n hadConflicts = false; // TODO: detect actual conflicts\n }\n }\n\n // Save updated skill\n await this.storage.saveSkill(updatedSkill);\n\n this.emit({\n type: 'upstream:updated',\n localId,\n previousVersion,\n newVersion: updatedSkill.version,\n });\n\n return {\n success: true,\n skill: updatedSkill,\n previousVersion,\n newVersion: updatedSkill.version,\n hadConflicts,\n };\n }\n\n /**\n * Merge local and remote skills\n */\n private mergeSkills(local: Skill, remote: Skill): Skill {\n // Simple merge: take remote content, keep local metadata\n return {\n ...remote,\n id: local.id,\n // Preserve local instructions if they were modified\n instructions: local.instructions !== remote.instructions\n ? `${local.instructions}\\n\\n---\\n\\n${remote.instructions}`\n : remote.instructions,\n // Update upstream tracking\n upstream: {\n remote: local.upstream!.remote,\n skillId: local.upstream!.skillId,\n version: remote.version,\n syncedAt: new Date(),\n },\n };\n }\n\n /**\n * Unlink a skill from its upstream (convert link to fork)\n */\n async unlink(localId: string): Promise<void> {\n this.ensureInitialized();\n\n const skill = await this.storage.getSkill(localId);\n if (!skill) {\n throw new Error(`Skill not found: ${localId}`);\n }\n\n if (!skill.upstream) {\n throw new Error(`Skill ${localId} is not linked to an upstream`);\n }\n\n // Record original source in derivedFrom\n const upstream = skill.upstream;\n skill.derivedFrom = [\n ...(skill.derivedFrom || []),\n `${upstream.remote}/${upstream.skillId}@${upstream.version}`,\n ];\n\n // Remove upstream tracking\n delete skill.upstream;\n\n // Save updated skill\n await this.storage.saveSkill(skill);\n\n this.emit({ type: 'upstream:unlinked', localId });\n }\n\n // ===========================================================================\n // Events\n // ===========================================================================\n\n /**\n * Subscribe to federation events\n */\n on(handler: FederationEventHandler): () => void {\n this.eventHandlers.push(handler);\n return () => this.off(handler);\n }\n\n /**\n * Unsubscribe from events\n */\n off(handler: FederationEventHandler): void {\n const index = this.eventHandlers.indexOf(handler);\n if (index >= 0) {\n this.eventHandlers.splice(index, 1);\n }\n }\n\n /**\n * Emit an event\n */\n private emit(event: FederationEvent): void {\n for (const handler of this.eventHandlers) {\n try {\n handler(event);\n } catch (error) {\n console.error('Federation event handler error:', error);\n }\n }\n }\n}\n\n/**\n * Create a FederationManager instance\n */\nexport function createFederationManager(\n options: FederationManagerOptions\n): FederationManager {\n return new FederationManager(options);\n}\n","/**\n * SkillBank - Main orchestrator for skill-tree library\n *\n * Provides a unified interface for:\n * - Storing and retrieving skills\n * - Version management and lineage tracking\n * - Serving layer integration\n * - Federation and sync\n */\n\nimport type {\n Skill,\n SkillFilter,\n SkillVersion,\n SkillLineage,\n StorageAdapter,\n SkillTreeEvent,\n SkillTreeEventHandler,\n SkillScope,\n SkillVisibility,\n MaterializationConfig,\n} from './types.js';\nimport { hasTaxonomySupport } from './types.js';\nimport { SyncManager } from './sync/sync-manager.js';\nimport type { SyncConfig } from './sync/types.js';\nimport { SkillGraphServer } from './serving/graph-server.js';\nimport type { GraphServerConfig } from './serving/types.js';\nimport {\n createStorageView,\n createServingEventBridge,\n type SkillStorageView,\n type ServingEventBridge,\n type SkillBankToServingEvent,\n type ServingToSkillBankEvent,\n} from './serving/interfaces.js';\nimport {\n FederationManager,\n} from './federation/index.js';\nimport { MemoryStorageAdapter } from './storage/base.js';\nimport { CachedStorageAdapter } from './storage/cached.js';\nimport { LineageTracker, type NewVersionOptions, type ForkOptions, type RollbackOptions } from './versioning/index.js';\nimport { HookRegistry } from './hooks/registry.js';\nimport { Materializer } from './materialization/materializer.js';\nimport type {\n HookEvent,\n HookContext,\n SkillCrudHookContext,\n} from './hooks/types.js';\n\n/**\n * Configuration for SkillBank\n */\nexport interface SkillBankConfig {\n /** Storage configuration */\n storage?:\n | { type: 'memory' }\n | { basePath: string; openSkillsCompatible?: boolean };\n /** Namespace configuration for multi-tier skill trees */\n namespace?: {\n /** Current agent ID (used as owner for personal skills) */\n agentId: string;\n /** Team the agent belongs to */\n team?: string;\n /** Default scope for new skills */\n defaultScope?: SkillScope;\n /** Default visibility for new skills */\n defaultVisibility?: SkillVisibility;\n };\n /** Hook registry for event-driven extensibility */\n hookRegistry?: HookRegistry;\n /** Sync configuration for multi-agent collaboration */\n sync?: {\n /** Sync configuration (remote, agent identity, behavior, conflicts) */\n config: SyncConfig;\n /** Pull remote changes on initialize() (default: false) */\n pullOnInit?: boolean;\n };\n /** Materialization configuration for agent-discoverable skill output */\n materialization?: MaterializationConfig;\n}\n\n/**\n * Main SkillBank class\n */\nexport class SkillBank {\n private storage: StorageAdapter;\n private lineageTracker: LineageTracker;\n private eventHandlers: SkillTreeEventHandler[] = [];\n private initialized = false;\n\n /** Namespace configuration for multi-tier skill trees */\n private namespaceConfig?: {\n agentId: string;\n team?: string;\n defaultScope: SkillScope;\n defaultVisibility: SkillVisibility;\n };\n\n /** Federation manager for remote repository connections */\n private federationManager?: FederationManager;\n\n /** Base path for filesystem storage (needed for federation) */\n private basePath?: string;\n\n /** Hook registry for event-driven extensibility */\n private hookRegistry: HookRegistry;\n\n /** Sync manager for multi-agent collaboration */\n private syncManager?: SyncManager;\n\n /** Whether to pull on initialize */\n private syncPullOnInit = false;\n\n /** Materializer for agent-discoverable output */\n private materializer?: Materializer;\n\n constructor(config: SkillBankConfig = {}) {\n // Initialize hook registry (use provided or create new)\n this.hookRegistry = config.hookRegistry ?? new HookRegistry();\n\n // Initialize storage\n if (config.storage && 'type' in config.storage && config.storage.type === 'memory') {\n this.storage = new MemoryStorageAdapter();\n } else if (config.storage && 'basePath' in config.storage) {\n this.basePath = config.storage.basePath;\n this.storage = new CachedStorageAdapter({\n basePath: config.storage.basePath,\n openSkillsCompatible: config.storage.openSkillsCompatible ?? true,\n });\n } else {\n this.storage = new MemoryStorageAdapter();\n }\n\n // Initialize lineage tracker\n this.lineageTracker = new LineageTracker(this.storage);\n\n // Initialize namespace configuration\n if (config.namespace) {\n this.namespaceConfig = {\n agentId: config.namespace.agentId,\n team: config.namespace.team,\n defaultScope: config.namespace.defaultScope || 'personal',\n defaultVisibility: config.namespace.defaultVisibility || 'private',\n };\n }\n\n // Initialize sync if configured\n if (config.sync) {\n if (!this.basePath) {\n throw new Error(\n 'Sync requires a basePath. Configure storage: { basePath: \"...\" }'\n );\n }\n this.syncManager = new SyncManager({\n repoPath: this.basePath,\n config: config.sync.config,\n hookRegistry: this.hookRegistry,\n });\n this.syncPullOnInit = config.sync.pullOnInit ?? false;\n }\n\n // Initialize materializer if configured\n if (config.materialization?.enabled && this.basePath) {\n this.materializer = new Materializer(\n this.storage,\n this.basePath,\n config.materialization\n );\n }\n }\n\n /**\n * Initialize the skill bank (required before use)\n */\n async initialize(): Promise<void> {\n await this.storage.initialize();\n\n // Initialize federation if basePath is available\n if (this.basePath) {\n this.federationManager = new FederationManager({\n basePath: this.basePath,\n storage: this.storage,\n });\n await this.federationManager.initialize();\n }\n\n // Initialize sync if configured\n if (this.syncManager) {\n await this.syncManager.initialize();\n if (this.syncPullOnInit) {\n await this.syncManager.pull();\n }\n }\n\n // Initialize materializer if configured\n if (this.materializer) {\n await this.materializer.initialize();\n }\n\n this.initialized = true;\n }\n\n /**\n * Shutdown the skill bank cleanly\n */\n async shutdown(): Promise<void> {\n if (this.syncManager) {\n await this.syncManager.shutdown();\n }\n if (this.materializer) {\n this.materializer.shutdown();\n }\n }\n\n /**\n * Ensure initialized before operations\n */\n private ensureInitialized(): void {\n if (!this.initialized) {\n throw new Error('SkillBank not initialized. Call initialize() first.');\n }\n }\n\n // ==========================================================================\n // Skill CRUD Operations\n // ==========================================================================\n\n /**\n * Get a skill by ID\n */\n async getSkill(id: string, version?: string): Promise<Skill | null> {\n this.ensureInitialized();\n return this.storage.getSkill(id, version);\n }\n\n /**\n * List all skills with optional filtering\n */\n async listSkills(filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n return this.storage.listSkills(filter);\n }\n\n /**\n * Search skills by query (uses SQLite FTS when available)\n */\n async searchSkills(query: string): Promise<Skill[]> {\n this.ensureInitialized();\n return this.storage.searchSkills(query);\n }\n\n /**\n * Save or update a skill\n *\n * Handles:\n * - Setting timestamps (createdAt on new skills, updatedAt always)\n * - Applying namespace if configured\n * - Placing in taxonomy if available\n * - Emitting skill:created or skill:updated events\n */\n async saveSkill(skill: Skill): Promise<void> {\n this.ensureInitialized();\n\n // Apply namespace if configured and skill doesn't have one\n const prepared = this.ensureNamespace(skill);\n\n const existing = await this.storage.getSkill(prepared.id);\n\n // Set timestamps\n if (!existing && !prepared.createdAt) {\n prepared.createdAt = new Date();\n }\n prepared.updatedAt = new Date();\n\n await this.storage.saveSkill(prepared);\n\n if (existing) {\n this.emit({ type: 'skill:updated', skill: prepared, previousVersion: existing.version });\n } else {\n this.emit({ type: 'skill:created', skill: prepared });\n }\n\n // Place in taxonomy if available and storage supports it\n if (prepared.taxonomy && hasTaxonomySupport(this.storage)) {\n try {\n await this.storage.placeInTaxonomy(prepared.id, prepared.taxonomy);\n } catch {\n // Taxonomy placement is optional\n }\n }\n }\n\n /**\n * Ensure a skill has namespace information\n */\n private ensureNamespace(skill: Skill): Skill {\n if (skill.namespace || !this.namespaceConfig) {\n return skill;\n }\n\n return {\n ...skill,\n namespace: {\n scope: this.namespaceConfig.defaultScope,\n owner: this.namespaceConfig.agentId,\n team: this.namespaceConfig.team,\n visibility: this.namespaceConfig.defaultVisibility,\n },\n };\n }\n\n /**\n * Delete a skill\n */\n async deleteSkill(id: string, version?: string): Promise<boolean> {\n this.ensureInitialized();\n\n const deleted = await this.storage.deleteSkill(id, version);\n if (deleted) {\n this.emit({ type: 'skill:deleted', skillId: id });\n }\n return deleted;\n }\n\n /**\n * Deprecate a skill\n */\n async deprecateSkill(id: string): Promise<Skill> {\n this.ensureInitialized();\n\n const skill = await this.storage.getSkill(id);\n if (!skill) {\n throw new Error(`Skill not found: ${id}`);\n }\n\n const deprecated: Skill = {\n ...skill,\n status: 'deprecated',\n updatedAt: new Date(),\n };\n\n await this.storage.saveSkill(deprecated);\n this.emit({ type: 'skill:deprecated', skillId: id });\n\n return deprecated;\n }\n\n // ==========================================================================\n // Version Management\n // ==========================================================================\n\n /**\n * Create a new version of a skill\n */\n async createVersion(\n skillId: string,\n updates: Partial<Skill>,\n options?: NewVersionOptions\n ): Promise<Skill> {\n this.ensureInitialized();\n\n const newSkill = await this.lineageTracker.createVersion(skillId, updates, options);\n this.emit({\n type: 'skill:updated',\n skill: newSkill,\n previousVersion: newSkill.parentVersion || '',\n });\n\n return newSkill;\n }\n\n /**\n * Fork a skill to create a new variant\n */\n async forkSkill(skillId: string, options: ForkOptions): Promise<Skill> {\n this.ensureInitialized();\n\n const forked = await this.lineageTracker.forkSkill(skillId, options);\n this.emit({ type: 'skill:created', skill: forked });\n\n return forked;\n }\n\n /**\n * Get version history for a skill\n */\n async getVersionHistory(skillId: string): Promise<SkillVersion[]> {\n this.ensureInitialized();\n return this.storage.getVersionHistory(skillId);\n }\n\n /**\n * Get full lineage for a skill\n */\n async getLineage(skillId: string): Promise<SkillLineage | null> {\n this.ensureInitialized();\n return this.storage.getLineage(skillId);\n }\n\n /**\n * Rollback a skill to a previous version\n */\n async rollbackSkill(\n skillId: string,\n toVersion: string,\n options?: RollbackOptions\n ): Promise<Skill> {\n this.ensureInitialized();\n return this.lineageTracker.rollback(skillId, toVersion, options);\n }\n\n /**\n * Compare two versions of a skill\n */\n async compareVersions(skillId: string, versionA: string, versionB: string) {\n this.ensureInitialized();\n return this.lineageTracker.compareVersions(skillId, versionA, versionB);\n }\n\n // ==========================================================================\n // Events\n // ==========================================================================\n\n /**\n * Subscribe to skill bank events (skill:created, skill:updated, skill:deleted, skill:deprecated).\n * Returns an unsubscribe function.\n *\n * This is for simple, synchronous event listeners. For advanced use cases — async\n * handlers, priority ordering, filtering, or storage-level hooks (storage:after-save,\n * storage:after-delete) — use `getHookRegistry().register()` instead.\n */\n on(handler: SkillTreeEventHandler): () => void {\n this.eventHandlers.push(handler);\n return () => {\n this.off(handler);\n };\n }\n\n /**\n * Unsubscribe a handler from events\n */\n off(handler: SkillTreeEventHandler): void {\n const index = this.eventHandlers.indexOf(handler);\n if (index >= 0) {\n this.eventHandlers.splice(index, 1);\n }\n }\n\n /**\n * Get current event handler count\n */\n getEventHandlerCount(): number {\n return this.eventHandlers.length;\n }\n\n /**\n * Emit an event to all handlers and execute corresponding hooks\n */\n private emit(event: SkillTreeEvent): void {\n // Execute event handlers (synchronous)\n for (const handler of this.eventHandlers) {\n try {\n handler(event);\n } catch (error) {\n console.error('Event handler error:', error);\n }\n }\n\n // Execute hooks asynchronously (fire-and-forget for backward compatibility)\n const hookEvent = this.mapEventToHook(event);\n if (hookEvent) {\n const context = this.buildHookContext(event, hookEvent);\n this.hookRegistry.execute(hookEvent, context).catch((err) => {\n console.error('Hook execution error:', err);\n });\n }\n\n // Trigger materialization (fire-and-forget)\n if (this.materializer) {\n const materialize = async () => {\n if (event.type === 'skill:created' || event.type === 'skill:updated') {\n await this.materializer!.onSkillChanged(event.skill.id);\n } else if (event.type === 'skill:deleted') {\n await this.materializer!.onSkillDeleted(event.skillId);\n }\n };\n materialize().catch((err) => {\n console.error('Materialization error:', err);\n });\n }\n }\n\n /**\n * Map SkillTreeEvent type to HookEvent type\n */\n private mapEventToHook(event: SkillTreeEvent): HookEvent | null {\n const mapping: Record<SkillTreeEvent['type'], HookEvent | null> = {\n 'skill:created': 'skill:created',\n 'skill:updated': 'skill:updated',\n 'skill:deprecated': 'skill:deprecated',\n 'skill:deleted': 'skill:deleted',\n };\n return mapping[event.type] ?? null;\n }\n\n /**\n * Build hook context from SkillTreeEvent\n */\n private buildHookContext(\n event: SkillTreeEvent,\n hookEvent: HookEvent\n ): Omit<HookContext, 'invocationId' | 'timestamp'> {\n switch (event.type) {\n case 'skill:created':\n return {\n event: hookEvent as 'skill:created',\n skill: event.skill,\n } as Omit<SkillCrudHookContext, 'invocationId' | 'timestamp'>;\n\n case 'skill:updated':\n return {\n event: hookEvent as 'skill:updated',\n skill: event.skill,\n previousVersion: event.previousVersion,\n } as Omit<SkillCrudHookContext, 'invocationId' | 'timestamp'>;\n\n case 'skill:deprecated':\n return {\n event: hookEvent as 'skill:deprecated',\n skill: { id: event.skillId } as Skill,\n } as Omit<SkillCrudHookContext, 'invocationId' | 'timestamp'>;\n\n case 'skill:deleted':\n return {\n event: hookEvent as 'skill:deleted',\n skill: { id: event.skillId } as Skill,\n } as Omit<SkillCrudHookContext, 'invocationId' | 'timestamp'>;\n\n default:\n return { event: hookEvent } as Omit<HookContext, 'invocationId' | 'timestamp'>;\n }\n }\n\n /**\n * Get the underlying storage adapter (for advanced use cases)\n */\n getStorage(): StorageAdapter {\n return this.storage;\n }\n\n /**\n * Get the hook registry for registering custom hooks\n */\n getHookRegistry(): HookRegistry {\n return this.hookRegistry;\n }\n\n // ==========================================================================\n // Serving Layer Integration\n // ==========================================================================\n\n /**\n * Create a serving layer (SkillGraphServer) wired to this SkillBank\n *\n * @example\n * ```typescript\n * const { server, eventBridge, storageView } = await bank.createServingLayer({\n * initialLoadout: { tags: ['typescript'] },\n * maxExpanded: 5,\n * });\n *\n * await server.setLoadoutForTask('Fix authentication bug');\n * ```\n */\n async createServingLayer(config?: GraphServerConfig): Promise<{\n server: SkillGraphServer;\n eventBridge: ServingEventBridge;\n storageView: SkillStorageView;\n }> {\n this.ensureInitialized();\n\n // Create read-only storage view\n const storageView = createStorageView(this.storage);\n\n // Create event bridge\n const { bridge, emitFromSkillBank, onServingEvent } = createServingEventBridge();\n\n // Subscribe to SkillBank events and forward to serving layer\n this.on((event) => {\n const servingEvent = this.mapToServingEvent(event);\n if (servingEvent) {\n emitFromSkillBank(servingEvent);\n }\n });\n\n // Subscribe to serving events and handle in SkillBank\n onServingEvent((event) => {\n this.handleServingEvent(event);\n });\n\n // Create server with the storage adapter\n const server = new SkillGraphServer(this.storage, config);\n await server.initialize();\n\n return { server, eventBridge: bridge, storageView };\n }\n\n /**\n * Map SkillBank events to serving layer events\n */\n private mapToServingEvent(event: SkillTreeEvent): SkillBankToServingEvent | null {\n switch (event.type) {\n case 'skill:created':\n return { type: 'skill:created', skill: event.skill };\n case 'skill:updated':\n return { type: 'skill:updated', skill: event.skill, previousVersion: event.previousVersion };\n case 'skill:deleted':\n return { type: 'skill:deleted', skillId: event.skillId };\n case 'skill:deprecated':\n return { type: 'skill:deprecated', skillId: event.skillId };\n default:\n return null;\n }\n }\n\n /**\n * Handle events from serving layer\n */\n private async handleServingEvent(event: ServingToSkillBankEvent): Promise<void> {\n switch (event.type) {\n case 'skill:used':\n // Update skill metrics\n const skill = await this.storage.getSkill(event.skillId);\n if (skill) {\n skill.metrics.usageCount++;\n skill.metrics.lastUsed = new Date();\n if (event.success) {\n const total = skill.metrics.usageCount;\n const currentSuccesses = skill.metrics.successRate * (total - 1);\n skill.metrics.successRate = (currentSuccesses + 1) / total;\n } else {\n const total = skill.metrics.usageCount;\n const currentSuccesses = skill.metrics.successRate * (total - 1);\n skill.metrics.successRate = currentSuccesses / total;\n }\n skill.updatedAt = new Date();\n await this.storage.saveSkill(skill);\n }\n break;\n\n case 'skill:feedback':\n // Record feedback in skill metrics\n const feedbackSkill = await this.storage.getSkill(event.skillId);\n if (feedbackSkill) {\n feedbackSkill.metrics.feedbackScores.push(event.score);\n if (feedbackSkill.metrics.feedbackScores.length > 50) {\n feedbackSkill.metrics.feedbackScores = feedbackSkill.metrics.feedbackScores.slice(-50);\n }\n feedbackSkill.updatedAt = new Date();\n await this.storage.saveSkill(feedbackSkill);\n }\n break;\n\n case 'skill:requested':\n break;\n\n case 'loadout:changed':\n break;\n }\n }\n\n // ==========================================================================\n // Utilities\n // ==========================================================================\n\n /**\n * Get statistics about the skill bank\n */\n async getStats(): Promise<SkillBankStats> {\n this.ensureInitialized();\n\n const skills = await this.storage.listSkills();\n\n const stats: SkillBankStats = {\n totalSkills: skills.length,\n byStatus: {\n draft: 0,\n active: 0,\n deprecated: 0,\n experimental: 0,\n },\n byTag: {},\n avgSuccessRate: 0,\n totalUsage: 0,\n };\n\n // Initialize namespace stats if config is present\n if (this.namespaceConfig) {\n stats.byScope = { personal: 0, team: 0, global: 0 };\n stats.byVisibility = { private: 0, 'team-only': 0, public: 0 };\n }\n\n let successRateSum = 0;\n let successRateCount = 0;\n\n for (const skill of skills) {\n stats.byStatus[skill.status]++;\n\n for (const tag of skill.tags) {\n stats.byTag[tag] = (stats.byTag[tag] || 0) + 1;\n }\n\n stats.totalUsage += skill.metrics.usageCount;\n if (skill.metrics.successRate > 0) {\n successRateSum += skill.metrics.successRate;\n successRateCount++;\n }\n\n if (stats.byScope && stats.byVisibility) {\n const scope = skill.namespace?.scope || 'personal';\n const visibility = skill.namespace?.visibility || 'private';\n stats.byScope[scope]++;\n stats.byVisibility[visibility]++;\n }\n }\n\n stats.avgSuccessRate = successRateCount > 0 ? successRateSum / successRateCount : 0;\n\n return stats;\n }\n\n /**\n * Export all skills (for backup or migration)\n */\n async exportAll(): Promise<Skill[]> {\n this.ensureInitialized();\n return this.storage.listSkills();\n }\n\n /**\n * Import skills (for restore or migration)\n */\n async importSkills(skills: Skill[]): Promise<{ imported: number; failed: number }> {\n this.ensureInitialized();\n\n let imported = 0;\n let failed = 0;\n\n for (const skill of skills) {\n try {\n await this.storage.saveSkill(skill);\n this.emit({ type: 'skill:created', skill });\n imported++;\n } catch {\n failed++;\n }\n }\n\n return { imported, failed };\n }\n\n // ==========================================================================\n // Sync (Multi-Agent Collaboration)\n // ==========================================================================\n\n /**\n * Access the sync manager for multi-agent skill synchronization.\n *\n * @throws Error if sync is not configured\n */\n get sync(): SyncManager {\n if (!this.syncManager) {\n throw new Error(\n 'Sync not configured. Provide sync config in SkillBankConfig: { sync: { config: createDefaultSyncConfig(...) } }'\n );\n }\n return this.syncManager;\n }\n\n // ==========================================================================\n // Federation (Remote Repository Connections)\n // ==========================================================================\n\n /**\n * Access the federation manager for remote repository operations.\n *\n * @throws Error if no basePath is configured (federation requires filesystem storage)\n */\n get federation(): FederationManager {\n if (!this.federationManager) {\n throw new Error(\n 'Federation requires a basePath. Configure storage: { basePath: \"...\" }'\n );\n }\n return this.federationManager;\n }\n}\n\n/**\n * Statistics about the skill bank\n */\nexport interface SkillBankStats {\n totalSkills: number;\n byStatus: Record<Skill['status'], number>;\n byTag: Record<string, number>;\n avgSuccessRate: number;\n totalUsage: number;\n byScope?: {\n personal: number;\n team: number;\n global: number;\n };\n byVisibility?: {\n private: number;\n 'team-only': number;\n public: number;\n };\n}\n\n/**\n * Create a SkillBank with common defaults\n */\nexport function createSkillBank(config?: SkillBankConfig): SkillBank {\n return new SkillBank(config);\n}\n","/**\n * Cached Storage Adapter\n *\n * Composes FilesystemStorageAdapter (source of truth) with an optional\n * SQLiteStorageAdapter cache for fast FTS search and indexed queries.\n *\n * The SQLite cache is stored in .skilltree/.cache/index.db and is\n * gitignored. If better-sqlite3 is unavailable, it operates in\n * filesystem-only mode gracefully.\n *\n * Directory structure:\n * basePath/.skilltree/\n * skills/ ← committed source of truth\n * .cache/\n * index.db ← SQLite cache (gitignored)\n * manifest.json ← file mtime manifest for staleness detection\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { BaseStorageAdapter } from './base.js';\nimport { FilesystemStorageAdapter } from './filesystem.js';\nimport type { FilesystemStorageConfig } from './filesystem.js';\nimport type {\n Skill,\n SkillFilter,\n SkillVersion,\n SkillLineage,\n SkillFork,\n} from '../types.js';\n\nexport interface CachedStorageConfig {\n /** Base directory for skill storage */\n basePath: string;\n /** Use OpenSkills-compatible format (SKILL.md) — default: true */\n openSkillsCompatible?: boolean;\n}\n\ninterface CacheManifest {\n /** Timestamp of last cache rebuild */\n builtAt: string;\n /** Map of skill ID → file mtime ISO string */\n skills: Record<string, string>;\n}\n\n// Minimal interface for the SQLite adapter methods we use\ninterface SQLiteCacheAdapter {\n initialize(): Promise<void>;\n saveSkill(skill: Skill): Promise<void>;\n getSkill(id: string, version?: string): Promise<Skill | null>;\n listSkills(filter?: SkillFilter): Promise<Skill[]>;\n deleteSkill(id: string, version?: string): Promise<boolean>;\n getVersionHistory(skillId: string): Promise<SkillVersion[]>;\n getLineage(skillId: string): Promise<SkillLineage | null>;\n searchSkills(query: string): Promise<Skill[]>;\n close(): void;\n}\n\n/**\n * Cached storage adapter that uses filesystem as source of truth\n * with an optional SQLite cache for fast queries.\n */\nexport class CachedStorageAdapter extends BaseStorageAdapter {\n private source: FilesystemStorageAdapter;\n private cache: SQLiteCacheAdapter | null = null;\n private basePath: string;\n private cacheDir: string;\n private dbPath: string;\n private manifestPath: string;\n\n constructor(config: CachedStorageConfig) {\n super();\n this.basePath = config.basePath;\n this.cacheDir = path.join(config.basePath, '.skilltree', '.cache');\n this.dbPath = path.join(this.cacheDir, 'index.db');\n this.manifestPath = path.join(this.cacheDir, 'manifest.json');\n\n this.source = new FilesystemStorageAdapter({\n basePath: config.basePath,\n openSkillsCompatible: config.openSkillsCompatible ?? true,\n trackVersions: true,\n });\n }\n\n async initialize(): Promise<void> {\n // Initialize filesystem (source of truth)\n await this.source.initialize();\n\n // Ensure cache directory exists\n if (!fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n }\n\n // Try to initialize SQLite cache\n try {\n const { SQLiteStorageAdapter } = await import('./sqlite.js');\n const sqliteCache = new SQLiteStorageAdapter({\n dbPath: this.dbPath,\n walMode: true,\n enableFTS: true,\n });\n await sqliteCache.initialize();\n this.cache = sqliteCache;\n\n // Rebuild cache if stale\n await this.rebuildIfStale();\n } catch {\n // better-sqlite3 not available — filesystem-only mode\n this.cache = null;\n }\n\n this.initialized = true;\n }\n\n /**\n * Get the base path for this storage\n */\n getBasePath(): string {\n return this.basePath;\n }\n\n /**\n * Whether the SQLite cache is active\n */\n hasCacheEnabled(): boolean {\n return this.cache !== null;\n }\n\n // ==========================================================================\n // Write operations — write-through (filesystem first, then cache)\n // ==========================================================================\n\n async saveSkill(skill: Skill): Promise<void> {\n this.ensureInitialized();\n\n // Write to source of truth first\n await this.source.saveSkill(skill);\n\n // Update cache\n if (this.cache) {\n try {\n await this.cache.saveSkill(skill);\n await this.updateManifestEntry(skill.id);\n } catch {\n // Cache update failed — non-fatal\n }\n }\n }\n\n async deleteSkill(id: string, version?: string): Promise<boolean> {\n this.ensureInitialized();\n\n // Delete from source of truth\n const result = await this.source.deleteSkill(id, version);\n\n // Update cache\n if (this.cache && result) {\n try {\n await this.cache.deleteSkill(id, version);\n await this.removeManifestEntry(id);\n } catch {\n // Cache update failed — non-fatal\n }\n }\n\n return result;\n }\n\n // ==========================================================================\n // Read operations — prefer cache when available\n // ==========================================================================\n\n async getSkill(id: string, version?: string): Promise<Skill | null> {\n this.ensureInitialized();\n // Always read from source of truth for single-skill reads\n // (ensures consistency, and single file reads are fast)\n return this.source.getSkill(id, version);\n }\n\n async listSkills(filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n // Use cache for filtered queries (indexed)\n if (this.cache && filter) {\n try {\n return await this.cache.listSkills(filter);\n } catch {\n // Fallback to source\n }\n }\n return this.source.listSkills(filter);\n }\n\n async searchSkills(query: string): Promise<Skill[]> {\n this.ensureInitialized();\n // Use cache for FTS search\n if (this.cache) {\n try {\n return await this.cache.searchSkills(query);\n } catch {\n // Fallback to source\n }\n }\n return this.source.searchSkills(query);\n }\n\n async getVersionHistory(skillId: string): Promise<SkillVersion[]> {\n this.ensureInitialized();\n return this.source.getVersionHistory(skillId);\n }\n\n async getLineage(skillId: string): Promise<SkillLineage | null> {\n this.ensureInitialized();\n return this.source.getLineage(skillId);\n }\n\n // ==========================================================================\n // Fork tracking — write-through\n // ==========================================================================\n\n async recordFork(sourceSkillId: string, fork: SkillFork): Promise<void> {\n this.ensureInitialized();\n await this.source.recordFork(sourceSkillId, fork);\n }\n\n // ==========================================================================\n // Cache management\n // ==========================================================================\n\n /**\n * Force a full cache rebuild from filesystem\n */\n async rebuildCache(): Promise<void> {\n if (!this.cache) return;\n\n const skills = await this.source.listSkills();\n const manifest: CacheManifest = {\n builtAt: new Date().toISOString(),\n skills: {},\n };\n\n for (const skill of skills) {\n try {\n await this.cache.saveSkill(skill);\n manifest.skills[skill.id] = skill.updatedAt.toISOString();\n } catch {\n // Skip individual skill failures\n }\n }\n\n await this.writeManifest(manifest);\n }\n\n /**\n * Check if cache is stale and rebuild if needed\n */\n private async rebuildIfStale(): Promise<void> {\n if (!this.cache) return;\n\n const manifest = this.readManifest();\n if (!manifest) {\n // No manifest = first run, do full rebuild\n await this.rebuildCache();\n return;\n }\n\n // Compare current filesystem state against manifest\n const skills = await this.source.listSkills();\n const currentIds = new Set(skills.map(s => s.id));\n const manifestIds = new Set(Object.keys(manifest.skills));\n\n // Check for added/removed/modified skills\n let stale = false;\n\n // New or modified skills\n for (const skill of skills) {\n if (!manifestIds.has(skill.id)) {\n stale = true;\n break;\n }\n const manifestMtime = manifest.skills[skill.id];\n if (manifestMtime !== skill.updatedAt.toISOString()) {\n stale = true;\n break;\n }\n }\n\n // Removed skills\n if (!stale) {\n for (const id of manifestIds) {\n if (!currentIds.has(id)) {\n stale = true;\n break;\n }\n }\n }\n\n if (stale) {\n await this.rebuildCache();\n }\n }\n\n private readManifest(): CacheManifest | null {\n try {\n const content = fs.readFileSync(this.manifestPath, 'utf-8');\n return JSON.parse(content) as CacheManifest;\n } catch {\n return null;\n }\n }\n\n private async writeManifest(manifest: CacheManifest): Promise<void> {\n fs.writeFileSync(this.manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');\n }\n\n private async updateManifestEntry(skillId: string): Promise<void> {\n const manifest = this.readManifest() || {\n builtAt: new Date().toISOString(),\n skills: {},\n };\n manifest.skills[skillId] = new Date().toISOString();\n await this.writeManifest(manifest);\n }\n\n private async removeManifestEntry(skillId: string): Promise<void> {\n const manifest = this.readManifest();\n if (manifest) {\n delete manifest.skills[skillId];\n await this.writeManifest(manifest);\n }\n }\n\n /**\n * Close the cache database connection\n */\n close(): void {\n if (this.cache && 'close' in this.cache) {\n this.cache.close();\n }\n }\n}\n","/**\n * Filesystem storage adapter\n * Compatible with OpenSkills SKILL.md format (YAML frontmatter + Markdown)\n *\n * Directory structure:\n * basePath/\n * .skilltree/\n * config.json <- optional configuration\n * skills/ <- default skills location\n * skill-id/\n * SKILL.md\n * .skilltree.json <- metadata\n * .versions/ <- version history\n */\n\nimport * as fs from 'fs/promises';\nimport * as fss from 'fs';\nimport * as path from 'path';\nimport type {\n Skill,\n SkillFilter,\n SkillVersion,\n SkillLineage,\n SkillFork,\n} from '../types.js';\nimport { BaseStorageAdapter } from './base.js';\nimport {\n getSkilltreeDir,\n getSkillsDir,\n initSkilltreeDir,\n discoverSkills,\n type DiscoveredSkill,\n} from '../federation/skilltree-config.js';\n\n/**\n * Configuration for filesystem storage\n */\nexport interface FilesystemStorageConfig {\n /** Base directory for skill storage */\n basePath: string;\n /** Use OpenSkills-compatible format (SKILL.md) */\n openSkillsCompatible?: boolean;\n /** Store version history */\n trackVersions?: boolean;\n}\n\n/**\n * Metadata stored alongside skills\n */\ninterface SkillTreeMetadata {\n /** Source information */\n source?: Skill['source'];\n /** Installation/creation info */\n installedAt: string;\n /** Version history references */\n versions?: string[];\n /** Lineage information */\n lineage?: {\n rootId: string;\n parentVersion?: string;\n derivedFrom?: string[];\n forks?: SkillFork[];\n };\n /** Upstream tracking for linked skills from federation */\n upstream?: Skill['upstream'];\n /** Namespace information */\n namespace?: Skill['namespace'];\n}\n\n/**\n * Filesystem storage adapter with OpenSkills compatibility\n *\n * Uses .skilltree/ directory structure:\n * basePath/.skilltree/skills/ <- skills stored here\n * basePath/.skilltree/.versions/ <- version history\n */\nexport class FilesystemStorageAdapter extends BaseStorageAdapter {\n private config: Required<FilesystemStorageConfig>;\n private skilltreeDir: string;\n private skillsDir: string;\n private versionsDir: string;\n\n constructor(config: FilesystemStorageConfig) {\n super();\n this.config = {\n basePath: config.basePath,\n openSkillsCompatible: config.openSkillsCompatible ?? true,\n trackVersions: config.trackVersions ?? true,\n };\n this.skilltreeDir = getSkilltreeDir(this.config.basePath);\n this.skillsDir = getSkillsDir(this.config.basePath);\n this.versionsDir = path.join(this.skilltreeDir, '.versions');\n }\n\n async initialize(): Promise<void> {\n // Initialize .skilltree directory structure\n await initSkilltreeDir(this.config.basePath);\n\n // Create versions directory if tracking\n if (this.config.trackVersions) {\n await fs.mkdir(this.versionsDir, { recursive: true });\n }\n\n this.initialized = true;\n }\n\n /**\n * Get the base path for this storage\n */\n getBasePath(): string {\n return this.config.basePath;\n }\n\n async saveSkill(skill: Skill): Promise<void> {\n this.ensureInitialized();\n\n const skillDir = path.join(this.skillsDir, skill.id);\n await fs.mkdir(skillDir, { recursive: true });\n\n // Save main skill file\n const skillContent = this.serializeSkill(skill);\n const skillFileName = this.config.openSkillsCompatible ? 'SKILL.md' : 'skill.md';\n await fs.writeFile(path.join(skillDir, skillFileName), skillContent, 'utf-8');\n\n // Save metadata\n const metadata = this.createMetadata(skill);\n await fs.writeFile(\n path.join(skillDir, '.skilltree.json'),\n JSON.stringify(metadata, null, 2),\n 'utf-8'\n );\n\n // Save version snapshot if tracking\n if (this.config.trackVersions) {\n await this.saveVersionSnapshot(skill);\n }\n }\n\n async getSkill(id: string, version?: string): Promise<Skill | null> {\n this.ensureInitialized();\n\n if (version && this.config.trackVersions) {\n return this.getVersionedSkill(id, version);\n }\n\n // Use discovery to find the skill (supports flexible locations)\n const discovered = await discoverSkills(this.config.basePath);\n const location = discovered.find(d => d.id === id);\n\n if (!location) {\n return null;\n }\n\n try {\n const content = await fs.readFile(location.filePath, 'utf-8');\n const metadata = await this.loadMetadata(location.directory);\n return this.parseSkill(id, content, metadata);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n }\n\n async listSkills(filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n\n const skills: Skill[] = [];\n\n // Use discovery to find all skills\n const discovered = await discoverSkills(this.config.basePath);\n\n for (const location of discovered) {\n try {\n const content = await fs.readFile(location.filePath, 'utf-8');\n const metadata = await this.loadMetadata(location.directory);\n const skill = this.parseSkill(location.id, content, metadata);\n skills.push(skill);\n } catch (error) {\n // Skip unreadable skills\n console.warn(`Failed to read skill at ${location.filePath}:`, error);\n }\n }\n\n return this.applyFilter(skills, filter);\n }\n\n async deleteSkill(id: string, version?: string): Promise<boolean> {\n this.ensureInitialized();\n\n if (version && this.config.trackVersions) {\n return this.deleteVersion(id, version);\n }\n\n // Find the skill location\n const discovered = await discoverSkills(this.config.basePath);\n const location = discovered.find(d => d.id === id);\n\n if (!location) {\n return false;\n }\n\n try {\n await fs.rm(location.directory, { recursive: true });\n\n // Also remove version history\n if (this.config.trackVersions) {\n const versionDir = path.join(this.versionsDir, id);\n await fs.rm(versionDir, { recursive: true }).catch(() => {});\n }\n\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return false;\n }\n throw error;\n }\n }\n\n async getVersionHistory(skillId: string): Promise<SkillVersion[]> {\n this.ensureInitialized();\n\n if (!this.config.trackVersions) {\n // Return just current version\n const skill = await this.getSkill(skillId);\n if (!skill) return [];\n return [\n {\n skillId,\n version: skill.version,\n skill,\n changelog: '',\n createdAt: skill.createdAt,\n contentHash: this.hashContent(skill),\n },\n ];\n }\n\n const versionDir = path.join(this.versionsDir, skillId);\n const versions: SkillVersion[] = [];\n\n try {\n const entries = await fs.readdir(versionDir);\n\n for (const entry of entries) {\n if (!entry.endsWith('.json')) continue;\n\n const versionPath = path.join(versionDir, entry);\n const content = await fs.readFile(versionPath, 'utf-8');\n const versionData = JSON.parse(content) as SkillVersion & { skill: unknown };\n\n // Reconstruct dates\n versionData.createdAt = new Date(versionData.createdAt);\n if (versionData.skill) {\n const skill = versionData.skill as Skill;\n skill.createdAt = new Date(skill.createdAt);\n skill.updatedAt = new Date(skill.updatedAt);\n }\n\n versions.push(versionData);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n\n return versions.sort((a, b) => this.compareVersions(a.version, b.version));\n }\n\n async getLineage(skillId: string): Promise<SkillLineage | null> {\n this.ensureInitialized();\n\n const versions = await this.getVersionHistory(skillId);\n if (versions.length === 0) return null;\n\n // Find the skill location and load metadata\n const discovered = await discoverSkills(this.config.basePath);\n const location = discovered.find(d => d.id === skillId);\n const metadata = location ? await this.loadMetadata(location.directory) : null;\n\n return {\n rootId: metadata?.lineage?.rootId || skillId,\n versions,\n forks: metadata?.lineage?.forks || [],\n };\n }\n\n async searchSkills(query: string): Promise<Skill[]> {\n this.ensureInitialized();\n const allSkills = await this.listSkills();\n return this.textSearch(allSkills, query);\n }\n\n // ==========================================================================\n // Serialization\n // ==========================================================================\n\n /**\n * Serialize skill to YAML frontmatter + Markdown format\n */\n private serializeSkill(skill: Skill): string {\n const frontmatter = this.buildFrontmatter(skill);\n return `---\\n${frontmatter}---\\n\\n${skill.instructions}\\n`;\n }\n\n /**\n * Build YAML frontmatter\n */\n private buildFrontmatter(skill: Skill): string {\n const lines: string[] = [];\n\n lines.push(`name: ${skill.name}`);\n lines.push(`description: |`);\n lines.push(` ${skill.description}`);\n lines.push(`version: ${skill.version}`);\n lines.push(`author: ${skill.author}`);\n lines.push(`status: ${skill.status}`);\n lines.push(`date: ${skill.updatedAt.toISOString().split('T')[0]}`);\n\n if (skill.tags.length > 0) {\n lines.push(`tags:`);\n for (const tag of skill.tags) {\n lines.push(` - ${tag}`);\n }\n }\n\n if (skill.parentVersion) {\n lines.push(`parentVersion: ${skill.parentVersion}`);\n }\n\n if (skill.derivedFrom && skill.derivedFrom.length > 0) {\n lines.push(`derivedFrom:`);\n for (const id of skill.derivedFrom) {\n lines.push(` - ${id}`);\n }\n }\n\n if (skill.related && skill.related.length > 0) {\n lines.push(`related:`);\n for (const id of skill.related) {\n lines.push(` - ${id}`);\n }\n }\n\n return lines.join('\\n') + '\\n';\n }\n\n /**\n * Parse skill from YAML frontmatter + Markdown content\n */\n private parseSkill(\n id: string,\n content: string,\n metadata?: SkillTreeMetadata | null\n ): Skill {\n const { frontmatter, body } = this.parseFrontmatterAndBody(content);\n\n // Parse frontmatter fields\n const name = this.extractYamlField(frontmatter, 'name') || id;\n const description = this.extractYamlMultiline(frontmatter, 'description') || '';\n const version = this.extractYamlField(frontmatter, 'version') || '1.0.0';\n const author = this.extractYamlField(frontmatter, 'author') || 'unknown';\n const status = (this.extractYamlField(frontmatter, 'status') || 'active') as Skill['status'];\n const dateStr = this.extractYamlField(frontmatter, 'date');\n const tags = this.extractYamlList(frontmatter, 'tags');\n const parentVersion = this.extractYamlField(frontmatter, 'parentVersion');\n const derivedFrom = this.extractYamlList(frontmatter, 'derivedFrom');\n const related = this.extractYamlList(frontmatter, 'related');\n\n // Body is the instructions verbatim\n const instructions = body.trim();\n\n const date = dateStr ? new Date(dateStr) : new Date();\n\n // Reconstruct upstream dates if present\n let upstream = metadata?.upstream;\n if (upstream?.syncedAt) {\n upstream = {\n ...upstream,\n syncedAt: new Date(upstream.syncedAt),\n };\n }\n\n return {\n id,\n name,\n version,\n description,\n instructions,\n related: related.length > 0 ? related : undefined,\n author,\n tags,\n createdAt: date,\n updatedAt: date,\n status,\n parentVersion: parentVersion || undefined,\n derivedFrom: derivedFrom.length > 0 ? derivedFrom : undefined,\n metrics: {\n usageCount: 0,\n successRate: 0,\n feedbackScores: [],\n },\n source: metadata?.source,\n upstream,\n namespace: metadata?.namespace,\n };\n }\n\n /**\n * Split content into frontmatter and body\n */\n private parseFrontmatterAndBody(content: string): { frontmatter: string; body: string } {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---\\n?([\\s\\S]*)$/);\n if (match) {\n return { frontmatter: match[1], body: match[2] };\n }\n return { frontmatter: '', body: content };\n }\n\n\n /**\n * Extract a single-line YAML field\n */\n private extractYamlField(yaml: string, field: string): string | null {\n const match = yaml.match(new RegExp(`^${field}:\\\\s*(.+)$`, 'm'));\n return match ? match[1].trim() : null;\n }\n\n /**\n * Extract a multiline YAML field (using |)\n */\n private extractYamlMultiline(yaml: string, field: string): string | null {\n const match = yaml.match(new RegExp(`^${field}:\\\\s*\\\\|\\\\n((?:\\\\s{2}.+\\\\n?)+)`, 'm'));\n if (match) {\n return match[1]\n .split('\\n')\n .map((line) => line.replace(/^\\s{2}/, ''))\n .join('\\n')\n .trim();\n }\n // Fallback to single line\n return this.extractYamlField(yaml, field);\n }\n\n /**\n * Extract a YAML list\n */\n private extractYamlList(yaml: string, field: string): string[] {\n const match = yaml.match(new RegExp(`^${field}:\\\\n((?:\\\\s+-\\\\s+.+\\\\n?)+)`, 'm'));\n if (match) {\n return match[1]\n .split('\\n')\n .map((line) => line.replace(/^\\s+-\\s+/, '').trim())\n .filter((line) => line.length > 0);\n }\n return [];\n }\n\n\n // ==========================================================================\n // Version Management\n // ==========================================================================\n\n /**\n * Save a version snapshot\n */\n private async saveVersionSnapshot(skill: Skill): Promise<void> {\n const versionDir = path.join(this.versionsDir, skill.id);\n await fs.mkdir(versionDir, { recursive: true });\n\n const versionFile = path.join(versionDir, `${skill.version}.json`);\n const versionData: SkillVersion = {\n skillId: skill.id,\n version: skill.version,\n skill,\n changelog: '', // Could be enhanced to track changes\n createdAt: new Date(),\n contentHash: this.hashContent(skill),\n };\n\n await fs.writeFile(versionFile, JSON.stringify(versionData, null, 2), 'utf-8');\n }\n\n /**\n * Get a specific version of a skill\n */\n private async getVersionedSkill(id: string, version: string): Promise<Skill | null> {\n const versionFile = path.join(this.versionsDir, id, `${version}.json`);\n\n try {\n const content = await fs.readFile(versionFile, 'utf-8');\n const versionData = JSON.parse(content) as SkillVersion;\n\n // Reconstruct dates\n const skill = versionData.skill;\n skill.createdAt = new Date(skill.createdAt);\n skill.updatedAt = new Date(skill.updatedAt);\n\n return skill;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Delete a specific version\n */\n private async deleteVersion(id: string, version: string): Promise<boolean> {\n const versionFile = path.join(this.versionsDir, id, `${version}.json`);\n\n try {\n await fs.unlink(versionFile);\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return false;\n }\n throw error;\n }\n }\n\n // ==========================================================================\n // Metadata\n // ==========================================================================\n\n /**\n * Create metadata for a skill\n */\n private createMetadata(skill: Skill): SkillTreeMetadata {\n return {\n source: skill.source,\n installedAt: new Date().toISOString(),\n lineage: {\n rootId: skill.id,\n parentVersion: skill.parentVersion,\n derivedFrom: skill.derivedFrom,\n },\n upstream: skill.upstream,\n namespace: skill.namespace,\n };\n }\n\n /**\n * Load metadata for a skill directory\n */\n private async loadMetadata(skillDir: string): Promise<SkillTreeMetadata | null> {\n const metadataPath = path.join(skillDir, '.skilltree.json');\n\n try {\n const content = await fs.readFile(metadataPath, 'utf-8');\n return JSON.parse(content) as SkillTreeMetadata;\n } catch {\n return null;\n }\n }\n\n /**\n * Save metadata for a skill directory\n */\n private async saveMetadata(skillDir: string, metadata: SkillTreeMetadata): Promise<void> {\n const metadataPath = path.join(skillDir, '.skilltree.json');\n await fs.writeFile(metadataPath, JSON.stringify(metadata, null, 2), 'utf-8');\n }\n\n // ==========================================================================\n // Utilities\n // ==========================================================================\n\n /**\n * Compare semantic versions\n */\n private compareVersions(a: string, b: string): number {\n const partsA = a.split('.').map(Number);\n const partsB = b.split('.').map(Number);\n\n for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {\n const numA = partsA[i] || 0;\n const numB = partsB[i] || 0;\n if (numA !== numB) return numA - numB;\n }\n return 0;\n }\n\n /**\n * Generate content hash\n */\n private hashContent(skill: Skill): string {\n const content = JSON.stringify({\n instructions: skill.instructions,\n });\n let hash = 0;\n for (let i = 0; i < content.length; i++) {\n const char = content.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(16);\n }\n\n // ==========================================================================\n // Fork Tracking\n // ==========================================================================\n\n async recordFork(sourceSkillId: string, fork: SkillFork): Promise<void> {\n this.ensureInitialized();\n\n const discovered = await discoverSkills(this.config.basePath);\n const location = discovered.find(d => d.id === sourceSkillId);\n if (!location) return;\n\n const metadata = await this.loadMetadata(location.directory);\n if (!metadata) return;\n\n if (!metadata.lineage) {\n metadata.lineage = { rootId: sourceSkillId };\n }\n if (!metadata.lineage.forks) {\n metadata.lineage.forks = [];\n }\n\n // Avoid duplicates\n const exists = metadata.lineage.forks.some(\n (f) => f.forkedSkillId === fork.forkedSkillId\n );\n if (!exists) {\n metadata.lineage.forks.push(fork);\n await this.saveMetadata(location.directory, metadata);\n }\n }\n}\n","/**\n * Skill lineage tracking\n * Tracks the evolution and relationships between skills\n */\n\nimport type {\n Skill,\n SkillVersion,\n SkillLineage,\n SkillFork,\n StorageAdapter,\n} from '../types.js';\nimport { hasForkSupport } from '../types.js';\nimport {\n bumpVersion,\n compareVersions,\n getLatestVersion,\n inferBumpType,\n type BumpType,\n type VersionChanges,\n} from './semver.js';\n\n/**\n * Options for creating a new version\n */\nexport interface NewVersionOptions {\n /** Type of version bump (auto-inferred if not provided) */\n bumpType?: BumpType;\n /** Changelog entry for this version */\n changelog?: string;\n /** Changes for auto-inferring bump type */\n changes?: VersionChanges;\n}\n\n/**\n * Options for rolling back a skill\n */\nexport interface RollbackOptions {\n /** Why the rollback is being performed */\n reason?: string;\n /** Custom changelog entry (auto-generated if not provided) */\n changelog?: string;\n}\n\n/**\n * Options for forking a skill\n */\nexport interface ForkOptions {\n /** New skill ID for the fork */\n newId: string;\n /** New name for the forked skill */\n newName?: string;\n /** Reason for forking */\n reason: string;\n /** Version to fork from (defaults to latest) */\n fromVersion?: string;\n}\n\n/**\n * Lineage tracker for managing skill versions and forks\n */\nexport class LineageTracker {\n constructor(private storage: StorageAdapter) {}\n\n /**\n * Create a new version of a skill\n */\n async createVersion(\n skillId: string,\n updates: Partial<Skill>,\n options: NewVersionOptions = {}\n ): Promise<Skill> {\n // Get current skill\n const currentSkill = await this.storage.getSkill(skillId);\n if (!currentSkill) {\n throw new Error(`Skill not found: ${skillId}`);\n }\n\n // Determine new version\n const bumpType = options.bumpType || inferBumpType(options.changes || {});\n const newVersion = bumpVersion(currentSkill.version, bumpType);\n\n // Create updated skill\n const updatedSkill: Skill = {\n ...currentSkill,\n ...updates,\n id: skillId,\n version: newVersion,\n parentVersion: currentSkill.version,\n updatedAt: new Date(),\n };\n\n // Save the new version\n await this.storage.saveSkill(updatedSkill);\n\n return updatedSkill;\n }\n\n /**\n * Fork a skill to create a new, related skill\n */\n async forkSkill(skillId: string, options: ForkOptions): Promise<Skill> {\n // Get source skill\n const sourceSkill = await this.storage.getSkill(skillId, options.fromVersion);\n if (!sourceSkill) {\n throw new Error(`Skill not found: ${skillId}${options.fromVersion ? `@${options.fromVersion}` : ''}`);\n }\n\n // Create forked skill\n const forkedSkill: Skill = {\n ...sourceSkill,\n id: options.newId,\n name: options.newName || `${sourceSkill.name}-fork`,\n version: '1.0.0',\n parentVersion: undefined,\n derivedFrom: [skillId],\n createdAt: new Date(),\n updatedAt: new Date(),\n status: 'draft',\n metrics: {\n usageCount: 0,\n successRate: 0,\n feedbackScores: [],\n },\n source: {\n type: 'composed',\n importedAt: new Date(),\n },\n };\n\n // Save forked skill\n await this.storage.saveSkill(forkedSkill);\n\n // Record the fork in the source skill's lineage\n const fork: SkillFork = {\n forkedSkillId: options.newId,\n fromVersion: sourceSkill.version,\n reason: options.reason,\n forkedAt: new Date(),\n };\n\n if (hasForkSupport(this.storage)) {\n await this.storage.recordFork(skillId, fork);\n }\n\n // Always persist fork reference on the source skill itself\n // This ensures fork tracking works regardless of storage backend\n const existingForks = sourceSkill.forks || [];\n if (!existingForks.includes(options.newId)) {\n sourceSkill.forks = [...existingForks, options.newId];\n await this.storage.saveSkill(sourceSkill);\n }\n\n return forkedSkill;\n }\n\n /**\n * Merge changes from one skill into another\n */\n async mergeSkill(\n targetId: string,\n sourceId: string,\n options: {\n /** Fields to merge */\n fields?: (keyof Skill)[];\n /** Strategy for conflicts */\n conflictStrategy?: 'source' | 'target' | 'combine';\n /** Changelog entry */\n changelog?: string;\n } = {}\n ): Promise<Skill> {\n const targetSkill = await this.storage.getSkill(targetId);\n const sourceSkill = await this.storage.getSkill(sourceId);\n\n if (!targetSkill) throw new Error(`Target skill not found: ${targetId}`);\n if (!sourceSkill) throw new Error(`Source skill not found: ${sourceId}`);\n\n const fields = options.fields || [\n 'instructions',\n ];\n const strategy = options.conflictStrategy || 'combine';\n\n // Build merged updates\n const updates: Partial<Skill> = {};\n\n for (const field of fields) {\n if (field === 'tags') {\n updates.tags = [...new Set([...targetSkill.tags, ...sourceSkill.tags])];\n } else if (field === 'instructions') {\n updates.instructions = this.mergeText(\n targetSkill.instructions || '',\n sourceSkill.instructions || '',\n strategy\n );\n }\n }\n\n // Track derivation\n updates.derivedFrom = [\n ...(targetSkill.derivedFrom || []),\n sourceId,\n ].filter((id, i, arr) => arr.indexOf(id) === i);\n\n // Create new version with merged content\n return this.createVersion(targetId, updates, {\n bumpType: 'minor',\n changelog: options.changelog || `Merged from ${sourceId}`,\n changes: { newFeatures: [`Merged content from ${sourceId}`] },\n });\n }\n\n /**\n * Get the full lineage tree for a skill\n */\n async getLineageTree(skillId: string): Promise<LineageTree | null> {\n const lineage = await this.storage.getLineage(skillId);\n if (!lineage) return null;\n\n const tree: LineageTree = {\n skillId,\n versions: lineage.versions,\n forks: [],\n ancestors: [],\n };\n\n // Get fork information\n for (const fork of lineage.forks) {\n const forkedSkill = await this.storage.getSkill(fork.forkedSkillId);\n if (forkedSkill) {\n tree.forks.push({\n skill: forkedSkill,\n fork,\n });\n }\n }\n\n // Get ancestor information (skills this was derived from)\n const currentSkill = await this.storage.getSkill(skillId);\n if (currentSkill?.derivedFrom) {\n for (const ancestorId of currentSkill.derivedFrom) {\n const ancestor = await this.storage.getSkill(ancestorId);\n if (ancestor) {\n tree.ancestors.push(ancestor);\n }\n }\n }\n\n return tree;\n }\n\n /**\n * Rollback a skill to a previous version.\n * Creates a new version (patch bump) with the content of the target version.\n * The rollback is recorded in the skill's notes for auditability.\n */\n async rollback(\n skillId: string,\n toVersion: string,\n options?: RollbackOptions\n ): Promise<Skill> {\n const targetSkill = await this.storage.getSkill(skillId, toVersion);\n if (!targetSkill) {\n throw new Error(`Version not found: ${skillId}@${toVersion}`);\n }\n\n const currentSkill = await this.storage.getSkill(skillId);\n if (!currentSkill) {\n throw new Error(`Skill not found: ${skillId}`);\n }\n\n // Create new version that's a copy of the old version\n const newVersion = bumpVersion(currentSkill.version, 'patch');\n\n // Build rollback changelog entry\n const rollbackReason = options?.reason || 'No reason specified';\n const changelogEntry =\n options?.changelog ||\n `Rollback from ${currentSkill.version} to ${toVersion}: ${rollbackReason}`;\n\n // Append rollback note to instructions for auditability\n const rollbackNote = `\\n\\n[rollback] ${currentSkill.version} → ${toVersion} (${rollbackReason})`;\n const instructions = targetSkill.instructions\n ? `${targetSkill.instructions}${rollbackNote}`\n : rollbackNote.trim();\n\n const rolledBackSkill: Skill = {\n ...targetSkill,\n version: newVersion,\n parentVersion: currentSkill.version,\n instructions,\n updatedAt: new Date(),\n };\n\n await this.storage.saveSkill(rolledBackSkill);\n return rolledBackSkill;\n }\n\n /**\n * Compare two versions of a skill\n */\n async compareVersions(\n skillId: string,\n versionA: string,\n versionB: string\n ): Promise<VersionDiff> {\n const skillA = await this.storage.getSkill(skillId, versionA);\n const skillB = await this.storage.getSkill(skillId, versionB);\n\n if (!skillA) throw new Error(`Version not found: ${skillId}@${versionA}`);\n if (!skillB) throw new Error(`Version not found: ${skillId}@${versionB}`);\n\n return {\n versionA,\n versionB,\n changes: this.diffSkills(skillA, skillB),\n };\n }\n\n /**\n * Get suggested next version based on changes\n */\n async suggestNextVersion(skillId: string, changes: VersionChanges): Promise<string> {\n const skill = await this.storage.getSkill(skillId);\n if (!skill) throw new Error(`Skill not found: ${skillId}`);\n\n const bumpType = inferBumpType(changes);\n return bumpVersion(skill.version, bumpType);\n }\n\n // ==========================================================================\n // Private helpers\n // ==========================================================================\n\n private mergeText(\n target: string,\n source: string,\n strategy: 'source' | 'target' | 'combine'\n ): string {\n switch (strategy) {\n case 'source':\n return source;\n case 'target':\n return target;\n case 'combine':\n if (!target) return source;\n if (!source) return target;\n return `${target}\\n\\n---\\n\\n${source}`;\n }\n }\n\n private diffSkills(skillA: Skill, skillB: Skill): SkillDiffChanges {\n const changes: SkillDiffChanges = {\n modified: [],\n added: [],\n removed: [],\n };\n\n // Compare text fields\n const textFields: (keyof Skill)[] = [\n 'name',\n 'description',\n 'instructions',\n ];\n\n for (const field of textFields) {\n const valueA = skillA[field];\n const valueB = skillB[field];\n if (valueA !== valueB) {\n changes.modified.push({\n field,\n oldValue: valueA as string,\n newValue: valueB as string,\n });\n }\n }\n\n // Compare tags\n const tagsA = new Set(skillA.tags);\n const tagsB = new Set(skillB.tags);\n\n for (const tag of tagsB) {\n if (!tagsA.has(tag)) {\n changes.added.push({ type: 'tag', value: tag });\n }\n }\n for (const tag of tagsA) {\n if (!tagsB.has(tag)) {\n changes.removed.push({ type: 'tag', value: tag });\n }\n }\n\n return changes;\n }\n}\n\n/**\n * Full lineage tree for a skill\n */\nexport interface LineageTree {\n skillId: string;\n versions: SkillVersion[];\n forks: Array<{\n skill: Skill;\n fork: SkillFork;\n }>;\n ancestors: Skill[];\n}\n\n/**\n * Diff between two versions\n */\nexport interface VersionDiff {\n versionA: string;\n versionB: string;\n changes: SkillDiffChanges;\n}\n\n/**\n * Detailed changes between skills\n */\nexport interface SkillDiffChanges {\n modified: Array<{\n field: string;\n oldValue: string;\n newValue: string;\n }>;\n added: Array<{\n type: string;\n value: string;\n }>;\n removed: Array<{\n type: string;\n value: string;\n }>;\n}\n","/**\n * Skill Merging System\n * Advanced merge capabilities with conflict detection, preview, and smart strategies\n */\n\nimport type { Skill, StorageAdapter } from '../types.js';\nimport { bumpVersion, type BumpType } from './semver.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Strategy for handling merge conflicts\n */\nexport type MergeStrategy =\n | 'source' // Use source value\n | 'target' // Use target value\n | 'combine' // Combine both values\n | 'newest' // Use value from newer skill\n | 'longest' // Use longer content\n | 'union' // For arrays, combine unique items\n | 'intersection'; // For arrays, keep only common items\n\n/**\n * Configuration for merging skills\n */\nexport interface MergeConfig {\n /** Default strategy for text fields */\n textStrategy?: MergeStrategy;\n /** Strategy for tags */\n tagStrategy?: MergeStrategy;\n /** Fields to include in merge (defaults to all) */\n includeFields?: (keyof Skill)[];\n /** Fields to exclude from merge */\n excludeFields?: (keyof Skill)[];\n /** Version bump type (auto-inferred if not specified) */\n bumpType?: BumpType;\n /** Changelog entry */\n changelog?: string;\n}\n\n/**\n * A single merge conflict\n */\nexport interface MergeConflict {\n /** Field with conflict */\n field: keyof Skill;\n /** Value in target skill */\n targetValue: unknown;\n /** Value in source skill */\n sourceValue: unknown;\n /** Suggested resolution */\n suggestion: 'source' | 'target' | 'combine';\n /** Reason for suggestion */\n reason: string;\n}\n\n/**\n * Resolution for a conflict\n */\nexport interface ConflictResolution {\n /** Field being resolved */\n field: keyof Skill;\n /** Resolution strategy */\n resolution: MergeStrategy | 'custom';\n /** Custom value (when resolution is 'custom') */\n customValue?: unknown;\n}\n\n/**\n * Preview of merge operation\n */\nexport interface MergePreview {\n /** Target skill ID */\n targetId: string;\n /** Source skill ID */\n sourceId: string;\n /** Detected conflicts */\n conflicts: MergeConflict[];\n /** Fields that will be modified */\n modifications: Array<{\n field: keyof Skill;\n currentValue: unknown;\n newValue: unknown;\n strategy: MergeStrategy;\n }>;\n /** Resulting skill preview */\n previewSkill: Partial<Skill>;\n /** Suggested version */\n suggestedVersion: string;\n /** Whether any conflicts need resolution */\n hasConflicts: boolean;\n}\n\n/**\n * Result of merge operation\n */\nexport interface MergeResult {\n /** Successfully merged skill */\n skill: Skill;\n /** Conflicts that were resolved */\n resolvedConflicts: MergeConflict[];\n /** Strategy used for each field */\n appliedStrategies: Map<keyof Skill, MergeStrategy>;\n /** Changelog generated */\n changelog: string;\n}\n\n/**\n * Suggestion for merging similar skills\n */\nexport interface MergeSuggestion {\n /** Source skill ID */\n sourceId: string;\n /** Target skill ID */\n targetId: string;\n /** Similarity score */\n similarity: number;\n /** Reason for suggestion */\n reason: string;\n /** Fields that could benefit from merge */\n beneficialFields: (keyof Skill)[];\n /** Potential conflicts */\n potentialConflicts: string[];\n}\n\n// =============================================================================\n// Default Configuration\n// =============================================================================\n\nconst DEFAULT_MERGE_CONFIG: Required<Omit<MergeConfig, 'changelog'>> & { changelog?: string } = {\n textStrategy: 'combine',\n tagStrategy: 'union',\n includeFields: ['instructions', 'tags'],\n excludeFields: ['id', 'version', 'createdAt', 'updatedAt', 'metrics', 'source'],\n bumpType: 'minor',\n};\n\n// =============================================================================\n// SkillMerger Class\n// =============================================================================\n\n/**\n * Advanced skill merging with conflict detection and resolution\n */\nexport class SkillMerger {\n private config: typeof DEFAULT_MERGE_CONFIG;\n\n constructor(\n private storage: StorageAdapter,\n config: MergeConfig = {}\n ) {\n this.config = {\n ...DEFAULT_MERGE_CONFIG,\n ...config,\n };\n }\n\n /**\n * Preview a merge without applying it\n */\n async preview(\n targetId: string,\n sourceId: string,\n config: MergeConfig = {}\n ): Promise<MergePreview> {\n const mergeConfig = { ...this.config, ...config };\n\n const targetSkill = await this.storage.getSkill(targetId);\n const sourceSkill = await this.storage.getSkill(sourceId);\n\n if (!targetSkill) throw new Error(`Target skill not found: ${targetId}`);\n if (!sourceSkill) throw new Error(`Source skill not found: ${sourceId}`);\n\n // Detect conflicts\n const conflicts = this.detectConflicts(targetSkill, sourceSkill, mergeConfig);\n\n // Build modifications preview\n const modifications = this.buildModifications(targetSkill, sourceSkill, mergeConfig);\n\n // Build preview skill\n const previewSkill = this.buildMergedSkill(\n targetSkill,\n sourceSkill,\n mergeConfig,\n new Map()\n );\n\n return {\n targetId,\n sourceId,\n conflicts,\n modifications,\n previewSkill,\n suggestedVersion: bumpVersion(targetSkill.version, mergeConfig.bumpType || 'minor'),\n hasConflicts: conflicts.length > 0,\n };\n }\n\n /**\n * Detect conflicts between two skills\n */\n detectConflicts(\n target: Skill,\n source: Skill,\n config: MergeConfig = {}\n ): MergeConflict[] {\n const mergeConfig = { ...this.config, ...config };\n const conflicts: MergeConflict[] = [];\n const fieldsToCheck = this.getFieldsToMerge(mergeConfig);\n\n for (const field of fieldsToCheck) {\n const targetValue = target[field];\n const sourceValue = source[field];\n\n if (this.valuesConflict(targetValue, sourceValue, field)) {\n conflicts.push({\n field,\n targetValue,\n sourceValue,\n ...this.suggestResolution(field, targetValue, sourceValue, target, source),\n });\n }\n }\n\n return conflicts;\n }\n\n /**\n * Merge skills with optional conflict resolutions\n */\n async merge(\n targetId: string,\n sourceId: string,\n options: {\n config?: MergeConfig;\n resolutions?: ConflictResolution[];\n } = {}\n ): Promise<MergeResult> {\n const mergeConfig = { ...this.config, ...options.config };\n\n const targetSkill = await this.storage.getSkill(targetId);\n const sourceSkill = await this.storage.getSkill(sourceId);\n\n if (!targetSkill) throw new Error(`Target skill not found: ${targetId}`);\n if (!sourceSkill) throw new Error(`Source skill not found: ${sourceId}`);\n\n // Build resolution map\n const resolutionMap = new Map<keyof Skill, ConflictResolution>();\n for (const resolution of options.resolutions || []) {\n resolutionMap.set(resolution.field, resolution);\n }\n\n // Detect and handle conflicts\n const conflicts = this.detectConflicts(targetSkill, sourceSkill, mergeConfig);\n const resolvedConflicts: MergeConflict[] = [];\n const appliedStrategies = new Map<keyof Skill, MergeStrategy>();\n\n // Check for unresolved conflicts\n for (const conflict of conflicts) {\n const resolution = resolutionMap.get(conflict.field);\n if (resolution) {\n resolvedConflicts.push(conflict);\n if (resolution.resolution !== 'custom') {\n appliedStrategies.set(conflict.field, resolution.resolution);\n }\n }\n }\n\n // Build merged skill\n const mergedUpdates = this.buildMergedSkill(\n targetSkill,\n sourceSkill,\n mergeConfig,\n resolutionMap\n );\n\n // Track derivation\n mergedUpdates.derivedFrom = [\n ...(targetSkill.derivedFrom || []),\n sourceId,\n ].filter((id, i, arr) => arr.indexOf(id) === i);\n\n // Create new version\n const newVersion = bumpVersion(\n targetSkill.version,\n mergeConfig.bumpType || 'minor'\n );\n\n const mergedSkill: Skill = {\n ...targetSkill,\n ...mergedUpdates,\n version: newVersion,\n parentVersion: targetSkill.version,\n updatedAt: new Date(),\n };\n\n // Save the merged skill\n await this.storage.saveSkill(mergedSkill);\n\n const changelog =\n mergeConfig.changelog || this.generateChangelog(targetId, sourceId, resolvedConflicts);\n\n return {\n skill: mergedSkill,\n resolvedConflicts,\n appliedStrategies,\n changelog,\n };\n }\n\n /**\n * Suggest skills that could benefit from merging\n */\n async suggestMerges(\n skills: Skill[],\n options: {\n minSimilarity?: number;\n maxSuggestions?: number;\n } = {}\n ): Promise<MergeSuggestion[]> {\n const minSimilarity = options.minSimilarity ?? 0.3;\n const maxSuggestions = options.maxSuggestions ?? 10;\n const suggestions: MergeSuggestion[] = [];\n\n // Compare all pairs\n for (let i = 0; i < skills.length; i++) {\n for (let j = i + 1; j < skills.length; j++) {\n const skillA = skills[i];\n const skillB = skills[j];\n\n // Skip if one is derived from the other (already related)\n if (\n skillA.derivedFrom?.includes(skillB.id) ||\n skillB.derivedFrom?.includes(skillA.id)\n ) {\n continue;\n }\n\n const similarity = this.calculateSimilarity(skillA, skillB);\n if (similarity >= minSimilarity) {\n suggestions.push(this.buildMergeSuggestion(skillA, skillB, similarity));\n }\n }\n }\n\n // Sort by similarity and limit\n return suggestions\n .sort((a, b) => b.similarity - a.similarity)\n .slice(0, maxSuggestions);\n }\n\n /**\n * Update merge configuration\n */\n setConfig(config: MergeConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n // ===========================================================================\n // Private Helpers\n // ===========================================================================\n\n private getFieldsToMerge(config: typeof DEFAULT_MERGE_CONFIG): (keyof Skill)[] {\n const include = new Set(config.includeFields);\n const exclude = new Set(config.excludeFields);\n return [...include].filter((f) => !exclude.has(f));\n }\n\n private valuesConflict(\n targetValue: unknown,\n sourceValue: unknown,\n field: keyof Skill\n ): boolean {\n // No conflict if either is empty\n if (targetValue === undefined || targetValue === null) return false;\n if (sourceValue === undefined || sourceValue === null) return false;\n\n // Arrays: conflict if both have content but differ\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n if (targetValue.length === 0 || sourceValue.length === 0) return false;\n // Check if they have different items\n const targetSet = new Set(targetValue.map((v) => JSON.stringify(v)));\n const sourceSet = new Set(sourceValue.map((v) => JSON.stringify(v)));\n // Conflict if source has items not in target\n for (const item of sourceSet) {\n if (!targetSet.has(item)) return true;\n }\n return false;\n }\n\n // Strings: conflict if both have content and differ\n if (typeof targetValue === 'string' && typeof sourceValue === 'string') {\n if (!targetValue.trim() || !sourceValue.trim()) return false;\n return targetValue !== sourceValue;\n }\n\n // Objects: conflict if JSON differs\n return JSON.stringify(targetValue) !== JSON.stringify(sourceValue);\n }\n\n private suggestResolution(\n field: keyof Skill,\n targetValue: unknown,\n sourceValue: unknown,\n target: Skill,\n source: Skill\n ): { suggestion: 'source' | 'target' | 'combine'; reason: string } {\n // For arrays, suggest combining\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n return {\n suggestion: 'combine',\n reason: 'Both skills have unique items that could be merged',\n };\n }\n\n // For text fields, compare lengths and dates\n if (typeof targetValue === 'string' && typeof sourceValue === 'string') {\n // Prefer longer content\n if (sourceValue.length > targetValue.length * 1.5) {\n return {\n suggestion: 'source',\n reason: 'Source has significantly more detailed content',\n };\n }\n if (targetValue.length > sourceValue.length * 1.5) {\n return {\n suggestion: 'target',\n reason: 'Target has significantly more detailed content',\n };\n }\n\n // Prefer newer\n const targetDate = target.updatedAt?.getTime() || 0;\n const sourceDate = source.updatedAt?.getTime() || 0;\n if (sourceDate > targetDate) {\n return {\n suggestion: 'source',\n reason: 'Source was more recently updated',\n };\n }\n if (targetDate > sourceDate) {\n return {\n suggestion: 'target',\n reason: 'Target was more recently updated',\n };\n }\n\n return {\n suggestion: 'combine',\n reason: 'Both values have comparable content',\n };\n }\n\n return {\n suggestion: 'target',\n reason: 'Defaulting to target value',\n };\n }\n\n private buildModifications(\n target: Skill,\n source: Skill,\n config: typeof DEFAULT_MERGE_CONFIG\n ): MergePreview['modifications'] {\n const modifications: MergePreview['modifications'] = [];\n const fields = this.getFieldsToMerge(config);\n\n for (const field of fields) {\n const currentValue = target[field];\n const sourceValue = source[field];\n\n if (sourceValue === undefined || sourceValue === null) continue;\n\n const strategy = this.getStrategyForField(field, config);\n const newValue = this.mergeField(field, currentValue, sourceValue, strategy);\n\n if (JSON.stringify(newValue) !== JSON.stringify(currentValue)) {\n modifications.push({\n field,\n currentValue,\n newValue,\n strategy,\n });\n }\n }\n\n return modifications;\n }\n\n private buildMergedSkill(\n target: Skill,\n source: Skill,\n config: typeof DEFAULT_MERGE_CONFIG,\n resolutions: Map<keyof Skill, ConflictResolution>\n ): Partial<Skill> {\n const updates: Partial<Skill> = {};\n const fields = this.getFieldsToMerge(config);\n\n for (const field of fields) {\n const targetValue = target[field];\n const sourceValue = source[field];\n\n // Check for custom resolution\n const resolution = resolutions.get(field);\n if (resolution?.resolution === 'custom' && resolution.customValue !== undefined) {\n (updates as Record<string, unknown>)[field] = resolution.customValue;\n continue;\n }\n\n // Get strategy (from resolution or config)\n const strategy =\n resolution?.resolution !== 'custom'\n ? resolution?.resolution || this.getStrategyForField(field, config)\n : this.getStrategyForField(field, config);\n\n (updates as Record<string, unknown>)[field] = this.mergeField(\n field,\n targetValue,\n sourceValue,\n strategy\n );\n }\n\n return updates;\n }\n\n private getStrategyForField(\n field: keyof Skill,\n config: typeof DEFAULT_MERGE_CONFIG\n ): MergeStrategy {\n switch (field) {\n case 'tags':\n return config.tagStrategy;\n default:\n return config.textStrategy;\n }\n }\n\n private mergeField(\n field: keyof Skill,\n targetValue: unknown,\n sourceValue: unknown,\n strategy: MergeStrategy\n ): unknown {\n // Handle null/undefined\n if (targetValue === undefined || targetValue === null) return sourceValue;\n if (sourceValue === undefined || sourceValue === null) return targetValue;\n\n // Handle arrays (triggerConditions, examples, tags)\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n return this.mergeArrays(field, targetValue, sourceValue, strategy);\n }\n\n // Handle strings\n if (typeof targetValue === 'string' && typeof sourceValue === 'string') {\n return this.mergeStrings(targetValue, sourceValue, strategy);\n }\n\n // Default: use strategy\n switch (strategy) {\n case 'source':\n return sourceValue;\n case 'target':\n return targetValue;\n default:\n return targetValue;\n }\n }\n\n private mergeArrays(\n field: keyof Skill,\n target: unknown[],\n source: unknown[],\n strategy: MergeStrategy\n ): unknown[] {\n switch (strategy) {\n case 'source':\n return source;\n case 'target':\n return target;\n case 'union':\n case 'combine': {\n // Deduplicate based on field type\n if (field === 'tags') {\n return [...new Set([...(target as string[]), ...(source as string[])])];\n }\n // Generic array union\n const seen = new Set(target.map((v) => JSON.stringify(v)));\n const result = [...target];\n for (const item of source) {\n const key = JSON.stringify(item);\n if (!seen.has(key)) {\n result.push(item);\n seen.add(key);\n }\n }\n return result;\n }\n case 'intersection': {\n const sourceSet = new Set(source.map((v) => JSON.stringify(v)));\n return target.filter((v) => sourceSet.has(JSON.stringify(v)));\n }\n default:\n return target;\n }\n }\n\n private mergeStrings(\n target: string,\n source: string,\n strategy: MergeStrategy\n ): string {\n switch (strategy) {\n case 'source':\n return source;\n case 'target':\n return target;\n case 'combine':\n if (!target.trim()) return source;\n if (!source.trim()) return target;\n return `${target}\\n\\n---\\n\\n${source}`;\n case 'longest':\n return target.length >= source.length ? target : source;\n default:\n return target;\n }\n }\n\n private calculateSimilarity(skillA: Skill, skillB: Skill): number {\n let score = 0;\n let weights = 0;\n\n // Tag overlap (weight: 3)\n const tagsA = new Set(skillA.tags);\n const tagsB = new Set(skillB.tags);\n const tagUnion = new Set([...tagsA, ...tagsB]);\n const tagIntersection = [...tagsA].filter((t) => tagsB.has(t));\n if (tagUnion.size > 0) {\n score += (tagIntersection.length / tagUnion.size) * 3;\n weights += 3;\n }\n\n // Instructions similarity via word overlap (weight: 4)\n const wordsA = new Set(\n (skillA.instructions || '').toLowerCase().split(/\\s+/).filter((w) => w.length > 3)\n );\n const wordsB = new Set(\n (skillB.instructions || '').toLowerCase().split(/\\s+/).filter((w) => w.length > 3)\n );\n const wordUnion = new Set([...wordsA, ...wordsB]);\n const wordIntersection = [...wordsA].filter((w) => wordsB.has(w));\n if (wordUnion.size > 0) {\n score += (wordIntersection.length / wordUnion.size) * 4;\n weights += 4;\n }\n\n return weights > 0 ? score / weights : 0;\n }\n\n private buildMergeSuggestion(\n skillA: Skill,\n skillB: Skill,\n similarity: number\n ): MergeSuggestion {\n const beneficialFields: (keyof Skill)[] = [];\n const potentialConflicts: string[] = [];\n\n // Check which fields could benefit from merging\n if (skillA.instructions !== skillB.instructions) {\n beneficialFields.push('instructions');\n }\n if (skillA.tags.length !== skillB.tags.length) {\n beneficialFields.push('tags');\n }\n\n // Check for potential conflicts\n if (skillA.instructions && skillB.instructions && skillA.instructions !== skillB.instructions) {\n potentialConflicts.push('Different instructions - manual review needed');\n }\n\n // Determine merge direction (newer/more complete should be target)\n const aScore = this.calculateCompleteness(skillA);\n const bScore = this.calculateCompleteness(skillB);\n const [source, target] = aScore < bScore ? [skillA, skillB] : [skillB, skillA];\n\n // Build reason\n const reasons: string[] = [];\n const tagOverlap = skillA.tags.filter((t) => skillB.tags.includes(t));\n if (tagOverlap.length > 0) {\n reasons.push(`Share tags: ${tagOverlap.join(', ')}`);\n }\n if (beneficialFields.includes('instructions')) {\n reasons.push('Could combine instructions');\n }\n\n return {\n sourceId: source.id,\n targetId: target.id,\n similarity,\n reason: reasons.join('; ') || 'Similar content detected',\n beneficialFields,\n potentialConflicts,\n };\n }\n\n private calculateCompleteness(skill: Skill): number {\n let score = 0;\n if (skill.instructions) score += 3;\n score += skill.tags.length * 0.2;\n return score;\n }\n\n private generateChangelog(\n targetId: string,\n sourceId: string,\n resolvedConflicts: MergeConflict[]\n ): string {\n const lines = [`Merged from ${sourceId}`];\n\n if (resolvedConflicts.length > 0) {\n lines.push('');\n lines.push('Resolved conflicts:');\n for (const conflict of resolvedConflicts) {\n lines.push(`- ${conflict.field}: ${conflict.reason}`);\n }\n }\n\n return lines.join('\\n');\n }\n}\n\n/**\n * Create a skill merger instance\n */\nexport function createSkillMerger(\n storage: StorageAdapter,\n config?: MergeConfig\n): SkillMerger {\n return new SkillMerger(storage, config);\n}\n","/**\n * Hook Registry for managing and executing hooks\n */\n\nimport { randomUUID } from 'crypto';\nimport type {\n HookEvent,\n HookHandler,\n HookPriority,\n HookContext,\n HookResult,\n RegisteredHook,\n} from './types.js';\n\n/**\n * Options for registering a hook\n */\nexport interface RegisterHookOptions {\n /** Hook name for display */\n name: string;\n /** Events to listen for */\n events: HookEvent | HookEvent[];\n /** Handler function */\n handler: HookHandler;\n /** Execution priority (default: 'normal') */\n priority?: HookPriority;\n /** Whether the hook is enabled (default: true) */\n enabled?: boolean;\n /** Optional filter function */\n filter?: (context: HookContext) => boolean;\n}\n\n/**\n * Result of executing hooks for an event\n */\nexport interface HookExecutionResult {\n /** Event that was triggered */\n event: HookEvent;\n /** Number of hooks executed */\n executedCount: number;\n /** Number of hooks that passed */\n passedCount: number;\n /** Whether all hooks passed */\n allPassed: boolean;\n /** Whether execution was aborted */\n aborted: boolean;\n /** Results from each hook */\n results: Array<{\n hookId: string;\n hookName: string;\n result: HookResult;\n duration: number;\n }>;\n /** Total execution time (ms) */\n totalDuration: number;\n}\n\n/**\n * Priority order for hook execution\n */\nconst PRIORITY_ORDER: Record<HookPriority, number> = {\n high: 0,\n normal: 1,\n low: 2,\n};\n\n/**\n * Registry for managing hooks\n */\nexport class HookRegistry {\n private hooks: Map<string, RegisteredHook> = new Map();\n private eventIndex: Map<HookEvent, Set<string>> = new Map();\n\n /**\n * Register a new hook\n */\n register(options: RegisterHookOptions): string {\n const id = randomUUID();\n const events = Array.isArray(options.events) ? options.events : [options.events];\n\n const hook: RegisteredHook = {\n id,\n name: options.name,\n events,\n handler: options.handler,\n priority: options.priority || 'normal',\n enabled: options.enabled !== false,\n filter: options.filter,\n };\n\n this.hooks.set(id, hook);\n\n // Update event index\n for (const event of events) {\n if (!this.eventIndex.has(event)) {\n this.eventIndex.set(event, new Set());\n }\n this.eventIndex.get(event)!.add(id);\n }\n\n return id;\n }\n\n /**\n * Unregister a hook\n */\n unregister(hookId: string): boolean {\n const hook = this.hooks.get(hookId);\n if (!hook) return false;\n\n // Remove from event index\n for (const event of hook.events) {\n this.eventIndex.get(event)?.delete(hookId);\n }\n\n this.hooks.delete(hookId);\n return true;\n }\n\n /**\n * Enable a hook\n */\n enable(hookId: string): boolean {\n const hook = this.hooks.get(hookId);\n if (!hook) return false;\n hook.enabled = true;\n return true;\n }\n\n /**\n * Disable a hook\n */\n disable(hookId: string): boolean {\n const hook = this.hooks.get(hookId);\n if (!hook) return false;\n hook.enabled = false;\n return true;\n }\n\n /**\n * Get a hook by ID\n */\n get(hookId: string): RegisteredHook | undefined {\n return this.hooks.get(hookId);\n }\n\n /**\n * List all registered hooks\n */\n list(): RegisteredHook[] {\n return Array.from(this.hooks.values());\n }\n\n /**\n * List hooks for a specific event\n */\n listForEvent(event: HookEvent): RegisteredHook[] {\n const hookIds = this.eventIndex.get(event);\n if (!hookIds) return [];\n\n return Array.from(hookIds)\n .map((id) => this.hooks.get(id)!)\n .filter((hook) => hook.enabled)\n .sort((a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority]);\n }\n\n /**\n * Execute hooks for an event\n */\n async execute(\n event: HookEvent,\n context: Omit<HookContext, 'invocationId' | 'timestamp'>\n ): Promise<HookExecutionResult> {\n const startTime = Date.now();\n const hooks = this.listForEvent(event);\n const results: HookExecutionResult['results'] = [];\n\n let aborted = false;\n\n // Build full context\n const fullContext: HookContext = {\n ...context,\n invocationId: randomUUID(),\n timestamp: new Date(),\n } as HookContext;\n\n for (const hook of hooks) {\n if (aborted) break;\n\n // Check filter\n if (hook.filter && !hook.filter(fullContext)) {\n continue;\n }\n\n const hookStart = Date.now();\n let result: HookResult;\n\n try {\n result = await hook.handler(fullContext);\n } catch (error) {\n result = {\n continue: true,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n\n const duration = Date.now() - hookStart;\n results.push({\n hookId: hook.id,\n hookName: hook.name,\n result,\n duration,\n });\n\n if (!result.continue) {\n aborted = true;\n }\n }\n\n const totalDuration = Date.now() - startTime;\n const passedCount = results.filter((r) => r.result.continue && !r.result.error).length;\n\n return {\n event,\n executedCount: results.length,\n passedCount,\n allPassed: passedCount === results.length,\n aborted,\n results,\n totalDuration,\n };\n }\n\n /**\n * Execute hooks and allow modification of data (for 'before' hooks)\n */\n async executeWithTransform<T>(\n event: HookEvent,\n context: Omit<HookContext, 'invocationId' | 'timestamp'>,\n data: T\n ): Promise<{ result: HookExecutionResult; data: T }> {\n const executionResult = await this.execute(event, context);\n let transformedData = data;\n\n // Apply modifications from hooks in order\n for (const hookResult of executionResult.results) {\n if (hookResult.result.modified !== undefined) {\n transformedData = hookResult.result.modified as T;\n }\n }\n\n return { result: executionResult, data: transformedData };\n }\n\n /**\n * Clear all hooks\n */\n clear(): void {\n this.hooks.clear();\n this.eventIndex.clear();\n }\n\n /**\n * Get statistics about registered hooks\n */\n stats(): {\n totalHooks: number;\n enabledHooks: number;\n hooksByEvent: Record<string, number>;\n hooksByPriority: Record<HookPriority, number>;\n } {\n const hooks = Array.from(this.hooks.values());\n const hooksByEvent: Record<string, number> = {};\n const hooksByPriority: Record<HookPriority, number> = {\n high: 0,\n normal: 0,\n low: 0,\n };\n\n for (const hook of hooks) {\n hooksByPriority[hook.priority]++;\n for (const event of hook.events) {\n hooksByEvent[event] = (hooksByEvent[event] || 0) + 1;\n }\n }\n\n return {\n totalHooks: hooks.length,\n enabledHooks: hooks.filter((h) => h.enabled).length,\n hooksByEvent,\n hooksByPriority,\n };\n }\n}\n\n/**\n * Global hook registry instance\n */\nexport const hookRegistry = new HookRegistry();\n","/**\n * Materializer - Keeps agent-discoverable filesystem representations\n * in sync with the skill bank.\n *\n * Supports two modes:\n * - 'symlink': Creates symlinks from discovery paths into .skilltree/skills/\n * - 'copy': Copies skill directories to discovery paths\n *\n * Also auto-regenerates AGENTS.md on skill changes with marker-based sections.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { StorageAdapter, MaterializationConfig } from '../types.js';\nimport type { AgentsGeneratorConfig } from '../agents/types.js';\n\nconst SKILLTREE_MARKER_START = '<!-- SKILLTREE_START -->';\nconst SKILLTREE_MARKER_END = '<!-- SKILLTREE_END -->';\n\nexport class Materializer {\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private pendingRegen = false;\n private regenerating = false;\n private watcher: fs.FSWatcher | null = null;\n private watchDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n private storage: StorageAdapter,\n private basePath: string,\n private config: MaterializationConfig\n ) {}\n\n private get mode(): 'symlink' | 'copy' {\n return this.config.mode ?? 'symlink';\n }\n\n private get skillsSourceDir(): string {\n return path.join(this.basePath, '.skilltree', 'skills');\n }\n\n /**\n * Initial materialization: create all symlinks/copies + generate AGENTS.md\n */\n async initialize(): Promise<void> {\n if (!this.config.enabled) return;\n\n // Ensure target directories exist\n for (const targetPath of this.config.symlinkPaths ?? []) {\n const resolved = this.resolvePath(targetPath);\n fs.mkdirSync(resolved, { recursive: true });\n }\n\n // Materialize all existing skills\n const skills = await this.storage.listSkills();\n for (const skill of skills) {\n await this.ensureMaterialized(skill.id);\n }\n\n // Clean up stale entries\n await this.cleanup();\n\n // Generate AGENTS.md if configured\n if (this.config.agentsMdPath) {\n await this.regenerateAgentsMd();\n }\n }\n\n /**\n * Called when a skill is created or updated\n */\n async onSkillChanged(skillId: string): Promise<void> {\n if (!this.config.enabled) return;\n\n await this.ensureMaterialized(skillId);\n this.scheduleAgentsMdRegen();\n }\n\n /**\n * Called when a skill is deleted\n */\n async onSkillDeleted(skillId: string): Promise<void> {\n if (!this.config.enabled) return;\n\n await this.removeMaterialized(skillId);\n this.scheduleAgentsMdRegen();\n }\n\n // ===========================================================================\n // Symlink / Copy operations\n // ===========================================================================\n\n /**\n * Materialize a skill to all configured paths (symlink or copy)\n */\n private async ensureMaterialized(skillId: string): Promise<void> {\n const sourcePath = path.join(this.skillsSourceDir, skillId);\n if (!fs.existsSync(sourcePath)) return;\n\n for (const targetBase of this.config.symlinkPaths ?? []) {\n const targetDir = this.resolvePath(targetBase);\n const targetPath = path.join(targetDir, skillId);\n\n if (this.mode === 'copy') {\n this.copyDir(sourcePath, targetPath);\n } else {\n this.ensureSymlink(sourcePath, targetPath);\n }\n }\n }\n\n /**\n * Remove a materialized skill from all configured paths\n */\n private async removeMaterialized(skillId: string): Promise<void> {\n const sourcePath = path.resolve(path.join(this.skillsSourceDir, skillId));\n\n for (const targetBase of this.config.symlinkPaths ?? []) {\n const targetPath = path.join(this.resolvePath(targetBase), skillId);\n if (!fs.existsSync(targetPath)) continue;\n\n if (this.mode === 'copy') {\n // Only remove if it has our marker file\n const markerPath = path.join(targetPath, '.skilltree-managed');\n if (fs.existsSync(markerPath)) {\n fs.rmSync(targetPath, { recursive: true, force: true });\n }\n } else {\n try {\n const linkTarget = fs.readlinkSync(targetPath);\n if (path.resolve(linkTarget) === sourcePath) {\n fs.unlinkSync(targetPath);\n }\n } catch {\n // Not a symlink — don't touch\n }\n }\n }\n }\n\n /**\n * Create or verify a symlink\n */\n private ensureSymlink(sourcePath: string, targetPath: string): void {\n if (fs.existsSync(targetPath)) {\n try {\n const existing = fs.readlinkSync(targetPath);\n if (path.resolve(existing) === path.resolve(sourcePath)) return;\n // Wrong target — remove and recreate\n fs.unlinkSync(targetPath);\n } catch {\n // Not a symlink (manual dir?) — skip to avoid clobbering\n return;\n }\n }\n\n try {\n fs.symlinkSync(sourcePath, targetPath, 'dir');\n } catch (err) {\n // On Windows, try junction fallback\n if ((err as NodeJS.ErrnoException).code === 'EPERM') {\n try {\n fs.symlinkSync(sourcePath, targetPath, 'junction');\n } catch {\n // Can't create symlinks — skip silently\n }\n }\n }\n }\n\n /**\n * Copy a skill directory, adding a marker file so we know we manage it\n */\n private copyDir(sourcePath: string, targetPath: string): void {\n // Remove existing copy if managed by us\n if (fs.existsSync(targetPath)) {\n const markerPath = path.join(targetPath, '.skilltree-managed');\n if (fs.existsSync(markerPath)) {\n fs.rmSync(targetPath, { recursive: true, force: true });\n } else {\n // Not our directory — skip\n return;\n }\n }\n\n fs.cpSync(sourcePath, targetPath, { recursive: true });\n // Add marker so we know this copy is ours\n fs.writeFileSync(\n path.join(targetPath, '.skilltree-managed'),\n JSON.stringify({ source: sourcePath, copiedAt: new Date().toISOString() })\n );\n }\n\n // ===========================================================================\n // AGENTS.md generation\n // ===========================================================================\n\n /**\n * Schedule debounced AGENTS.md regeneration\n */\n private scheduleAgentsMdRegen(): void {\n if (!this.config.agentsMdPath) return;\n\n this.pendingRegen = true;\n\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n\n const debounceMs = this.config.debounceMs ?? 500;\n this.debounceTimer = setTimeout(async () => {\n this.debounceTimer = null;\n if (this.pendingRegen) {\n this.pendingRegen = false;\n await this.regenerateAgentsMd();\n }\n }, debounceMs);\n }\n\n /**\n * Regenerate AGENTS.md with marker-based section replacement\n */\n async regenerateAgentsMd(): Promise<void> {\n const agentsMdPath = this.config.agentsMdPath;\n if (!agentsMdPath) return;\n\n // Guard against concurrent regeneration\n if (this.regenerating) {\n this.pendingRegen = true;\n return;\n }\n this.regenerating = true;\n\n try {\n await this._doRegenerateAgentsMd(agentsMdPath);\n } finally {\n this.regenerating = false;\n // If another change came in while we were regenerating, run again\n if (this.pendingRegen) {\n this.pendingRegen = false;\n await this.regenerateAgentsMd();\n }\n }\n }\n\n private async _doRegenerateAgentsMd(agentsMdPath: string): Promise<void> {\n const resolvedPath = this.resolvePath(agentsMdPath);\n const generatorConfig: AgentsGeneratorConfig = {\n format: this.config.agentsMdFormat ?? 'xml',\n };\n\n // Generate fresh skill content\n const { generateAgentsMd } = await import('../agents/sync.js');\n const skillContent = await generateAgentsMd(this.storage, generatorConfig);\n\n const markedContent =\n `${SKILLTREE_MARKER_START}\\n${skillContent}\\n${SKILLTREE_MARKER_END}`;\n\n // Check if file already exists with markers\n if (fs.existsSync(resolvedPath)) {\n const existing = fs.readFileSync(resolvedPath, 'utf-8');\n const startIdx = existing.indexOf(SKILLTREE_MARKER_START);\n const endIdx = existing.indexOf(SKILLTREE_MARKER_END);\n\n if (startIdx !== -1 && endIdx !== -1) {\n // Replace just our section\n const before = existing.slice(0, startIdx);\n const after = existing.slice(endIdx + SKILLTREE_MARKER_END.length);\n fs.writeFileSync(resolvedPath, before + markedContent + after);\n return;\n }\n\n // No markers — append our section\n fs.writeFileSync(resolvedPath, existing + '\\n\\n' + markedContent + '\\n');\n return;\n }\n\n // New file — write with markers\n const dir = path.dirname(resolvedPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(resolvedPath, markedContent + '\\n');\n }\n\n // ===========================================================================\n // Cleanup\n // ===========================================================================\n\n /**\n * Remove stale entries (symlinks or copies) that point to non-existent skills\n */\n async cleanup(): Promise<void> {\n const skills = await this.storage.listSkills();\n const skillIds = new Set(skills.map((s) => s.id));\n\n for (const targetBase of this.config.symlinkPaths ?? []) {\n const resolved = this.resolvePath(targetBase);\n if (!fs.existsSync(resolved)) continue;\n\n const entries = fs.readdirSync(resolved);\n for (const entry of entries) {\n const entryPath = path.join(resolved, entry);\n if (skillIds.has(entry)) continue;\n\n if (this.mode === 'copy') {\n // Only remove copies we manage\n const markerPath = path.join(entryPath, '.skilltree-managed');\n if (fs.existsSync(markerPath)) {\n fs.rmSync(entryPath, { recursive: true, force: true });\n }\n } else {\n try {\n const linkTarget = fs.readlinkSync(entryPath);\n // Only clean up symlinks pointing into our .skilltree/skills/\n const resolvedTarget = path.resolve(linkTarget);\n if (resolvedTarget.startsWith(this.skillsSourceDir + path.sep) || resolvedTarget === this.skillsSourceDir) {\n fs.unlinkSync(entryPath);\n }\n } catch {\n // Not a symlink — skip\n }\n }\n }\n }\n }\n\n // ===========================================================================\n // File watcher\n // ===========================================================================\n\n /**\n * Start watching .skilltree/skills/ for external changes.\n * Re-materializes when files are added/changed/removed outside the SkillBank API.\n */\n watch(): void {\n if (this.watcher) return;\n if (!this.config.enabled) return;\n\n const watchDir = this.skillsSourceDir;\n if (!fs.existsSync(watchDir)) return;\n\n this.watcher = fs.watch(watchDir, { recursive: true }, (_eventType, filename) => {\n if (!filename) return;\n\n // Debounce watch events (fs.watch fires many events per change)\n if (this.watchDebounceTimer) {\n clearTimeout(this.watchDebounceTimer);\n }\n this.watchDebounceTimer = setTimeout(async () => {\n this.watchDebounceTimer = null;\n try {\n // Re-run full materialization (simpler than tracking individual changes)\n const skills = await this.storage.listSkills();\n for (const skill of skills) {\n await this.ensureMaterialized(skill.id);\n }\n await this.cleanup();\n if (this.config.agentsMdPath) {\n await this.regenerateAgentsMd();\n }\n } catch {\n // Watcher errors are non-fatal\n }\n }, this.config.debounceMs ?? 500);\n });\n }\n\n /**\n * Stop watching for file changes\n */\n unwatch(): void {\n if (this.watcher) {\n this.watcher.close();\n this.watcher = null;\n }\n if (this.watchDebounceTimer) {\n clearTimeout(this.watchDebounceTimer);\n this.watchDebounceTimer = null;\n }\n }\n\n // ===========================================================================\n // Lifecycle\n // ===========================================================================\n\n /**\n * Flush any pending debounced operations (useful for testing)\n */\n async flush(): Promise<void> {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n if (this.pendingRegen) {\n this.pendingRegen = false;\n await this.regenerateAgentsMd();\n }\n }\n\n /**\n * Tear down: cancel pending timers and stop watcher\n */\n shutdown(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n this.pendingRegen = false;\n this.unwatch();\n }\n\n /**\n * Resolve a path relative to basePath, handling ~ expansion\n */\n private resolvePath(p: string): string {\n if (p.startsWith('~')) {\n return path.join(process.env.HOME || process.env.USERPROFILE || '', p.slice(1));\n }\n if (path.isAbsolute(p)) return p;\n return path.resolve(this.basePath, p);\n }\n}\n","/**\n * Storage adapters for skill persistence\n */\n\nexport { BaseStorageAdapter, MemoryStorageAdapter } from './base.js';\nexport { FilesystemStorageAdapter, type FilesystemStorageConfig } from './filesystem.js';\nexport { SQLiteStorageAdapter, type SQLiteStorageConfig } from './sqlite.js';\nexport { CachedStorageAdapter, type CachedStorageConfig } from './cached.js';\nexport {\n migrateStorage,\n type MigrationOptions,\n type MigrationResult,\n type MigrationProgressItem,\n} from './migration.js';\n\n// Re-export types\nexport type { StorageAdapter, SkillFilter, StorageConfig } from '../types.js';\n","/**\n * Storage migration utility\n *\n * Migrates skill data between storage backends (memory, filesystem, SQLite).\n * Copies skills, version history, and lineage.\n */\n\nimport type {\n StorageAdapter,\n Skill,\n SkillLineage,\n} from '../types.js';\n\n/**\n * Options for storage migration\n */\nexport interface MigrationOptions {\n /** Migrate skills */\n skills?: boolean;\n /** Migrate version history and lineage */\n lineage?: boolean;\n /** Called for each item migrated */\n onProgress?: (item: MigrationProgressItem) => void;\n /** Whether to overwrite existing items in the target */\n overwrite?: boolean;\n}\n\n/**\n * Progress item for migration callbacks\n */\nexport interface MigrationProgressItem {\n type: 'skill' | 'lineage';\n id: string;\n status: 'migrated' | 'skipped' | 'error';\n error?: string;\n}\n\n/**\n * Result of a storage migration\n */\nexport interface MigrationResult {\n /** Total items processed */\n totalProcessed: number;\n /** Successfully migrated items */\n migrated: number;\n /** Skipped items (already exist and overwrite=false) */\n skipped: number;\n /** Failed items */\n errors: number;\n /** Breakdown by type */\n details: {\n skills: { migrated: number; skipped: number; errors: number };\n lineages: { migrated: number; skipped: number; errors: number };\n };\n}\n\n/**\n * Migrate data from one storage backend to another.\n *\n * Both storage adapters must be initialized before calling this function.\n *\n * @example\n * ```typescript\n * const memory = new MemoryStorageAdapter();\n * const fs = new FilesystemStorageAdapter({ basePath: './skills' });\n * await memory.initialize();\n * await fs.initialize();\n *\n * const result = await migrateStorage(memory, fs, {\n * skills: true,\n * lineage: true,\n * onProgress: (item) => console.log(`${item.type}: ${item.id} - ${item.status}`),\n * });\n * ```\n */\nexport async function migrateStorage(\n source: StorageAdapter,\n target: StorageAdapter,\n options: MigrationOptions = {}\n): Promise<MigrationResult> {\n const opts: Required<MigrationOptions> = {\n skills: options.skills ?? true,\n lineage: options.lineage ?? true,\n onProgress: options.onProgress ?? (() => {}),\n overwrite: options.overwrite ?? false,\n };\n\n const result: MigrationResult = {\n totalProcessed: 0,\n migrated: 0,\n skipped: 0,\n errors: 0,\n details: {\n skills: { migrated: 0, skipped: 0, errors: 0 },\n lineages: { migrated: 0, skipped: 0, errors: 0 },\n },\n };\n\n // Migrate skills\n if (opts.skills) {\n await migrateSkills(source, target, opts, result);\n }\n\n // Migrate lineage\n if (opts.lineage) {\n await migrateLineages(source, target, opts, result);\n }\n\n return result;\n}\n\nasync function migrateSkills(\n source: StorageAdapter,\n target: StorageAdapter,\n opts: Required<MigrationOptions>,\n result: MigrationResult\n): Promise<void> {\n const skills = await source.listSkills();\n\n for (const skill of skills) {\n result.totalProcessed++;\n try {\n if (!opts.overwrite) {\n const existing = await target.getSkill(skill.id);\n if (existing) {\n result.skipped++;\n result.details.skills.skipped++;\n opts.onProgress({ type: 'skill', id: skill.id, status: 'skipped' });\n continue;\n }\n }\n\n await target.saveSkill(skill);\n result.migrated++;\n result.details.skills.migrated++;\n opts.onProgress({ type: 'skill', id: skill.id, status: 'migrated' });\n } catch (error) {\n result.errors++;\n result.details.skills.errors++;\n opts.onProgress({\n type: 'skill',\n id: skill.id,\n status: 'error',\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n}\n\nasync function migrateLineages(\n source: StorageAdapter,\n target: StorageAdapter,\n opts: Required<MigrationOptions>,\n result: MigrationResult\n): Promise<void> {\n // Get all skills to find their lineages\n const skills = await source.listSkills();\n\n for (const skill of skills) {\n result.totalProcessed++;\n try {\n const lineage = await source.getLineage(skill.id);\n if (!lineage) {\n result.skipped++;\n result.details.lineages.skipped++;\n continue;\n }\n\n // Save each version in the history to the target\n const versionHistory = await source.getVersionHistory(skill.id);\n for (const version of versionHistory) {\n const versionedSkill = await source.getSkill(skill.id, version.version);\n if (versionedSkill) {\n await target.saveSkill(versionedSkill);\n }\n }\n\n result.migrated++;\n result.details.lineages.migrated++;\n opts.onProgress({ type: 'lineage', id: skill.id, status: 'migrated' });\n } catch (error) {\n result.errors++;\n result.details.lineages.errors++;\n opts.onProgress({\n type: 'lineage',\n id: skill.id,\n status: 'error',\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n}\n\n","/**\n * AGENTS.md Integration Module\n */\n\nexport {\n type SkillFormat,\n type AgentsGeneratorConfig,\n type SkillSelector,\n type ParsedAgentSkill,\n type ParsedAgentsFile,\n type SyncResult,\n DEFAULT_AGENTS_CONFIG,\n} from './types.js';\n\nexport {\n AgentsGenerator,\n createAgentsGenerator,\n} from './generator.js';\n\nexport {\n AgentsParser,\n createAgentsParser,\n} from './parser.js';\n\nexport {\n AgentsSync,\n createAgentsSync,\n generateAgentsMd,\n writeAgentsMd,\n importFromAgentsMd,\n type SyncOptions,\n} from './sync.js';\n","/**\n * Built-in hooks for common use cases\n *\n * Runtime metrics hooks (matched/applied/feedback) have moved to cognitive-core\n * which handles skill usage tracking via sessionlog integration.\n */\n\nimport type {\n HookHandler,\n HookResult,\n StorageHookContext,\n} from './types.js';\nimport type { RegisterHookOptions } from './registry.js';\n\n// =============================================================================\n// Logging Hooks\n// =============================================================================\n\n/**\n * Creates a logging hook that logs all events\n */\nexport function createLoggingHook(\n logger: (message: string, context?: Record<string, unknown>) => void = console.log\n): RegisterHookOptions {\n return {\n name: 'logging-hook',\n events: [\n 'storage:before-save',\n 'storage:after-save',\n 'skill:created',\n 'skill:updated',\n 'skill:deleted',\n ],\n priority: 'low',\n handler: async (context): Promise<HookResult> => {\n logger(`[Hook] ${context.event}`, {\n invocationId: context.invocationId,\n timestamp: context.timestamp,\n });\n return { continue: true };\n },\n };\n}\n\n// =============================================================================\n// Storage Hooks\n// =============================================================================\n\n/**\n * Creates a hook that backs up skills before save\n */\nexport function createBackupHook(\n backupFn: (skill: unknown) => Promise<void>\n): RegisterHookOptions {\n const handler: HookHandler<StorageHookContext> = async (context) => {\n if (context.event !== 'storage:before-save') {\n return { continue: true };\n }\n\n try {\n await backupFn(context.skill);\n return { continue: true };\n } catch (error) {\n return {\n continue: true, // Don't block save on backup failure\n error: error instanceof Error ? error : new Error(String(error)),\n message: 'Backup failed but continuing with save',\n };\n }\n };\n\n return {\n name: 'backup-hook',\n events: ['storage:before-save'],\n priority: 'high',\n handler: handler as HookHandler,\n };\n}\n\n/**\n * Creates a hook that validates skills before save\n */\nexport function createSaveValidationHook(options: {\n requiredFields?: (keyof any)[];\n maxDescriptionLength?: number;\n requireTriggers?: boolean;\n}): RegisterHookOptions {\n const handler: HookHandler<StorageHookContext> = async (context) => {\n if (context.event !== 'storage:before-save') {\n return { continue: true };\n }\n\n const skill = context.skill;\n const errors: string[] = [];\n\n // Check required fields\n if (options.requiredFields) {\n for (const field of options.requiredFields) {\n if (!(skill as unknown as Record<string, unknown>)[field as string]) {\n errors.push(`Missing required field: ${String(field)}`);\n }\n }\n }\n\n // Check description length\n if (\n options.maxDescriptionLength &&\n skill.description &&\n skill.description.length > options.maxDescriptionLength\n ) {\n errors.push(\n `Description too long: ${skill.description.length} > ${options.maxDescriptionLength}`\n );\n }\n\n // Check instructions requirement\n if (options.requireTriggers && (!skill.instructions || skill.instructions.trim() === '')) {\n errors.push('Skill must have instructions');\n }\n\n if (errors.length > 0) {\n return {\n continue: false,\n message: errors.join('; '),\n };\n }\n\n return { continue: true };\n };\n\n return {\n name: 'save-validation',\n events: ['storage:before-save'],\n priority: 'high',\n handler: handler as HookHandler,\n };\n}\n\n// =============================================================================\n// Composite Hook Utilities\n// =============================================================================\n\n/**\n * Combines multiple hook handlers into one\n */\nexport function combineHandlers(\n ...handlers: HookHandler[]\n): HookHandler {\n return async (context) => {\n for (const handler of handlers) {\n const result = await handler(context);\n if (!result.continue) {\n return result;\n }\n }\n return { continue: true };\n };\n}\n\n/**\n * Creates a conditional hook that only runs when filter passes\n */\nexport function conditionalHook(\n filter: (context: any) => boolean,\n handler: HookHandler\n): HookHandler {\n return async (context) => {\n if (!filter(context)) {\n return { continue: true };\n }\n return handler(context);\n };\n}\n","/**\n * Multi-Agent Sync Module\n *\n * Git-based skill synchronization for multi-agent collaboration.\n */\n\n// Types\nexport type {\n // Configuration\n SyncConfig,\n RemoteConfig,\n AgentConfig,\n SyncBehaviorConfig,\n ConflictConfig,\n ConflictStrategy,\n\n // Operations\n PullOptions,\n PushOptions,\n SyncResult,\n SkillChange,\n SkillMergeResult,\n SyncError,\n\n // Conflicts\n SkillConflict,\n ConflictResolution,\n\n // Status\n SyncStatus,\n FetchResult,\n\n // State\n SyncState,\n SkillSyncState,\n\n // Internal\n RemoteSkillChange,\n MergeAttempt,\n\n // Hierarchical sync (custom skill trees)\n HierarchicalSyncConfig,\n HierarchicalAgentConfig,\n SyncTierConfig,\n HierarchicalConflictConfig,\n ScopeConflictStrategy,\n HierarchicalSyncResult,\n CrossTierConflict,\n SkillPromotion,\n PromoteOptions,\n DemoteOptions,\n HierarchicalSyncFilter,\n} from './types.js';\n\n// Classes\nexport { GitSyncAdapter, createGitSyncAdapter } from './git-sync-adapter.js';\nexport type { GitSyncAdapterOptions } from './git-sync-adapter.js';\n\nexport { ConflictStore, createConflictStore } from './conflict-store.js';\n\n// Hierarchical sync (custom skill trees with team sync)\nexport {\n HierarchicalSyncAdapter,\n createHierarchicalSyncAdapter,\n createDefaultHierarchicalConfig,\n} from './hierarchical-sync-adapter.js';\nexport type { HierarchicalSyncAdapterOptions } from './hierarchical-sync-adapter.js';\n\n// Sync Manager (SkillBank integration)\nexport { SyncManager, createSyncManager } from './sync-manager.js';\nexport type { SyncManagerOptions } from './sync-manager.js';\n\n// Helper to create a default config\nexport function createDefaultSyncConfig(\n remoteUrl: string,\n agentId: string,\n options?: {\n branch?: string;\n agentName?: string;\n environment?: string;\n }\n): import('./types.js').SyncConfig {\n return {\n remote: {\n type: 'git',\n url: remoteUrl,\n branch: options?.branch || 'main',\n skillsPath: 'skills/',\n },\n agent: {\n id: agentId,\n name: options?.agentName,\n environment: options?.environment,\n },\n sync: {\n mode: 'manual',\n pushStrategy: 'manual',\n pullStrategy: 'auto-merge',\n },\n conflicts: {\n defaultStrategy: 'prefer-newer',\n fieldStrategies: {\n tags: 'union',\n },\n },\n };\n}\n","/**\n * Indexer Service - Wraps the skill indexer functionality for use with SkillBank\n *\n * This service provides a bridge between the skill indexer (scraper/) and the\n * main skill-tree SkillBank. It can work in two modes:\n *\n * 1. Standalone mode: Direct database operations (default)\n * 2. Integrated mode: Uses SkillBank as the storage backend\n */\n\nimport * as path from \"path\";\nimport * as fs from \"fs\";\nimport type {\n Skill,\n SkillRelationship,\n SkillTaxonomy,\n StorageAdapter,\n} from \"../types.js\";\nimport type { SkillBank } from \"../skill-bank.js\";\nimport { loadConfig, SkillTreeConfig } from \"../config/index.js\";\nimport { convertIndexerSkill, type IndexerSkill } from \"../import/converter.js\";\n\n/**\n * Extended storage interface for indexer-specific operations (e.g., SQLite)\n */\ninterface IndexerStorage extends StorageAdapter {\n addRelationship(\n sourceId: string,\n targetId: string,\n type: string,\n confidence: number,\n reasoning?: string,\n ): Promise<void>;\n getTaxonomyTree(rootPath?: string[]): Promise<unknown[]>;\n getRelationships?(skillId: string): Promise<unknown[]>;\n}\n\nfunction hasIndexerSupport(storage: StorageAdapter): storage is IndexerStorage {\n const s = storage as unknown as Record<string, unknown>;\n return (\n typeof s.addRelationship === \"function\" &&\n typeof s.getTaxonomyTree === \"function\"\n );\n}\n\n/**\n * Skill source for scraping\n */\nexport interface SkillSource {\n type: \"awesome-list\" | \"repository\";\n url: string;\n}\n\n/**\n * Indexer configuration (service-level)\n */\nexport interface IndexerServiceConfig {\n /** GitHub API token */\n githubToken?: string;\n /** Anthropic API key for classification */\n anthropicApiKey?: string;\n /** Claude model to use */\n claudeModel?: string;\n /** Database path for standalone mode */\n databasePath?: string;\n /** Batch size for processing */\n batchSize?: number;\n /** Concurrency limit */\n concurrency?: number;\n /** Minimum confidence for classification */\n minConfidence?: number;\n /** Cache directory */\n cacheDir?: string;\n /** Cache TTL in seconds */\n cacheTtlSeconds?: number;\n /** Pre-loaded scraper module. When provided, skips filesystem-based module discovery entirely. */\n scraperModules?: any;\n}\n\n/**\n * Scrape result\n */\nexport interface ScrapeResult {\n discovered: number;\n scraped: number;\n skipped: number;\n failed: number;\n unchanged: number;\n errors: string[];\n}\n\n/**\n * Index result\n */\nexport interface IndexResult {\n indexed: number;\n skipped: number;\n failed: number;\n errors: string[];\n}\n\n/**\n * Relationship detection result\n */\nexport interface RelationshipResult {\n detected: number;\n skipped: number;\n errors: string[];\n}\n\n/**\n * Taxonomy node for tree display\n */\nexport interface TaxonomyNode {\n id: string;\n name: string;\n path: string[];\n skillCount: number;\n children: TaxonomyNode[];\n}\n\n/**\n * Database statistics\n */\nexport interface IndexerStats {\n totalSkills: number;\n indexedSkills: number;\n rawSkills: number;\n failedSkills: number;\n taxonomyNodes: number;\n relationships: number;\n sources: number;\n}\n\n/**\n * IndexerService - Manages skill discovery, classification, and relationship detection\n */\nexport class IndexerService {\n private serviceConfig: IndexerServiceConfig;\n private globalConfig: SkillTreeConfig;\n private skillBank?: SkillBank;\n private initialized = false;\n\n // Dynamic imports for scraper modules (lazy loaded)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private scraperModule?: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private indexerModule?: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private databaseModule?: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private db?: any;\n\n constructor(config: IndexerServiceConfig = {}, skillBank?: SkillBank) {\n // Load global config\n this.globalConfig = loadConfig();\n\n // Merge service config with global config\n this.serviceConfig = {\n githubToken: config.githubToken || this.globalConfig.indexer.github_token,\n anthropicApiKey:\n config.anthropicApiKey || this.globalConfig.indexer.anthropic_key,\n batchSize: config.batchSize || this.globalConfig.indexer.batch_size,\n minConfidence:\n config.minConfidence || this.globalConfig.indexer.min_confidence,\n concurrency: config.concurrency || 3,\n cacheTtlSeconds: config.cacheTtlSeconds || 3600,\n databasePath: config.databasePath,\n cacheDir: config.cacheDir,\n claudeModel: config.claudeModel,\n scraperModules: config.scraperModules,\n };\n this.skillBank = skillBank;\n }\n\n /**\n * Get effective configuration\n */\n getConfig(): IndexerServiceConfig {\n return { ...this.serviceConfig };\n }\n\n /**\n * Initialize the service (lazy load scraper modules)\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n try {\n // If pre-loaded modules were provided (e.g. from `skill-tree-indexer` package),\n // use them directly. The barrel exports classes (ScraperService, SkillClassifier,\n // createDatabase) which differ from the sub-module factory functions the filesystem\n // discovery path expects. We adapt via createScraper/createIndexer wrappers so the\n // rest of the class works unchanged.\n if (this.serviceConfig.scraperModules) {\n const mod = this.serviceConfig.scraperModules;\n\n // Initialize database first — needed by ScraperService constructor\n this.databaseModule = mod;\n if (mod.createDatabase) {\n const dbPath =\n this.serviceConfig.databasePath ||\n path.join(process.cwd(), \"scraper/data/skills.db\");\n const dbDir = path.dirname(dbPath);\n if (!fs.existsSync(dbDir)) fs.mkdirSync(dbDir, { recursive: true });\n this.db = mod.createDatabase({ type: \"sqlite\", path: dbPath });\n // SQLiteAdapter requires connect() + migrate() before use\n if (this.db.connect) await this.db.connect();\n if (this.db.migrate) await this.db.migrate();\n }\n\n const localDb = this.db;\n\n // Bridge ScraperService → createScraper factory.\n // ScraperService(db, config) has .scrape(source, opts) which handles both\n // awesome-list and repository types internally. We wrap it to match the\n // expected factory interface: createScraper(config) → { scrapeAwesomeList, scrapeRepository }\n if (mod.ScraperService) {\n this.scraperModule = {\n createScraper: (config: Record<string, unknown>) => {\n // ScraperConfig requires specific fields with defaults\n const scraperConfig = {\n githubToken: (config.githubToken as string) || \"\",\n cacheEnabled: true,\n cacheDir:\n (config.cacheDir as string) ||\n path.join(process.cwd(), \".cache/scraper\"),\n cacheTtlSeconds: (config.cacheTtlSeconds as number) || 3600,\n requestDelayMs: 100,\n maxRetries: 3,\n };\n const svc = new mod.ScraperService(localDb, scraperConfig);\n let initialized = false;\n const ensureInit = async () => {\n if (!initialized) {\n await svc.init();\n initialized = true;\n }\n };\n return {\n scrapeAwesomeList: async (\n url: string,\n opts?: { force?: boolean },\n ) => {\n await ensureInit();\n await svc.scrape({ type: \"awesome-list\", url }, opts);\n return (await localDb.listSkills()) || [];\n },\n scrapeRepository: async (\n url: string,\n opts?: { force?: boolean },\n ) => {\n await ensureInit();\n await svc.scrape({ type: \"repository\", url }, opts);\n return (await localDb.listSkills()) || [];\n },\n };\n },\n };\n }\n\n // Bridge SkillClassifier → createIndexer factory.\n // SkillClassifier(config) has .classify(skill, taxonomyTree).\n // The caller expects: createIndexer(config) → { classifySkill(skill) }\n if (mod.SkillClassifier) {\n this.indexerModule = {\n createIndexer: (config: Record<string, unknown>) => {\n const classifier = new mod.SkillClassifier(config);\n return {\n classifySkill: async (skill: unknown) => {\n // Get taxonomy tree if TaxonomyManager is available\n let tree: unknown = null;\n if (mod.TaxonomyManager && localDb) {\n try {\n const tm = new mod.TaxonomyManager(localDb);\n tree = await tm.getTree();\n } catch {\n /* no taxonomy yet */\n }\n }\n return classifier.classify(skill, tree);\n },\n };\n },\n };\n }\n\n this.initialized = true;\n return;\n }\n\n // Filesystem-based module discovery (CLI / standalone usage)\n const possiblePaths = [\n // Relative to this file in dist\n path.resolve(__dirname, \"../../scraper/dist\"),\n // Relative to project root\n path.resolve(process.cwd(), \"scraper/dist\"),\n // Absolute paths from config\n this.serviceConfig.cacheDir\n ? path.resolve(this.serviceConfig.cacheDir, \"../scraper/dist\")\n : null,\n ].filter(Boolean) as string[];\n\n let scraperBasePath: string | null = null;\n\n for (const basePath of possiblePaths) {\n const scraperIndex = path.join(basePath, \"scraper/index.js\");\n if (fs.existsSync(scraperIndex)) {\n scraperBasePath = basePath;\n break;\n }\n }\n\n if (!scraperBasePath) {\n throw new Error(\n \"Scraper modules not found. Run `cd scraper && npm run build` first.\",\n );\n }\n\n // Import modules\n const scraperPath = path.join(scraperBasePath, \"scraper/index.js\");\n const indexerPath = path.join(scraperBasePath, \"indexer/index.js\");\n const databasePath = path.join(scraperBasePath, \"database/index.js\");\n\n this.scraperModule = await import(/* webpackIgnore: true */ scraperPath);\n this.indexerModule = await import(/* webpackIgnore: true */ indexerPath);\n this.databaseModule = await import(\n /* webpackIgnore: true */ databasePath\n );\n\n // Initialize database connection\n if (this.databaseModule.createDatabase) {\n const dbPath =\n this.serviceConfig.databasePath ||\n path.join(process.cwd(), \"scraper/data/skills.db\");\n this.db = this.databaseModule.createDatabase(dbPath);\n }\n\n this.initialized = true;\n } catch (err) {\n // If scraper modules aren't available, operate in degraded mode\n console.warn(`Scraper modules not available: ${(err as Error).message}`);\n console.warn(\"Some indexer features will be limited.\");\n this.initialized = true; // Mark as initialized but in degraded mode\n }\n }\n\n /**\n * Check if the indexer is available\n */\n isAvailable(): boolean {\n return this.initialized && !!this.scraperModule;\n }\n\n /**\n * Check if running in degraded mode (no scraper modules)\n */\n isDegradedMode(): boolean {\n return this.initialized && !this.scraperModule;\n }\n\n /**\n * Scrape skills from GitHub sources\n */\n async scrape(\n sources: SkillSource[],\n options?: { force?: boolean },\n ): Promise<ScrapeResult> {\n await this.initialize();\n\n if (!this.scraperModule || !this.db) {\n throw new Error(\n \"Scraper not available. Build the scraper module first: cd scraper && npm run build\",\n );\n }\n\n const result: ScrapeResult = {\n discovered: 0,\n scraped: 0,\n skipped: 0,\n failed: 0,\n unchanged: 0,\n errors: [],\n };\n\n try {\n // Get the scraper instance\n const scraper = this.scraperModule.createScraper({\n githubToken: this.serviceConfig.githubToken,\n cacheDir: this.serviceConfig.cacheDir,\n cacheTtlSeconds: this.serviceConfig.cacheTtlSeconds,\n });\n\n for (const source of sources) {\n try {\n let skills: any[];\n\n if (source.type === \"awesome-list\") {\n // Scrape from awesome list\n skills = await scraper.scrapeAwesomeList(source.url, {\n force: options?.force,\n });\n } else {\n // Scrape single repository\n skills = await scraper.scrapeRepository(source.url, {\n force: options?.force,\n });\n }\n\n result.discovered += skills.length;\n\n // Store in database\n for (const skill of skills) {\n try {\n const existing = this.db.getSkillBySlug?.(skill.slug);\n if (existing && !options?.force) {\n result.unchanged++;\n } else {\n this.db.saveSkill?.(skill);\n result.scraped++;\n }\n } catch (err) {\n result.failed++;\n result.errors.push(\n `Failed to save skill ${skill.slug}: ${(err as Error).message}`,\n );\n }\n }\n } catch (err) {\n result.failed++;\n result.errors.push(\n `Failed to scrape ${source.url}: ${(err as Error).message}`,\n );\n }\n }\n } catch (err) {\n result.errors.push(`Scrape failed: ${(err as Error).message}`);\n }\n\n return result;\n }\n\n /**\n * Classify unindexed skills using AI\n */\n async classify(options?: {\n skillId?: string;\n all?: boolean;\n }): Promise<IndexResult> {\n await this.initialize();\n\n if (!this.indexerModule || !this.db) {\n throw new Error(\n \"Indexer not available. Build the scraper module first: cd scraper && npm run build\",\n );\n }\n\n const result: IndexResult = {\n indexed: 0,\n skipped: 0,\n failed: 0,\n errors: [],\n };\n\n try {\n // Get the indexer instance\n const indexer = this.indexerModule.createIndexer({\n anthropicApiKey: this.serviceConfig.anthropicApiKey,\n model: this.serviceConfig.claudeModel || \"claude-sonnet-4-20250514\",\n minConfidence: this.serviceConfig.minConfidence,\n });\n\n // Get skills to classify\n let skills: any[];\n if (options?.skillId) {\n const skill = this.db.getSkillBySlug?.(options.skillId);\n skills = skill ? [skill] : [];\n } else if (options?.all) {\n skills = this.db.getAllSkills?.() || [];\n } else {\n skills = this.db.getSkillsByStatus?.(\"raw\") || [];\n }\n\n // Process in batches\n const batchSize = this.serviceConfig.batchSize || 10;\n for (let i = 0; i < skills.length; i += batchSize) {\n const batch = skills.slice(i, i + batchSize);\n\n for (const skill of batch) {\n if (skill.status === \"indexed\" && !options?.all) {\n result.skipped++;\n continue;\n }\n\n try {\n const classification = await indexer.classifySkill(skill);\n\n // Update skill with classification\n skill.status = \"indexed\";\n skill.primaryPath = classification.primaryPath;\n skill.secondaryPaths = classification.secondaryPaths;\n skill.confidence = classification.confidence;\n skill.classificationReasoning = classification.reasoning;\n skill.indexedAt = new Date().toISOString();\n\n this.db.saveSkill?.(skill);\n result.indexed++;\n } catch (err) {\n result.failed++;\n result.errors.push(\n `Failed to classify ${skill.slug}: ${(err as Error).message}`,\n );\n }\n }\n }\n } catch (err) {\n result.errors.push(`Classification failed: ${(err as Error).message}`);\n }\n\n return result;\n }\n\n /**\n * Detect relationships between skills\n */\n async detectRelationships(options?: {\n skillId?: string;\n useAi?: boolean;\n }): Promise<RelationshipResult> {\n await this.initialize();\n\n const result: RelationshipResult = {\n detected: 0,\n skipped: 0,\n errors: [],\n };\n\n // If we have SkillBank integration, use SQLite storage directly\n if (this.skillBank) {\n try {\n const storage = this.skillBank.getStorage();\n if (hasIndexerSupport(storage)) {\n const skills = await this.skillBank.listSkills();\n const targetSkills = options?.skillId\n ? skills.filter((s) => s.id === options.skillId)\n : skills;\n\n for (const skill of targetSkills) {\n // Simple keyword-based relationship detection\n const relationships = this.detectSkillRelationships(skill, skills);\n\n for (const rel of relationships) {\n try {\n await storage.addRelationship(\n skill.id,\n rel.targetSkillId,\n rel.type,\n rel.confidence,\n rel.reasoning,\n );\n result.detected++;\n } catch (err) {\n // Relationship might already exist\n result.skipped++;\n }\n }\n }\n }\n } catch (err) {\n result.errors.push(\n `Relationship detection failed: ${(err as Error).message}`,\n );\n }\n\n return result;\n }\n\n // Fallback to scraper module\n if (!this.db) {\n throw new Error(\"Neither SkillBank nor scraper database available.\");\n }\n\n try {\n const skills = this.db.getAllSkills?.() || [];\n const targetSkills = options?.skillId\n ? skills.filter((s: any) => s.slug === options.skillId)\n : skills.filter((s: any) => s.status === \"indexed\");\n\n for (const skill of targetSkills) {\n const relationships = this.detectSkillRelationships(skill, skills);\n\n for (const rel of relationships) {\n try {\n this.db.saveRelationship?.({\n sourceSkillId: skill.id,\n ...rel,\n });\n result.detected++;\n } catch (err) {\n result.skipped++;\n }\n }\n }\n } catch (err) {\n result.errors.push(\n `Relationship detection failed: ${(err as Error).message}`,\n );\n }\n\n return result;\n }\n\n /**\n * Detect relationships for a single skill\n */\n private detectSkillRelationships(\n skill: Skill | any,\n allSkills: (Skill | any)[],\n ): SkillRelationship[] {\n const relationships: SkillRelationship[] = [];\n const skillId = skill.id || skill.slug;\n const skillContent =\n `${skill.name} ${skill.description} ${skill.instructions || \"\"} ${skill.content || \"\"}`.toLowerCase();\n\n for (const other of allSkills) {\n const otherId = other.id || other.slug;\n if (otherId === skillId) continue;\n\n const otherName = (other.name || \"\").toLowerCase();\n\n // Check for dependency keywords\n const dependencyPatterns = [\n \"requires\",\n \"depends on\",\n \"uses\",\n \"needs\",\n \"builds on\",\n ];\n for (const pattern of dependencyPatterns) {\n if (skillContent.includes(`${pattern} ${otherName}`)) {\n relationships.push({\n targetSkillId: otherId,\n type: \"depends_on\",\n confidence: 0.7,\n reasoning: `Content mentions \"${pattern} ${other.name}\"`,\n });\n break;\n }\n }\n\n // Check for extension keywords\n const extensionPatterns = [\n \"extends\",\n \"improves\",\n \"enhances\",\n \"builds upon\",\n ];\n for (const pattern of extensionPatterns) {\n if (skillContent.includes(`${pattern} ${otherName}`)) {\n relationships.push({\n targetSkillId: otherId,\n type: \"extends\",\n confidence: 0.7,\n reasoning: `Content mentions \"${pattern} ${other.name}\"`,\n });\n break;\n }\n }\n\n // Check for alternative keywords\n const alternativePatterns = [\n \"alternative to\",\n \"instead of\",\n \"replacement for\",\n ];\n for (const pattern of alternativePatterns) {\n if (skillContent.includes(`${pattern} ${otherName}`)) {\n relationships.push({\n targetSkillId: otherId,\n type: \"alternative\",\n confidence: 0.6,\n reasoning: `Content mentions \"${pattern} ${other.name}\"`,\n });\n break;\n }\n }\n\n // Check for same taxonomy category (related)\n const skillPath = skill.taxonomy?.primaryPath || skill.primaryPath || [];\n const otherPath = other.taxonomy?.primaryPath || other.primaryPath || [];\n if (skillPath.length >= 2 && otherPath.length >= 2) {\n if (skillPath[0] === otherPath[0] && skillPath[1] === otherPath[1]) {\n relationships.push({\n targetSkillId: otherId,\n type: \"related\",\n confidence: 0.5,\n reasoning: `Same taxonomy category: ${skillPath.slice(0, 2).join(\" > \")}`,\n });\n }\n }\n }\n\n return relationships;\n }\n\n /**\n * Get taxonomy tree\n */\n async getTaxonomyTree(rootPath?: string[]): Promise<TaxonomyNode> {\n await this.initialize();\n\n // If we have SkillBank integration with SQLite storage\n if (this.skillBank) {\n const storage = this.skillBank.getStorage();\n if (hasIndexerSupport(storage)) {\n const nodes = await storage.getTaxonomyTree(rootPath);\n // SQLite storage already returns tree structure with children\n // Convert it to a single root node\n return this.wrapTreeNodes(nodes, rootPath);\n }\n }\n\n // Fallback to building from skills\n const skills = this.skillBank\n ? await this.skillBank.listSkills()\n : this.db?.getAllSkills?.() || [];\n\n return this.buildTaxonomyTreeFromSkills(skills, rootPath);\n }\n\n /**\n * Wrap tree nodes returned from SQLite storage into a root node\n */\n private wrapTreeNodes(nodes: any[], rootPath?: string[]): TaxonomyNode {\n const root: TaxonomyNode = {\n id: \"root\",\n name: rootPath?.join(\" > \") || \"All Skills\",\n path: rootPath || [],\n skillCount: 0,\n children: [],\n };\n\n // Add root nodes as children and count total skills\n for (const node of nodes) {\n root.children.push(this.convertToTaxonomyNode(node));\n root.skillCount += this.countNodeSkills(node);\n }\n\n return root;\n }\n\n /**\n * Convert storage tree node to TaxonomyNode format\n */\n private convertToTaxonomyNode(node: any): TaxonomyNode {\n return {\n id: node.id,\n name: node.name,\n path: Array.isArray(node.path) ? node.path : (node.path || \"\").split(\"/\"),\n skillCount: node.skillCount || 0,\n children: (node.children || []).map((child: any) =>\n this.convertToTaxonomyNode(child),\n ),\n };\n }\n\n /**\n * Count total skills in a node tree\n */\n private countNodeSkills(node: any): number {\n let count = node.skillCount || 0;\n for (const child of node.children || []) {\n count += this.countNodeSkills(child);\n }\n return count;\n }\n\n /**\n * Build taxonomy tree from flat nodes\n */\n private buildTaxonomyTree(nodes: any[], rootPath?: string[]): TaxonomyNode {\n const root: TaxonomyNode = {\n id: \"root\",\n name: rootPath?.join(\" > \") || \"All Skills\",\n path: rootPath || [],\n skillCount: 0,\n children: [],\n };\n\n // Group nodes by parent\n const nodeMap = new Map<string, TaxonomyNode>();\n nodeMap.set(\"root\", root);\n\n for (const node of nodes) {\n const taxNode: TaxonomyNode = {\n id: node.id,\n name: node.name,\n path: node.path,\n skillCount: node.skillCount || 0,\n children: [],\n };\n nodeMap.set(node.id, taxNode);\n }\n\n // Build tree structure\n for (const node of nodes) {\n const taxNode = nodeMap.get(node.id)!;\n const parentId = node.parentId || \"root\";\n const parent = nodeMap.get(parentId);\n if (parent) {\n parent.children.push(taxNode);\n parent.skillCount += taxNode.skillCount;\n }\n }\n\n return root;\n }\n\n /**\n * Build taxonomy tree from skills\n */\n private buildTaxonomyTreeFromSkills(\n skills: any[],\n rootPath?: string[],\n ): TaxonomyNode {\n const root: TaxonomyNode = {\n id: \"root\",\n name: rootPath?.join(\" > \") || \"All Skills\",\n path: rootPath || [],\n skillCount: 0,\n children: [],\n };\n\n const nodeMap = new Map<string, TaxonomyNode>();\n\n for (const skill of skills) {\n const taxonomy =\n skill.taxonomy ||\n (skill.primaryPath ? { primaryPath: skill.primaryPath } : null);\n if (!taxonomy?.primaryPath) continue;\n\n const skillPath = taxonomy.primaryPath;\n\n // Check if matches root filter\n if (rootPath && rootPath.length > 0) {\n let matches = true;\n for (let i = 0; i < rootPath.length; i++) {\n if (skillPath[i] !== rootPath[i]) {\n matches = false;\n break;\n }\n }\n if (!matches) continue;\n }\n\n // Build path nodes\n let currentPath: string[] = [];\n let parent = root;\n\n for (const segment of skillPath) {\n currentPath = [...currentPath, segment];\n const pathKey = currentPath.join(\"/\");\n\n let node = nodeMap.get(pathKey);\n if (!node) {\n node = {\n id: pathKey,\n name: segment,\n path: [...currentPath],\n skillCount: 0,\n children: [],\n };\n nodeMap.set(pathKey, node);\n parent.children.push(node);\n }\n\n parent = node;\n }\n\n // Increment count for leaf node\n parent.skillCount++;\n root.skillCount++;\n }\n\n return root;\n }\n\n /**\n * Get indexer statistics\n */\n async getStats(): Promise<IndexerStats> {\n await this.initialize();\n\n // If we have SkillBank integration\n if (this.skillBank) {\n const skills = await this.skillBank.listSkills();\n const storage = this.skillBank.getStorage();\n\n let taxonomyNodes = 0;\n let relationships = 0;\n let sources = 0;\n\n if (storage) {\n if (hasIndexerSupport(storage)) {\n const tree = await storage.getTaxonomyTree();\n taxonomyNodes = this.countTaxonomyNodes(tree);\n\n // Count relationships\n if (storage.getRelationships) {\n for (const skill of skills) {\n const rels = await storage.getRelationships(skill.id);\n relationships += (rels as unknown[]).length;\n }\n }\n }\n\n // Count unique sources\n const sourceSet = new Set<string>();\n for (const skill of skills) {\n if (skill.externalSource?.repo) {\n sourceSet.add(skill.externalSource.repo);\n }\n if (skill.source?.type === \"imported\" && skill.externalSource?.url) {\n sourceSet.add(skill.externalSource.url);\n }\n }\n sources = sourceSet.size;\n }\n\n const indexed = skills.filter(\n (s) =>\n s.status === \"active\" &&\n (s.taxonomy || s.source?.type === \"imported\"),\n ).length;\n\n return {\n totalSkills: skills.length,\n indexedSkills: indexed,\n rawSkills: skills.filter((s) => s.status === \"draft\").length,\n failedSkills: skills.filter((s) => s.status === \"deprecated\").length,\n taxonomyNodes,\n relationships,\n sources,\n };\n }\n\n // Fallback to scraper database\n if (this.db) {\n const stats = this.db.getStats?.() || {};\n return {\n totalSkills: stats.totalSkills || 0,\n indexedSkills: stats.indexedSkills || 0,\n rawSkills: stats.rawSkills || 0,\n failedSkills: stats.failedSkills || 0,\n taxonomyNodes: stats.taxonomyNodes || 0,\n relationships: stats.relationships || 0,\n sources: stats.sources || 0,\n };\n }\n\n return {\n totalSkills: 0,\n indexedSkills: 0,\n rawSkills: 0,\n failedSkills: 0,\n taxonomyNodes: 0,\n relationships: 0,\n sources: 0,\n };\n }\n\n /**\n * Count nodes in taxonomy tree\n */\n private countTaxonomyNodes(nodes: any[]): number {\n let count = 0;\n for (const node of nodes) {\n count++;\n if (node.children) {\n count += this.countTaxonomyNodes(node.children);\n }\n }\n return count;\n }\n\n /**\n * Scrape and index skills directly into SkillBank\n * This is the streamlined workflow for integrated mode\n */\n async scrapeAndIndex(\n sources: SkillSource[],\n options?: {\n force?: boolean;\n autoClassify?: boolean;\n detectRelationships?: boolean;\n /** Import all scraped skills into SkillBank regardless of classification status */\n importAll?: boolean;\n },\n ): Promise<{\n scraped: ScrapeResult;\n indexed: IndexResult;\n relationships: RelationshipResult;\n skillsAdded: string[];\n }> {\n if (!this.skillBank) {\n throw new Error(\n \"SkillBank required for scrapeAndIndex. Use integrated mode.\",\n );\n }\n\n await this.initialize();\n\n const skillsAdded: string[] = [];\n\n // Step 1: Scrape skills\n const scraped = await this.scrape(sources, { force: options?.force });\n\n // Step 2: Classify if requested\n let indexed: IndexResult = {\n indexed: 0,\n skipped: 0,\n failed: 0,\n errors: [],\n };\n if (options?.autoClassify !== false) {\n indexed = await this.classify({ all: options?.force });\n }\n\n // Step 3: Convert and import into SkillBank\n if (this.db) {\n const skills =\n (await (this.db.getAllSkills?.() || this.db.listSkills?.())) || [];\n for (const skill of skills) {\n if (skill.status !== \"indexed\" && !options?.force && !options?.importAll) continue;\n\n try {\n const converted = convertIndexerSkill(skill as IndexerSkill);\n await this.skillBank.saveSkill(converted.skill);\n skillsAdded.push(converted.skill.id);\n } catch (err) {\n indexed.errors.push(\n `Failed to import ${skill.slug}: ${(err as Error).message}`,\n );\n }\n }\n }\n\n // Step 4: Detect relationships if requested\n let relationships: RelationshipResult = {\n detected: 0,\n skipped: 0,\n errors: [],\n };\n if (options?.detectRelationships !== false) {\n relationships = await this.detectRelationships();\n }\n\n return {\n scraped,\n indexed,\n relationships,\n skillsAdded,\n };\n }\n\n /**\n * Import skills from indexer database into SkillBank\n */\n async importFromIndexerDb(options?: {\n status?: \"raw\" | \"indexed\" | \"failed\";\n limit?: number;\n }): Promise<{ imported: number; failed: number; skills: Skill[] }> {\n if (!this.skillBank) {\n throw new Error(\"SkillBank not configured. Use integrated mode.\");\n }\n\n await this.initialize();\n\n if (!this.db) {\n throw new Error(\n \"Scraper database not available. Build the scraper module first.\",\n );\n }\n\n const result = { imported: 0, failed: 0, skills: [] as Skill[] };\n\n try {\n let skills: any[];\n if (options?.status) {\n skills = this.db.getSkillsByStatus?.(options.status) || [];\n } else {\n skills = this.db.getAllSkills?.() || [];\n }\n\n if (options?.limit) {\n skills = skills.slice(0, options.limit);\n }\n\n for (const skill of skills) {\n try {\n const converted = convertIndexerSkill(skill as IndexerSkill);\n await this.skillBank.saveSkill(converted.skill);\n result.imported++;\n result.skills.push(converted.skill);\n } catch (err) {\n result.failed++;\n }\n }\n } catch (err) {\n throw new Error(`Import failed: ${(err as Error).message}`);\n }\n\n return result;\n }\n\n /**\n * Get default skill sources from config\n */\n getDefaultSources(): SkillSource[] {\n const configSources = this.globalConfig.indexer.sources;\n\n if (configSources.length > 0) {\n return configSources.map((url) => ({\n type: \"awesome-list\" as const,\n url,\n }));\n }\n\n // Default sources if none configured\n return [\n {\n type: \"awesome-list\",\n url: \"https://github.com/VoltAgent/awesome-agent-skills\",\n },\n ];\n }\n\n /**\n * Close database connections\n */\n async close(): Promise<void> {\n if (this.db && typeof this.db.close === \"function\") {\n this.db.close();\n }\n this.db = undefined;\n this.initialized = false;\n }\n}\n\n// Legacy type alias for backwards compatibility\nexport type IndexerConfig = IndexerServiceConfig;\n\n/**\n * Create an IndexerService with SkillBank integration\n */\nexport function createIntegratedIndexer(\n skillBank: SkillBank,\n config: Partial<IndexerServiceConfig> = {},\n): IndexerService {\n return new IndexerService(config, skillBank);\n}\n\n/**\n * Create a standalone IndexerService\n */\nexport function createStandaloneIndexer(\n config: Partial<IndexerServiceConfig> = {},\n): IndexerService {\n return new IndexerService(config);\n}\n","/**\n * Configuration Types\n * Unified configuration schema for skill-tree and indexer settings\n */\n\n/**\n * Storage configuration\n */\nexport interface StorageConfig {\n /** Path to .skilltree directory */\n path: string;\n}\n\n/**\n * Indexer configuration\n */\nexport interface IndexerConfig {\n /** GitHub personal access token */\n github_token?: string;\n /** Anthropic API key for classification */\n anthropic_key?: string;\n /** Default sources to scrape */\n sources: string[];\n /** Batch size for processing */\n batch_size: number;\n /** Minimum confidence threshold for classification */\n min_confidence: number;\n}\n\n/**\n * Matching configuration\n */\nexport interface MatchingConfig {\n /** Embedding model to use */\n embedding_model: string;\n /** Similarity threshold for matching */\n similarity_threshold: number;\n}\n\n/**\n * Sync configuration\n */\nexport interface SyncConfig {\n /** Enable automatic sync checks */\n auto_check: boolean;\n /** Sync check interval in hours */\n check_interval_hours: number;\n /** Default conflict resolution strategy */\n conflict_resolution: 'local' | 'remote' | 'prompt';\n}\n\n/**\n * CLI configuration\n */\nexport interface CLIConfig {\n /** Default output format */\n output_format: 'table' | 'json' | 'yaml';\n /** Enable colored output */\n color: boolean;\n /** Quiet mode (minimal output) */\n quiet: boolean;\n}\n\n/**\n * Materialization configuration (config file schema)\n * Controls how skills are materialized to agent-discoverable locations.\n */\nexport interface MaterializationFileConfig {\n /** Enable automatic materialization on skill changes (default: false) */\n enabled: boolean;\n /** Materialization mode: 'symlink' creates symlinks, 'copy' copies directories */\n mode: 'symlink' | 'copy';\n /** Directories to symlink/copy skill dirs into (e.g. ['.claude/skills', '.agent/skills']) */\n symlink_paths: string[];\n /** Path to write AGENTS.md (e.g. './AGENTS.md'). Empty string means disabled */\n agents_md_path: string;\n /** Format for AGENTS.md generation */\n agents_md_format: 'xml' | 'markdown' | 'json';\n /** Debounce interval in ms for batch updates */\n debounce_ms: number;\n}\n\n/**\n * Complete skill-tree configuration\n */\nexport interface SkillTreeConfig {\n /** Storage settings */\n storage: StorageConfig;\n /** Indexer settings */\n indexer: IndexerConfig;\n /** Matching settings */\n matching: MatchingConfig;\n /** Sync settings */\n sync: SyncConfig;\n /** CLI settings */\n cli: CLIConfig;\n /** Materialization settings */\n materialization: MaterializationFileConfig;\n}\n\n/**\n * Partial configuration for overrides\n */\nexport type PartialSkillTreeConfig = {\n storage?: Partial<StorageConfig>;\n indexer?: Partial<IndexerConfig>;\n matching?: Partial<MatchingConfig>;\n sync?: Partial<SyncConfig>;\n cli?: Partial<CLIConfig>;\n materialization?: Partial<MaterializationFileConfig>;\n};\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: SkillTreeConfig = {\n storage: {\n path: '~/.skill-tree',\n },\n indexer: {\n sources: [],\n batch_size: 10,\n min_confidence: 0.7,\n },\n matching: {\n embedding_model: 'text-embedding-3-small',\n similarity_threshold: 0.8,\n },\n sync: {\n auto_check: false,\n check_interval_hours: 24,\n conflict_resolution: 'prompt',\n },\n cli: {\n output_format: 'table',\n color: true,\n quiet: false,\n },\n materialization: {\n enabled: false,\n mode: 'symlink',\n symlink_paths: [],\n agents_md_path: '',\n agents_md_format: 'xml',\n debounce_ms: 500,\n },\n};\n","/**\n * Configuration Loader\n * Loads and merges configuration from files and environment variables\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n SkillTreeConfig,\n PartialSkillTreeConfig,\n DEFAULT_CONFIG,\n} from './types.js';\n\n/**\n * Environment variable mappings\n */\nconst ENV_MAPPINGS: Record<string, string> = {\n GITHUB_TOKEN: 'indexer.github_token',\n ANTHROPIC_API_KEY: 'indexer.anthropic_key',\n SKILL_TREE_STORAGE_PATH: 'storage.path',\n SKILL_TREE_OUTPUT_FORMAT: 'cli.output_format',\n SKILL_TREE_QUIET: 'cli.quiet',\n SKILL_TREE_NO_COLOR: 'cli.color',\n};\n\n/**\n * Get the default config directory path\n */\nexport function getConfigDir(): string {\n return path.join(os.homedir(), '.skill-tree');\n}\n\n/**\n * Get the default config file path\n */\nexport function getConfigPath(): string {\n return path.join(getConfigDir(), 'config.yaml');\n}\n\n/**\n * Expand ~ to home directory in paths\n */\nexport function expandPath(filePath: string): string {\n if (filePath.startsWith('~/')) {\n return path.join(os.homedir(), filePath.slice(2));\n }\n if (filePath.startsWith('~')) {\n return path.join(os.homedir(), filePath.slice(1));\n }\n return filePath;\n}\n\n/**\n * Substitute environment variables in a string\n * Supports ${VAR} and $VAR syntax\n */\nexport function substituteEnvVars(value: string): string {\n // Handle ${VAR} syntax\n let result = value.replace(/\\$\\{([^}]+)\\}/g, (_, varName) => {\n return process.env[varName] || '';\n });\n\n // Handle $VAR syntax (not followed by {)\n result = result.replace(/\\$([A-Z_][A-Z0-9_]*)/gi, (_, varName) => {\n return process.env[varName] || '';\n });\n\n return result;\n}\n\n/**\n * Recursively substitute environment variables in an object\n */\nfunction substituteEnvVarsInObject<T>(obj: T): T {\n if (typeof obj === 'string') {\n return substituteEnvVars(obj) as T;\n }\n if (Array.isArray(obj)) {\n return obj.map(item => substituteEnvVarsInObject(item)) as T;\n }\n if (obj !== null && typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = substituteEnvVarsInObject(value);\n }\n return result as T;\n }\n return obj;\n}\n\n/**\n * Set a nested property using dot notation\n */\nfunction setNestedProperty(obj: Record<string, unknown>, path: string, value: unknown): void {\n const parts = path.split('.');\n let current = obj;\n\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (!(part in current)) {\n current[part] = {};\n }\n current = current[part] as Record<string, unknown>;\n }\n\n current[parts[parts.length - 1]] = value;\n}\n\n/**\n * Deep merge two objects\n */\nfunction deepMerge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceValue = source[key];\n const targetValue = result[key];\n\n if (\n sourceValue !== undefined &&\n typeof sourceValue === 'object' &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof targetValue === 'object' &&\n targetValue !== null &&\n !Array.isArray(targetValue)\n ) {\n result[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n ) as T[keyof T];\n } else if (sourceValue !== undefined) {\n result[key] = sourceValue as T[keyof T];\n }\n }\n\n return result;\n}\n\n/**\n * Parse YAML-like config (simple implementation)\n * For full YAML support, consider using js-yaml package\n */\nexport function parseSimpleYaml(content: string): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const lines = content.split('\\n');\n const stack: { indent: number; obj: Record<string, unknown> }[] = [{ indent: -1, obj: result }];\n\n for (const line of lines) {\n // Skip empty lines and comments\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) {\n continue;\n }\n\n // Calculate indentation\n const indent = line.search(/\\S/);\n\n // Pop stack until we find parent\n while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {\n stack.pop();\n }\n\n const parent = stack[stack.length - 1].obj;\n\n // Parse key: value or key:\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = trimmed.slice(0, colonIndex).trim();\n let value = trimmed.slice(colonIndex + 1).trim();\n\n if (value === '') {\n // Nested object\n const newObj: Record<string, unknown> = {};\n parent[key] = newObj;\n stack.push({ indent, obj: newObj });\n } else if (value.startsWith('[') && value.endsWith(']')) {\n // Inline array\n const items = value.slice(1, -1).split(',').map(s => s.trim()).filter(Boolean);\n parent[key] = items.map(item => {\n // Remove quotes if present\n if ((item.startsWith('\"') && item.endsWith('\"')) ||\n (item.startsWith(\"'\") && item.endsWith(\"'\"))) {\n return item.slice(1, -1);\n }\n // Parse numbers and booleans\n if (item === 'true') return true;\n if (item === 'false') return false;\n const num = Number(item);\n if (!isNaN(num)) return num;\n return item;\n });\n } else {\n // Scalar value\n // Remove quotes if present\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n\n // Parse booleans and numbers\n if (value === 'true') {\n parent[key] = true;\n } else if (value === 'false') {\n parent[key] = false;\n } else {\n const num = Number(value);\n if (!isNaN(num) && value !== '') {\n parent[key] = num;\n } else {\n parent[key] = value;\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Load configuration from file\n */\nexport function loadConfigFromFile(configPath: string): PartialSkillTreeConfig | null {\n const expandedPath = expandPath(configPath);\n\n if (!fs.existsSync(expandedPath)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(expandedPath, 'utf-8');\n const parsed = parseSimpleYaml(content);\n return substituteEnvVarsInObject(parsed) as PartialSkillTreeConfig;\n } catch (error) {\n console.error(`Warning: Failed to parse config file ${configPath}:`, error);\n return null;\n }\n}\n\n/**\n * Load configuration from environment variables\n */\nexport function loadConfigFromEnv(): PartialSkillTreeConfig {\n const config: Record<string, unknown> = {};\n\n for (const [envVar, configPath] of Object.entries(ENV_MAPPINGS)) {\n const value = process.env[envVar];\n if (value !== undefined) {\n // Special handling for boolean inversions\n if (envVar === 'SKILL_TREE_NO_COLOR') {\n setNestedProperty(config, configPath, value !== 'true' && value !== '1');\n } else if (envVar === 'SKILL_TREE_QUIET') {\n setNestedProperty(config, configPath, value === 'true' || value === '1');\n } else {\n setNestedProperty(config, configPath, value);\n }\n }\n }\n\n return config as PartialSkillTreeConfig;\n}\n\n/**\n * Configuration loader class\n */\nexport class ConfigLoader {\n private config: SkillTreeConfig;\n private configPath: string;\n private loaded: boolean = false;\n\n constructor(configPath?: string) {\n this.configPath = configPath || getConfigPath();\n this.config = { ...DEFAULT_CONFIG };\n }\n\n /**\n * Load configuration from all sources\n * Priority (highest to lowest):\n * 1. Environment variables\n * 2. Config file\n * 3. Default values\n */\n load(): SkillTreeConfig {\n if (this.loaded) {\n return this.config;\n }\n\n // Start with defaults\n let config = deepMerge({} as SkillTreeConfig, DEFAULT_CONFIG);\n\n // Apply file config\n const fileConfig = loadConfigFromFile(this.configPath);\n if (fileConfig) {\n config = deepMerge(config, fileConfig as Partial<SkillTreeConfig>);\n }\n\n // Apply environment variables (highest priority)\n const envConfig = loadConfigFromEnv();\n config = deepMerge(config, envConfig as Partial<SkillTreeConfig>);\n\n // Expand paths\n config.storage.path = expandPath(config.storage.path);\n\n this.config = config;\n this.loaded = true;\n\n return this.config;\n }\n\n /**\n * Get current configuration\n */\n getConfig(): SkillTreeConfig {\n if (!this.loaded) {\n return this.load();\n }\n return this.config;\n }\n\n /**\n * Override configuration with partial values\n */\n override(overrides: PartialSkillTreeConfig): SkillTreeConfig {\n this.config = deepMerge(this.getConfig(), overrides as Partial<SkillTreeConfig>);\n return this.config;\n }\n\n /**\n * Get a specific config value by path\n */\n get<T>(path: string): T | undefined {\n const parts = path.split('.');\n let current: unknown = this.getConfig();\n\n for (const part of parts) {\n if (current === null || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n\n return current as T;\n }\n\n /**\n * Check if config file exists\n */\n configFileExists(): boolean {\n return fs.existsSync(expandPath(this.configPath));\n }\n\n /**\n * Create default config file\n */\n createDefaultConfigFile(): void {\n const configDir = path.dirname(expandPath(this.configPath));\n\n // Ensure directory exists\n if (!fs.existsSync(configDir)) {\n fs.mkdirSync(configDir, { recursive: true });\n }\n\n const configContent = `# Skill Tree Configuration\n# Generated by skill-tree\n\nstorage:\n # Path to .skilltree directory (skills stored as files, SQLite cache auto-generated)\n path: ~/.skill-tree\n\nindexer:\n # GitHub token for API access (or use GITHUB_TOKEN env var)\n github_token: \\${GITHUB_TOKEN}\n # Anthropic API key for classification (or use ANTHROPIC_API_KEY env var)\n anthropic_key: \\${ANTHROPIC_API_KEY}\n sources: []\n batch_size: 10\n min_confidence: 0.7\n\nmatching:\n embedding_model: text-embedding-3-small\n similarity_threshold: 0.8\n\nsync:\n auto_check: false\n check_interval_hours: 24\n conflict_resolution: prompt\n\ncli:\n output_format: table\n color: true\n quiet: false\n\nmaterialization:\n # Enable automatic materialization to agent-discoverable paths\n enabled: false\n # Mode: 'symlink' (default) or 'copy'\n mode: symlink\n # Directories to expose skills in (e.g. .claude/skills, .agent/skills)\n symlink_paths: []\n # Path to auto-generate AGENTS.md (empty = disabled)\n agents_md_path: \"\"\n # Format for AGENTS.md: xml, markdown, json\n agents_md_format: xml\n # Debounce interval in ms for batch updates\n debounce_ms: 500\n`;\n\n fs.writeFileSync(expandPath(this.configPath), configContent);\n }\n}\n\n// Global config instance\nlet globalConfig: ConfigLoader | null = null;\n\n/**\n * Get the global config loader instance\n */\nexport function getConfigLoader(configPath?: string): ConfigLoader {\n if (!globalConfig) {\n globalConfig = new ConfigLoader(configPath);\n }\n return globalConfig;\n}\n\n/**\n * Load and return the global configuration\n */\nexport function loadConfig(configPath?: string): SkillTreeConfig {\n return getConfigLoader(configPath).load();\n}\n\n/**\n * Reset the global config instance (useful for testing)\n */\nexport function resetConfig(): void {\n globalConfig = null;\n}\n","/**\n * Converts skill indexer format to skill-tree format\n * Adapted from scraper/src/compat/converter.ts for direct use in skill-tree\n */\n\nimport type { Skill } from '../types.js';\n\n/**\n * Indexer skill format (from scraper export)\n */\nexport interface IndexerSkill {\n id: string;\n slug: string;\n name: string;\n displayName?: string;\n sourceRepo: string;\n sourcePath: string;\n sourceUrl: string;\n author: string;\n description: string;\n content: string;\n version: string;\n homepage?: string;\n metadata?: Record<string, unknown>;\n status: 'raw' | 'indexed' | 'failed';\n indexedAt?: string;\n indexingError?: string;\n scrapedAt: string;\n updatedAt: string;\n publishedAt?: string;\n // Indexed skill fields\n primaryPath?: string[];\n secondaryPaths?: string[][];\n confidence?: number;\n classificationReasoning?: string;\n tags?: string[];\n}\n\n/**\n * Indexer export format (full export with metadata)\n */\nexport interface IndexerExport {\n exportedAt: string;\n stats?: {\n totalSkills: number;\n indexedSkills: number;\n rawSkills: number;\n failedSkills: number;\n };\n taxonomy?: unknown;\n skills: IndexerSkill[];\n}\n\n\n/**\n * Conversion result with warnings\n */\nexport interface ConversionResult {\n skill: Skill;\n warnings: string[];\n hasStructuredContent: boolean;\n}\n\n/**\n * Convert a single indexer skill to skill-tree format\n */\nexport function convertIndexerSkill(indexerSkill: IndexerSkill): ConversionResult {\n const warnings: string[] = [];\n\n // The markdown body becomes the instructions directly\n const instructions = indexerSkill.content || '';\n const hasStructuredContent = instructions.trim().length > 0;\n\n if (!hasStructuredContent) {\n warnings.push('No content found, instructions will be empty');\n }\n\n // Build tags array\n const tags: string[] = [...(indexerSkill.tags || [])];\n if (indexerSkill.sourceRepo) {\n const repoName = indexerSkill.sourceRepo.split('/').pop();\n if (repoName && !tags.includes(repoName)) {\n tags.push(repoName);\n }\n }\n\n // Map status\n const status = indexerSkill.status === 'indexed' ? 'active' :\n indexerSkill.status === 'raw' ? 'draft' : 'draft';\n\n const skill: Skill = {\n id: indexerSkill.slug,\n name: indexerSkill.displayName || indexerSkill.name,\n version: indexerSkill.version,\n description: indexerSkill.description,\n instructions,\n author: indexerSkill.author,\n tags,\n createdAt: new Date(indexerSkill.scrapedAt),\n updatedAt: new Date(indexerSkill.updatedAt),\n status,\n metrics: {\n usageCount: 0,\n successRate: 0,\n feedbackScores: [],\n },\n source: {\n type: 'imported',\n location: indexerSkill.sourceUrl,\n importedAt: new Date(),\n },\n // Extended fields for indexed skills\n taxonomy: indexerSkill.primaryPath ? {\n primaryPath: indexerSkill.primaryPath,\n secondaryPaths: indexerSkill.secondaryPaths,\n confidence: indexerSkill.confidence,\n } : undefined,\n externalSource: {\n url: indexerSkill.sourceUrl,\n repo: indexerSkill.sourceRepo,\n scrapedAt: new Date(indexerSkill.scrapedAt),\n },\n };\n\n return { skill, warnings, hasStructuredContent };\n}\n\n/**\n * Convert multiple indexer skills to skill-tree format\n */\nexport function convertIndexerSkills(skills: IndexerSkill[]): {\n skills: Skill[];\n results: ConversionResult[];\n stats: {\n total: number;\n withStructuredContent: number;\n withWarnings: number;\n };\n} {\n const results: ConversionResult[] = [];\n const converted: Skill[] = [];\n\n for (const skill of skills) {\n const result = convertIndexerSkill(skill);\n results.push(result);\n converted.push(result.skill);\n }\n\n return {\n skills: converted,\n results,\n stats: {\n total: results.length,\n withStructuredContent: results.filter(r => r.hasStructuredContent).length,\n withWarnings: results.filter(r => r.warnings.length > 0).length,\n },\n };\n}\n\n/**\n * Parse and convert an indexer export file\n */\nexport function parseIndexerExport(content: string): {\n skills: Skill[];\n stats: {\n total: number;\n withStructuredContent: number;\n withWarnings: number;\n };\n exportMetadata?: {\n exportedAt: string;\n originalStats?: IndexerExport['stats'];\n };\n} {\n const data = JSON.parse(content);\n\n // Detect format: full export vs skill array\n let indexerSkills: IndexerSkill[];\n let exportMetadata: { exportedAt: string; originalStats?: IndexerExport['stats'] } | undefined;\n\n if (Array.isArray(data)) {\n // Direct array of skills\n indexerSkills = data;\n } else if (data.skills && Array.isArray(data.skills)) {\n // Full export format\n indexerSkills = data.skills;\n exportMetadata = {\n exportedAt: data.exportedAt,\n originalStats: data.stats,\n };\n } else {\n throw new Error('Invalid indexer export format: expected array or object with skills array');\n }\n\n const { skills, stats } = convertIndexerSkills(indexerSkills);\n return { skills, stats, exportMetadata };\n}\n"],"mappings":"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","names":["path","fs","Database","row","fs","path","fs","path","path","DEFAULT_CONFIG","DEFAULT_CONFIG","DEFAULT_CONFIG","path","result","fs","path","fs","path","fs","path","DEFAULT_CONFIG","fs","path","fs","path","SQLiteStorageAdapter","fs","path","generateAgentsMd","path","fs","DEFAULT_CONFIG","fs","path","path","DEFAULT_CONFIG"]}