skill-tree 0.1.2 → 0.1.3

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/types.ts","../../src/validation/types.ts","../../src/validation/validator.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/matching/embeddings.ts","../../src/matching/matcher.ts","../../src/composer/dependency-graph.ts","../../src/composer/composer.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/adapters/base.ts","../../src/adapters/claude-code.ts","../../src/adapters/openai.ts","../../src/adapters/anthropic.ts","../../src/adapters/generic.ts","../../src/adapters/index.ts","../../src/extraction/quality-gates.ts","../../src/extraction/base.ts","../../src/extraction/manual.ts","../../src/extraction/automatic.ts","../../src/storage/base.ts","../../src/storage/filesystem.ts","../../src/storage/sqlite.ts","../../src/versioning/lineage.ts","../../src/hooks/registry.ts","../../src/hooks/activation.ts","../../src/hooks/types.ts","../../src/skill-bank.ts","../../src/sync/git-sync-adapter.ts","../../src/sync/conflict-store.ts","../../src/sync/index.ts","../../src/mcp/tools/loadout-tools.ts","../../src/mcp/tools/skill-tools.ts","../../src/mcp/tools/index.ts","../../src/mcp/handlers.ts","../../src/mcp/server.ts","../../src/index.ts","../../src/config/types.ts","../../src/config/loader.ts","../../src/cli/commands/list.ts","../../src/cli/utils/paths.ts","../../src/cli/utils/skillbank.ts","../../src/cli/utils/output.ts","../../src/cli/commands/show.ts","../../src/cli/commands/search.ts","../../src/cli/commands/stats.ts","../../src/cli/commands/versions.ts","../../src/cli/commands/diff.ts","../../src/cli/commands/rollback.ts","../../src/cli/commands/fork.ts","../../src/cli/commands/deprecate.ts","../../src/cli/commands/activate.ts","../../src/cli/commands/delete.ts","../../src/cli/commands/export.ts","../../src/cli/commands/import.ts","../../src/import/converter.ts","../../src/import/detect.ts","../../src/cli/commands/indexer/index.ts","../../src/cli/commands/indexer/scrape.ts","../../src/services/indexer.ts","../../src/cli/commands/indexer/classify.ts","../../src/cli/commands/indexer/taxonomy.ts","../../src/cli/commands/indexer/relationships.ts","../../src/cli/commands/indexer/stats.ts","../../src/cli/commands/indexer/sync.ts","../../src/services/sync.ts","../../src/cli/commands/config.ts","../../src/cli/commands/sync.ts","../../src/cli/commands/mcp.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * skill-tree CLI\n * Management tool for agent skills\n */\n\nimport { Command } from 'commander';\nimport { VERSION } from '../index.js';\nimport { loadConfig, getConfigPath } from '../config/index.js';\nimport { listCommand } from './commands/list.js';\nimport { showCommand } from './commands/show.js';\nimport { searchCommand } from './commands/search.js';\nimport { statsCommand } from './commands/stats.js';\nimport { versionsCommand } from './commands/versions.js';\nimport { diffCommand } from './commands/diff.js';\nimport { rollbackCommand } from './commands/rollback.js';\nimport { forkCommand } from './commands/fork.js';\nimport { deprecateCommand } from './commands/deprecate.js';\nimport { activateCommand } from './commands/activate.js';\nimport { deleteCommand } from './commands/delete.js';\nimport { exportCommand } from './commands/export.js';\nimport { importCommand } from './commands/import.js';\nimport { indexerCommand } from './commands/indexer/index.js';\nimport { configCommand } from './commands/config.js';\nimport { syncCommand } from './commands/sync.js';\nimport { mcpCommand } from './commands/mcp.js';\n\nconst program = new Command();\n\n// Load configuration\nconst config = loadConfig();\n\nprogram\n .name('skill-tree')\n .description('Management CLI for agent skills')\n .version(VERSION)\n .option('-p, --path <dir>', 'Skills directory path', config.storage.path)\n .option('-c, --config <file>', 'Config file path', getConfigPath())\n .option('--json', 'Output as JSON', config.cli.output_format === 'json')\n .option('-q, --quiet', 'Suppress non-essential output', config.cli.quiet)\n .option('--no-color', 'Disable colored output', !config.cli.color);\n\n// Register commands\nprogram.addCommand(listCommand);\nprogram.addCommand(showCommand);\nprogram.addCommand(searchCommand);\nprogram.addCommand(statsCommand);\nprogram.addCommand(versionsCommand);\nprogram.addCommand(diffCommand);\nprogram.addCommand(rollbackCommand);\nprogram.addCommand(forkCommand);\nprogram.addCommand(deprecateCommand);\nprogram.addCommand(activateCommand);\nprogram.addCommand(deleteCommand);\nprogram.addCommand(exportCommand);\nprogram.addCommand(importCommand);\nprogram.addCommand(indexerCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(syncCommand);\nprogram.addCommand(mcpCommand);\n\n// Parse and execute\nprogram.parse();\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 (Claudeception-inspired structure)\n /** What problem does this skill solve? */\n problem: string;\n /** When should this skill be triggered? */\n triggerConditions: TriggerCondition[];\n /** Step-by-step solution */\n solution: string;\n /** How to verify the skill worked */\n verification: string;\n /** Concrete examples of usage */\n examples: SkillExample[];\n /** Additional notes, caveats, edge cases */\n notes?: 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 // Validation\n /** Last validation result (stored as summary for space efficiency) */\n lastValidation?: SkillValidationSummary;\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\nexport interface TriggerCondition {\n /** Type of trigger */\n type: 'error' | 'pattern' | 'context' | 'keyword' | 'custom';\n /** The actual condition (regex, keyword, description) */\n value: string;\n /** Optional description of when this triggers */\n description?: string;\n}\n\nexport interface SkillExample {\n /** Description of the scenario */\n scenario: string;\n /** Input/before state */\n before: string;\n /** Output/after state */\n after: string;\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\n/**\n * Compact validation result stored in skill\n */\nexport interface SkillValidationSummary {\n /** Validation status */\n status: 'passed' | 'failed' | 'partial' | 'skipped' | 'error';\n /** Pass rate (0-1) */\n passRate: number;\n /** Number of tests passed */\n passedCount: number;\n /** Number of tests failed */\n failedCount: number;\n /** When validation was run */\n validatedAt: Date;\n /** Recommended action */\n recommendedAction?: 'none' | 'review' | 'update' | 'deprecate' | 'delete';\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// TRAJECTORY / SESSION TYPES\n// =============================================================================\n\n/**\n * Represents a parsed agent session/trajectory\n */\nexport interface Trajectory {\n /** Unique session identifier */\n sessionId: string;\n /** When the session started */\n startedAt: Date;\n /** When the session ended */\n endedAt?: Date;\n /** The messages/turns in this session */\n turns: Turn[];\n /** Overall session metadata */\n metadata: TrajectoryMetadata;\n /** Session outcome */\n outcome?: TrajectoryOutcome;\n}\n\nexport interface Turn {\n /** Turn index (0-based) */\n index: number;\n /** Role: user, assistant, system, tool */\n role: 'user' | 'assistant' | 'system' | 'tool';\n /** Content of the turn */\n content: string;\n /** Tool calls made in this turn */\n toolCalls?: ToolCall[];\n /** Tool results returned in this turn */\n toolResults?: ToolResult[];\n /** Timestamp of this turn */\n timestamp?: Date;\n /** Extension data from custom extractors */\n [key: string]: unknown;\n}\n\nexport interface ToolCall {\n /** Tool name */\n name: string;\n /** Tool input/arguments */\n input: Record<string, unknown>;\n /** Unique call ID */\n callId?: string;\n}\n\nexport interface ToolResult {\n /** Corresponding call ID */\n callId?: string;\n /** Tool name */\n name: string;\n /** Result content */\n output: string;\n /** Whether the tool succeeded */\n success: boolean;\n /** Error message if failed */\n error?: string;\n}\n\nexport interface TrajectoryMetadata {\n /** Agent type (claude-code, custom, etc.) */\n agentType: string;\n /** Model used */\n model?: string;\n /** Working directory */\n workingDirectory?: string;\n /** Project/repo name */\n projectName?: string;\n /** Custom metadata */\n custom?: Record<string, unknown>;\n}\n\nexport interface TrajectoryOutcome {\n /** Did the session succeed in its goal? */\n success: boolean;\n /** Summary of what was accomplished */\n summary?: string;\n /** Files modified */\n filesModified?: string[];\n /** Errors encountered */\n errors?: string[];\n /** User satisfaction signal if available */\n userSatisfaction?: 'positive' | 'negative' | 'neutral';\n}\n\n// =============================================================================\n// EXTRACTION TYPES\n// =============================================================================\n\n/**\n * Configuration for skill extraction\n */\nexport interface ExtractionConfig {\n /** Extraction mode */\n mode: 'manual' | 'automatic' | 'hybrid';\n /** Quality gates to apply */\n qualityGates: QualityGate[];\n /** Minimum confidence score (0-1) for automatic extraction */\n minConfidence?: number;\n /** LLM to use for extraction (if automatic) */\n llmProvider?: LLMProvider;\n}\n\nexport interface QualityGate {\n /** Gate name */\n name: string;\n /** Gate type */\n type: 'reusability' | 'non-trivial' | 'verified' | 'specific' | 'custom';\n /** Description of what this gate checks */\n description: string;\n /** Whether this gate is required to pass */\n required: boolean;\n}\n\n/**\n * Result of extraction attempt\n */\nexport interface ExtractionResult {\n /** Whether extraction succeeded */\n success: boolean;\n /** Extracted skill (if successful) */\n skill?: Skill;\n /** Confidence score (0-1) */\n confidence: number;\n /** Quality gate results */\n gateResults: QualityGateResult[];\n /** Reason for failure (if failed) */\n failureReason?: string;\n /** Source trajectory info */\n sourceTrajectory: {\n sessionId: string;\n turnRange: [number, number];\n };\n}\n\nexport interface QualityGateResult {\n /** Gate name */\n gateName: string;\n /** Whether the gate passed */\n passed: boolean;\n /** Score (0-1) */\n score: number;\n /** Explanation */\n explanation: string;\n}\n\n/**\n * Manual extraction request\n */\nexport interface ManualExtractionRequest {\n /** Session to extract from (optional, can be inferred from trajectory) */\n sessionId?: string;\n /** Turn range to extract [start, end] */\n turnRange?: [number, number];\n /** Suggested skill name */\n suggestedName?: string;\n /** User-provided description */\n description?: string;\n /** Tags to apply */\n tags?: string[];\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 /** Storage type */\n type: 'filesystem' | 'sqlite' | 'memory';\n /** Base path for filesystem storage */\n basePath?: string;\n /** Whether to use OpenSkills-compatible format */\n openSkillsCompatible?: boolean;\n}\n\n// =============================================================================\n// SESSION ADAPTER TYPES\n// =============================================================================\n\n/**\n * Adapter for parsing different session formats\n */\nexport interface SessionAdapter {\n /** Adapter name */\n name: string;\n /** Supported file extensions */\n supportedExtensions: string[];\n\n /** Check if this adapter can handle the given input */\n canHandle(input: string | Buffer): boolean;\n\n /** Parse raw input into a Trajectory */\n parse(input: string | Buffer): Promise<Trajectory>;\n\n /** Parse multiple sessions from a directory or file */\n parseMany(input: string): Promise<Trajectory[]>;\n}\n\n// =============================================================================\n// LLM PROVIDER TYPES (for automatic extraction)\n// =============================================================================\n\nexport interface LLMProvider {\n /** Provider name */\n name: string;\n\n /** Generate completion */\n complete(prompt: string, options?: LLMOptions): Promise<string>;\n\n /** Generate structured output */\n completeStructured<T>(prompt: string, schema: object, options?: LLMOptions): Promise<T>;\n}\n\nexport interface LLMOptions {\n temperature?: number;\n maxTokens?: number;\n model?: string;\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 | { type: 'extraction:started'; sessionId: string }\n | { type: 'extraction:completed'; result: ExtractionResult }\n | { type: 'extraction:failed'; error: string };\n\nexport type SkillTreeEventHandler = (event: SkillTreeEvent) => void | Promise<void>;\n","/**\n * Skill Validation Types\n */\n\nimport type { Skill } from '../types.js';\n\n/**\n * Validation test case\n */\nexport interface ValidationTestCase {\n /** Test name/description */\n name: string;\n /** Input/scenario to test */\n input: string;\n /** Expected outcome (regex pattern or exact match) */\n expectedOutcome?: string;\n /** Whether the outcome should match or not match */\n shouldMatch?: boolean;\n /** Timeout in ms for the test */\n timeout?: number;\n /** Tags for categorizing tests */\n tags?: string[];\n}\n\n/**\n * Result of a single test case\n */\nexport interface TestCaseResult {\n /** Test case that was run */\n testCase: ValidationTestCase;\n /** Whether the test passed */\n passed: boolean;\n /** Actual output/result */\n actualOutput?: string;\n /** Error message if test failed */\n error?: string;\n /** Execution time in ms */\n executionTimeMs: number;\n /** When the test was run */\n timestamp: Date;\n}\n\n/**\n * Result of validating a skill\n */\nexport interface SkillValidationResult {\n /** Skill that was validated */\n skillId: string;\n /** Skill version */\n version: string;\n /** Overall validation status */\n status: 'passed' | 'failed' | 'partial' | 'skipped' | 'error';\n /** Individual test results */\n testResults: TestCaseResult[];\n /** Number of passed tests */\n passedCount: number;\n /** Number of failed tests */\n failedCount: number;\n /** Overall pass rate (0-1) */\n passRate: number;\n /** When validation was run */\n validatedAt: Date;\n /** Duration of validation in ms */\n durationMs: number;\n /** Warnings/suggestions */\n warnings: string[];\n /** Recommendation based on results */\n recommendation?: ValidationRecommendation;\n}\n\n/**\n * Validation recommendation\n */\nexport interface ValidationRecommendation {\n /** Action to take */\n action: 'none' | 'review' | 'update' | 'deprecate' | 'delete';\n /** Reason for recommendation */\n reason: string;\n /** Confidence in recommendation (0-1) */\n confidence: number;\n}\n\n/**\n * Validation schedule entry\n */\nexport interface ValidationSchedule {\n /** Skill ID */\n skillId: string;\n /** Validation frequency in days */\n frequencyDays: number;\n /** Last validation timestamp */\n lastValidated?: Date;\n /** Next scheduled validation */\n nextValidation: Date;\n /** Whether validation is enabled */\n enabled: boolean;\n /** Priority (lower = higher priority) */\n priority: number;\n}\n\n/**\n * Skill validator configuration\n */\nexport interface ValidatorConfig {\n /** Default timeout for tests in ms (default: 5000) */\n defaultTimeout?: number;\n /** Minimum pass rate to consider skill valid (default: 0.8) */\n minPassRate?: number;\n /** Days without use before suggesting deprecation (default: 90) */\n deprecationThresholdDays?: number;\n /** Minimum tests required for meaningful validation (default: 1) */\n minTests?: number;\n /** Enable automatic test generation (default: false) */\n autoGenerateTests?: boolean;\n /** Custom test runner function */\n testRunner?: TestRunner;\n}\n\n/**\n * Test runner function type\n */\nexport type TestRunner = (\n skill: Skill,\n testCase: ValidationTestCase\n) => Promise<TestCaseResult>;\n\n/**\n * Version compatibility check result\n */\nexport interface CompatibilityCheckResult {\n /** Skill ID */\n skillId: string;\n /** Version being checked */\n version: string;\n /** Whether version is compatible */\n isCompatible: boolean;\n /** Compatibility issues found */\n issues: CompatibilityIssue[];\n /** Suggested fixes */\n suggestions: string[];\n}\n\n/**\n * Compatibility issue\n */\nexport interface CompatibilityIssue {\n /** Issue type */\n type: 'breaking' | 'warning' | 'info';\n /** Field/area affected */\n field: string;\n /** Description of the issue */\n description: string;\n /** How to fix */\n fix?: string;\n}\n\n/**\n * Default validator configuration\n */\nexport const DEFAULT_VALIDATOR_CONFIG: Required<Omit<ValidatorConfig, 'testRunner'>> = {\n defaultTimeout: 5000,\n minPassRate: 0.8,\n deprecationThresholdDays: 90,\n minTests: 1,\n autoGenerateTests: false,\n};\n","/**\n * Skill Validator - Validates skills and suggests deprecations\n */\n\nimport type { Skill, StorageAdapter } from '../types.js';\nimport type {\n ValidatorConfig,\n ValidationTestCase,\n TestCaseResult,\n SkillValidationResult,\n ValidationRecommendation,\n ValidationSchedule,\n CompatibilityCheckResult,\n CompatibilityIssue,\n TestRunner,\n} from './types.js';\nimport { DEFAULT_VALIDATOR_CONFIG } from './types.js';\n\n/**\n * Main skill validator class\n */\nexport class SkillValidator {\n private config: Required<Omit<ValidatorConfig, 'testRunner'>> & { testRunner?: TestRunner };\n private storage?: StorageAdapter;\n private schedules: Map<string, ValidationSchedule> = new Map();\n private testRegistry: Map<string, ValidationTestCase[]> = new Map();\n\n constructor(config?: ValidatorConfig) {\n this.config = { ...DEFAULT_VALIDATOR_CONFIG, ...config };\n }\n\n /**\n * Set the storage adapter\n */\n setStorage(storage: StorageAdapter): void {\n this.storage = storage;\n }\n\n /**\n * Register test cases for a skill\n */\n registerTests(skillId: string, tests: ValidationTestCase[]): void {\n this.testRegistry.set(skillId, tests);\n }\n\n /**\n * Get registered tests for a skill\n */\n getTests(skillId: string): ValidationTestCase[] {\n return this.testRegistry.get(skillId) || [];\n }\n\n /**\n * Validate a skill\n */\n async validateSkill(skill: Skill, tests?: ValidationTestCase[]): Promise<SkillValidationResult> {\n const startTime = Date.now();\n const testCases = tests || this.testRegistry.get(skill.id) || [];\n const warnings: string[] = [];\n\n // Check if we have enough tests\n if (testCases.length < this.config.minTests) {\n if (this.config.autoGenerateTests) {\n const generated = this.generateTestsFromSkill(skill);\n testCases.push(...generated);\n warnings.push(`Auto-generated ${generated.length} test(s) from skill content`);\n } else {\n return {\n skillId: skill.id,\n version: skill.version,\n status: 'skipped',\n testResults: [],\n passedCount: 0,\n failedCount: 0,\n passRate: 0,\n validatedAt: new Date(),\n durationMs: Date.now() - startTime,\n warnings: [`Insufficient tests (${testCases.length}/${this.config.minTests} required)`],\n };\n }\n }\n\n // Run tests\n const testResults: TestCaseResult[] = [];\n for (const testCase of testCases) {\n const result = await this.runTest(skill, testCase);\n testResults.push(result);\n }\n\n // Calculate results\n const passedCount = testResults.filter((r) => r.passed).length;\n const failedCount = testResults.filter((r) => !r.passed).length;\n const passRate = testResults.length > 0 ? passedCount / testResults.length : 0;\n\n // Determine status\n let status: SkillValidationResult['status'];\n if (testResults.length === 0) {\n status = 'skipped';\n } else if (passRate >= this.config.minPassRate) {\n status = 'passed';\n } else if (passRate > 0) {\n status = 'partial';\n } else {\n status = 'failed';\n }\n\n // Generate recommendation\n const recommendation = this.generateRecommendation(skill, passRate, testResults);\n\n // Update schedule\n this.updateSchedule(skill.id, new Date());\n\n return {\n skillId: skill.id,\n version: skill.version,\n status,\n testResults,\n passedCount,\n failedCount,\n passRate,\n validatedAt: new Date(),\n durationMs: Date.now() - startTime,\n warnings,\n recommendation,\n };\n }\n\n /**\n * Validate all skills in storage\n */\n async validateAll(): Promise<Map<string, SkillValidationResult>> {\n if (!this.storage) {\n throw new Error('Storage not set. Call setStorage() first.');\n }\n\n const skills = await this.storage.listSkills({ status: ['active', 'experimental'] });\n const results = new Map<string, SkillValidationResult>();\n\n for (const skill of skills) {\n const result = await this.validateSkill(skill);\n results.set(skill.id, result);\n }\n\n return results;\n }\n\n /**\n * Get skills that need validation\n */\n async getSkillsNeedingValidation(): Promise<Skill[]> {\n if (!this.storage) {\n throw new Error('Storage not set. Call setStorage() first.');\n }\n\n const skills = await this.storage.listSkills({ status: ['active'] });\n const now = new Date();\n const needsValidation: Skill[] = [];\n\n for (const skill of skills) {\n const schedule = this.schedules.get(skill.id);\n if (!schedule || !schedule.enabled) {\n needsValidation.push(skill);\n } else if (schedule.nextValidation <= now) {\n needsValidation.push(skill);\n }\n }\n\n return needsValidation;\n }\n\n /**\n * Suggest deprecations based on validation results\n */\n async suggestDeprecations(): Promise<Array<{ skill: Skill; reason: string; confidence: number }>> {\n if (!this.storage) {\n throw new Error('Storage not set. Call setStorage() first.');\n }\n\n const skills = await this.storage.listSkills({ status: ['active'] });\n const suggestions: Array<{ skill: Skill; reason: string; confidence: number }> = [];\n\n for (const skill of skills) {\n // Check validation results\n const tests = this.testRegistry.get(skill.id);\n if (tests && tests.length > 0) {\n const result = await this.validateSkill(skill, tests);\n if (result.recommendation?.action === 'deprecate') {\n suggestions.push({\n skill,\n reason: result.recommendation.reason,\n confidence: result.recommendation.confidence,\n });\n continue;\n }\n }\n\n // Check for stale skills\n const daysSinceUpdate = (Date.now() - skill.updatedAt.getTime()) / (24 * 60 * 60 * 1000);\n if (daysSinceUpdate > this.config.deprecationThresholdDays) {\n const lastUsed = skill.metrics.lastUsed;\n const daysSinceUse = lastUsed\n ? (Date.now() - lastUsed.getTime()) / (24 * 60 * 60 * 1000)\n : daysSinceUpdate;\n\n if (daysSinceUse > this.config.deprecationThresholdDays) {\n suggestions.push({\n skill,\n reason: `Skill not used in ${Math.floor(daysSinceUse)} days`,\n confidence: Math.min(0.9, daysSinceUse / (this.config.deprecationThresholdDays * 2)),\n });\n }\n }\n\n // Check for low success rate\n if (skill.metrics.usageCount >= 5 && skill.metrics.successRate < 0.3) {\n suggestions.push({\n skill,\n reason: `Low success rate: ${(skill.metrics.successRate * 100).toFixed(1)}%`,\n confidence: 0.7,\n });\n }\n }\n\n // Sort by confidence (highest first)\n return suggestions.sort((a, b) => b.confidence - a.confidence);\n }\n\n /**\n * Check version compatibility\n */\n checkVersionCompatibility(\n skill: Skill,\n previousVersion?: Skill\n ): CompatibilityCheckResult {\n const issues: CompatibilityIssue[] = [];\n const suggestions: string[] = [];\n\n if (!previousVersion) {\n return {\n skillId: skill.id,\n version: skill.version,\n isCompatible: true,\n issues: [],\n suggestions: [],\n };\n }\n\n // Check for breaking changes in triggers\n const oldTriggers = new Set(previousVersion.triggerConditions.map((t) => t.value));\n const newTriggers = new Set(skill.triggerConditions.map((t) => t.value));\n\n for (const oldTrigger of oldTriggers) {\n if (!newTriggers.has(oldTrigger)) {\n issues.push({\n type: 'breaking',\n field: 'triggerConditions',\n description: `Removed trigger: \"${oldTrigger}\"`,\n fix: 'Consider keeping the old trigger or adding a migration path',\n });\n }\n }\n\n // Check for solution changes\n if (skill.solution !== previousVersion.solution) {\n const oldSolutionLength = previousVersion.solution.length;\n const newSolutionLength = skill.solution.length;\n const changePct = Math.abs(newSolutionLength - oldSolutionLength) / Math.max(oldSolutionLength, 1);\n\n if (changePct > 0.5) {\n issues.push({\n type: 'warning',\n field: 'solution',\n description: `Solution changed significantly (${(changePct * 100).toFixed(0)}% difference)`,\n fix: 'Update tests to reflect new solution',\n });\n }\n }\n\n // Check for problem redefinition\n if (skill.problem !== previousVersion.problem) {\n issues.push({\n type: 'warning',\n field: 'problem',\n description: 'Problem statement changed',\n fix: 'Ensure the skill still addresses the original use case',\n });\n }\n\n // Check version bump appropriateness\n const [oldMajor, oldMinor] = previousVersion.version.split('.').map(Number);\n const [newMajor, newMinor] = skill.version.split('.').map(Number);\n\n const hasBreakingChanges = issues.some((i) => i.type === 'breaking');\n if (hasBreakingChanges && newMajor <= oldMajor) {\n suggestions.push('Breaking changes detected - consider a major version bump');\n }\n\n const hasWarnings = issues.some((i) => i.type === 'warning');\n if (hasWarnings && newMinor <= oldMinor && newMajor === oldMajor) {\n suggestions.push('Significant changes detected - consider a minor version bump');\n }\n\n return {\n skillId: skill.id,\n version: skill.version,\n isCompatible: !hasBreakingChanges,\n issues,\n suggestions,\n };\n }\n\n /**\n * Set validation schedule for a skill\n */\n setSchedule(skillId: string, frequencyDays: number, priority: number = 5): void {\n const now = new Date();\n this.schedules.set(skillId, {\n skillId,\n frequencyDays,\n lastValidated: undefined,\n nextValidation: now,\n enabled: true,\n priority,\n });\n }\n\n /**\n * Get validation schedule for a skill\n */\n getSchedule(skillId: string): ValidationSchedule | undefined {\n return this.schedules.get(skillId);\n }\n\n /**\n * Disable validation schedule\n */\n disableSchedule(skillId: string): void {\n const schedule = this.schedules.get(skillId);\n if (schedule) {\n schedule.enabled = false;\n }\n }\n\n /**\n * Get all scheduled validations\n */\n getScheduledValidations(): ValidationSchedule[] {\n return Array.from(this.schedules.values())\n .filter((s) => s.enabled)\n .sort((a, b) => a.nextValidation.getTime() - b.nextValidation.getTime());\n }\n\n // Private methods\n\n /**\n * Run a single test case\n */\n private async runTest(skill: Skill, testCase: ValidationTestCase): Promise<TestCaseResult> {\n const startTime = Date.now();\n const timeout = testCase.timeout || this.config.defaultTimeout;\n\n try {\n // Use custom test runner if provided\n if (this.config.testRunner) {\n return await Promise.race([\n this.config.testRunner(skill, testCase),\n this.timeoutPromise<TestCaseResult>(timeout, testCase),\n ]);\n }\n\n // Default test runner: pattern matching\n const result = await Promise.race([\n this.defaultTestRunner(skill, testCase),\n this.timeoutPromise<TestCaseResult>(timeout, testCase),\n ]);\n\n return result;\n } catch (error) {\n return {\n testCase,\n passed: false,\n error: (error as Error).message,\n executionTimeMs: Date.now() - startTime,\n timestamp: new Date(),\n };\n }\n }\n\n /**\n * Default test runner using pattern matching\n */\n private async defaultTestRunner(skill: Skill, testCase: ValidationTestCase): Promise<TestCaseResult> {\n const startTime = Date.now();\n\n // Check if input matches trigger conditions\n const matchesTrigger = skill.triggerConditions.some((trigger) => {\n try {\n if (trigger.type === 'pattern' || trigger.type === 'error') {\n const regex = new RegExp(trigger.value, 'i');\n return regex.test(testCase.input);\n }\n return testCase.input.toLowerCase().includes(trigger.value.toLowerCase());\n } catch {\n return false;\n }\n });\n\n // Determine if test passed\n let passed: boolean;\n if (testCase.expectedOutcome) {\n try {\n const regex = new RegExp(testCase.expectedOutcome, 'i');\n const matches = regex.test(skill.solution) || regex.test(skill.problem);\n passed = testCase.shouldMatch !== false ? matches : !matches;\n } catch {\n passed = skill.solution.includes(testCase.expectedOutcome) ||\n skill.problem.includes(testCase.expectedOutcome);\n }\n } else {\n // Just check if skill would trigger\n passed = matchesTrigger;\n }\n\n return {\n testCase,\n passed,\n actualOutput: matchesTrigger ? 'Skill triggered' : 'Skill did not trigger',\n executionTimeMs: Date.now() - startTime,\n timestamp: new Date(),\n };\n }\n\n /**\n * Create a timeout promise\n */\n private timeoutPromise<T>(ms: number, testCase: ValidationTestCase): Promise<T> {\n return new Promise((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Test timed out after ${ms}ms: ${testCase.name}`));\n }, ms);\n });\n }\n\n /**\n * Generate tests from skill content\n */\n private generateTestsFromSkill(skill: Skill): ValidationTestCase[] {\n const tests: ValidationTestCase[] = [];\n\n // Generate tests from trigger conditions\n for (const trigger of skill.triggerConditions) {\n tests.push({\n name: `Trigger: ${trigger.type} - ${trigger.value.slice(0, 50)}`,\n input: trigger.value,\n expectedOutcome: trigger.value,\n shouldMatch: true,\n tags: ['auto-generated', 'trigger-test'],\n });\n }\n\n // Generate tests from examples\n for (const example of skill.examples) {\n if (example.before) {\n tests.push({\n name: `Example: ${example.scenario.slice(0, 50)}`,\n input: example.before,\n tags: ['auto-generated', 'example-test'],\n });\n }\n }\n\n return tests;\n }\n\n /**\n * Generate recommendation based on validation results\n */\n private generateRecommendation(\n skill: Skill,\n passRate: number,\n testResults: TestCaseResult[]\n ): ValidationRecommendation {\n // All tests pass\n if (passRate >= this.config.minPassRate) {\n return {\n action: 'none',\n reason: 'Skill is performing well',\n confidence: passRate,\n };\n }\n\n // Partial pass\n if (passRate > 0.5) {\n return {\n action: 'review',\n reason: `Pass rate (${(passRate * 100).toFixed(0)}%) below threshold (${this.config.minPassRate * 100}%)`,\n confidence: 1 - passRate,\n };\n }\n\n // Mostly failing\n if (passRate > 0) {\n return {\n action: 'update',\n reason: `Low pass rate: ${(passRate * 100).toFixed(0)}%`,\n confidence: 1 - passRate,\n };\n }\n\n // Complete failure\n return {\n action: 'deprecate',\n reason: 'All tests failed',\n confidence: 0.9,\n };\n }\n\n /**\n * Update validation schedule after running validation\n */\n private updateSchedule(skillId: string, validatedAt: Date): void {\n const schedule = this.schedules.get(skillId);\n if (schedule) {\n schedule.lastValidated = validatedAt;\n schedule.nextValidation = new Date(\n validatedAt.getTime() + schedule.frequencyDays * 24 * 60 * 60 * 1000\n );\n }\n }\n}\n\n/**\n * Create a skill validator\n */\nexport function createSkillValidator(config?: ValidatorConfig): SkillValidator {\n return new SkillValidator(config);\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 { SemanticMatcher, MatchContext } from '../matching/index.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 private semanticMatcher?: SemanticMatcher,\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 async applySemanticFilters(\n skills: Skill[],\n criteria: LoadoutCriteria\n ): Promise<Skill[]> {\n // Skip if no semantic criteria or no matcher\n if (!this.semanticMatcher) {\n return skills;\n }\n\n const hasSemanticCriteria =\n criteria.taskDescription ||\n criteria.problemContext ||\n criteria.errorContext ||\n (criteria.keywords && criteria.keywords.length > 0);\n\n if (!hasSemanticCriteria) {\n return skills;\n }\n\n // Build match context\n const context: MatchContext = {};\n\n if (criteria.taskDescription) {\n context.problemDescription = criteria.taskDescription;\n }\n if (criteria.problemContext) {\n context.problemDescription =\n (context.problemDescription || '') + ' ' + criteria.problemContext;\n }\n if (criteria.errorContext) {\n context.errorMessage = criteria.errorContext;\n }\n if (criteria.keywords) {\n context.keywords = criteria.keywords;\n }\n\n // Use semantic matcher to rank/filter\n const matches = await this.semanticMatcher.findByContext(context, skills, {\n threshold: this.config.semanticThreshold,\n maxResults: skills.length, // Don't limit yet, let applyLimits do that\n });\n\n // Return matched skills in relevance order\n return matches.map((m) => m.skill);\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.problem,\n skill.solution,\n skill.verification,\n skill.notes ?? '',\n ...skill.examples.map((e) => `${e.scenario} ${e.before} ${e.after}`),\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';\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 /** Include examples in expanded content */\n includeExamples?: boolean;\n}\n\n/**\n * Default configuration\n */\nconst DEFAULT_CONFIG: Required<ViewRendererConfig> = {\n includeTokenEstimates: false,\n maxSummaryLength: 150,\n includeExamples: true,\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(this.renderSkillContent(skill));\n lines.push(' </content>');\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(`**Problem:** ${skill.problem}`);\n lines.push('');\n lines.push(`**Solution:**`);\n lines.push(skill.solution);\n lines.push('');\n lines.push(`**Verification:** ${skill.verification}`);\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.name}`);\n lines.push('');\n lines.push('## Problem');\n lines.push('');\n lines.push(skill.problem);\n lines.push('');\n lines.push('## Solution');\n lines.push('');\n lines.push(skill.solution);\n lines.push('');\n lines.push('## Verification');\n lines.push('');\n lines.push(skill.verification);\n lines.push('');\n\n // Examples\n if (this.config.includeExamples && skill.examples.length > 0) {\n lines.push('## Examples');\n lines.push('');\n\n for (const example of skill.examples) {\n lines.push(`### ${example.scenario}`);\n lines.push('');\n lines.push('**Before:**');\n lines.push('```');\n lines.push(example.before);\n lines.push('```');\n lines.push('');\n lines.push('**After:**');\n lines.push('```');\n lines.push(example.after);\n lines.push('```');\n lines.push('');\n }\n }\n\n // Notes\n if (skill.notes) {\n lines.push('## Notes');\n lines.push('');\n lines.push(skill.notes);\n lines.push('');\n }\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 */\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 <= this.config.maxSummaryLength) {\n return firstSentence;\n }\n\n // Truncate if still too long\n return skill.description.substring(0, this.config.maxSummaryLength - 3) + '...';\n }\n\n /**\n * Render skill content for expanded view\n */\n private renderSkillContent(skill: Skill): string {\n const lines: string[] = [];\n\n lines.push('## Problem');\n lines.push(skill.problem);\n lines.push('');\n lines.push('## Solution');\n lines.push(skill.solution);\n lines.push('');\n lines.push('## Verification');\n lines.push(skill.verification);\n\n if (skill.notes) {\n lines.push('');\n lines.push('## Notes');\n lines.push(skill.notes);\n }\n\n if (this.config.includeExamples && skill.examples.length > 0) {\n lines.push('');\n lines.push('## Examples');\n for (const ex of skill.examples) {\n lines.push(`### ${ex.scenario}`);\n lines.push(`Before: ${ex.before}`);\n lines.push(`After: ${ex.after}`);\n }\n }\n\n // Indent all content\n return lines.map(line => ' ' + line).join('\\n');\n }\n\n /**\n * Escape special XML 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 * 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.problem,\n skill.solution,\n skill.verification,\n skill.notes ?? '',\n ...skill.examples.map(e => `${e.scenario} ${e.before} ${e.after}`),\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 { SemanticMatcher } from '../matching/index.js';\nimport type {\n LoadoutCriteria,\n LoadoutState,\n LoadoutSource,\n LoadoutView,\n SkillSummary,\n GraphServerConfig,\n ServingEvent,\n ServingEventHandler,\n EvictionStrategy,\n} from './types.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'>> & {\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 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'>> & {\n profiles: Record<string, LoadoutCriteria>;\n defaultProfile?: string;\n };\n private compiler: LoadoutCompiler;\n private projectDetector: ProjectDetector;\n private viewRenderer: ViewRenderer;\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 semanticMatcher?: SemanticMatcher\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, semanticMatcher);\n this.projectDetector = new ProjectDetector();\n this.viewRenderer = new ViewRenderer({\n includeTokenEstimates: this.config.includeTokenEstimates,\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 // 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.problem.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 // RENDERING\n // ===========================================================================\n\n /**\n * Render current state as system prompt content\n */\n renderSystemPrompt(): string {\n if (this.config.outputFormat === 'markdown') {\n return this.viewRenderer.renderMarkdown(this.state);\n }\n return this.viewRenderer.renderXml(this.state);\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 * Embedding provider interfaces and implementations\n */\n\n/**\n * Interface for embedding providers\n */\nexport interface EmbeddingProvider {\n /** Provider name */\n name: string;\n\n /** Dimension of the embedding vectors */\n dimensions: number;\n\n /** Generate embedding for a single text */\n embed(text: string): Promise<number[]>;\n\n /** Generate embeddings for multiple texts (batch) */\n embedBatch(texts: string[]): Promise<number[][]>;\n}\n\n/**\n * Options for embedding providers\n */\nexport interface EmbeddingProviderOptions {\n /** API key (if required) */\n apiKey?: string;\n /** Model name */\n model?: string;\n /** Base URL for API */\n baseUrl?: string;\n /** Additional options */\n options?: Record<string, unknown>;\n}\n\n/**\n * Simple hash-based embedding provider (for testing/development)\n * NOT suitable for production - use a real embedding model\n */\nexport class SimpleHashEmbedding implements EmbeddingProvider {\n name = 'simple-hash';\n dimensions = 64;\n\n async embed(text: string): Promise<number[]> {\n return this.hashToVector(text);\n }\n\n async embedBatch(texts: string[]): Promise<number[][]> {\n return texts.map((text) => this.hashToVector(text));\n }\n\n private hashToVector(text: string): number[] {\n const normalized = text.toLowerCase().trim();\n const vector: number[] = new Array(this.dimensions).fill(0);\n\n // Simple character-based hashing\n for (let i = 0; i < normalized.length; i++) {\n const charCode = normalized.charCodeAt(i);\n const idx = (charCode + i) % this.dimensions;\n vector[idx] += Math.sin(charCode * (i + 1)) * 0.1;\n }\n\n // Word-based features\n const words = normalized.split(/\\s+/);\n for (let i = 0; i < words.length; i++) {\n const word = words[i];\n const hash = this.simpleHash(word);\n const idx = hash % this.dimensions;\n vector[idx] += 0.5;\n }\n\n // Normalize to unit vector\n return this.normalize(vector);\n }\n\n private simpleHash(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash);\n }\n\n private normalize(vector: number[]): number[] {\n const magnitude = Math.sqrt(vector.reduce((sum, v) => sum + v * v, 0));\n if (magnitude === 0) return vector;\n return vector.map((v) => v / magnitude);\n }\n}\n\n/**\n * OpenAI embedding provider\n */\nexport class OpenAIEmbedding implements EmbeddingProvider {\n name = 'openai';\n dimensions = 1536; // text-embedding-3-small default\n\n private apiKey: string;\n private model: string;\n private baseUrl: string;\n\n constructor(options: EmbeddingProviderOptions) {\n if (!options.apiKey) {\n throw new Error('OpenAI API key is required');\n }\n this.apiKey = options.apiKey;\n this.model = options.model || 'text-embedding-3-small';\n this.baseUrl = options.baseUrl || 'https://api.openai.com/v1';\n\n // Update dimensions based on model\n if (this.model === 'text-embedding-3-large') {\n this.dimensions = 3072;\n } else if (this.model === 'text-embedding-ada-002') {\n this.dimensions = 1536;\n }\n }\n\n async embed(text: string): Promise<number[]> {\n const embeddings = await this.embedBatch([text]);\n if (embeddings.length === 0) {\n throw new Error('OpenAI API returned no embeddings');\n }\n return embeddings[0];\n }\n\n async embedBatch(texts: string[]): Promise<number[][]> {\n const response = await fetch(`${this.baseUrl}/embeddings`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: texts,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`OpenAI API error: ${error}`);\n }\n\n const data = (await response.json()) as {\n data: Array<{ embedding: number[]; index: number }>;\n };\n\n // Sort by index to maintain order\n return data.data\n .sort((a, b) => a.index - b.index)\n .map((item) => item.embedding);\n }\n}\n\n/**\n * Anthropic/Voyage embedding provider (placeholder)\n */\nexport class VoyageEmbedding implements EmbeddingProvider {\n name = 'voyage';\n dimensions = 1024;\n\n private apiKey: string;\n private model: string;\n\n constructor(options: EmbeddingProviderOptions) {\n if (!options.apiKey) {\n throw new Error('Voyage API key is required');\n }\n this.apiKey = options.apiKey;\n this.model = options.model || 'voyage-2';\n }\n\n async embed(text: string): Promise<number[]> {\n const embeddings = await this.embedBatch([text]);\n if (embeddings.length === 0) {\n throw new Error('Voyage API returned no embeddings');\n }\n return embeddings[0];\n }\n\n async embedBatch(texts: string[]): Promise<number[][]> {\n const response = await fetch('https://api.voyageai.com/v1/embeddings', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: texts,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Voyage API error: ${error}`);\n }\n\n const data = (await response.json()) as {\n data: Array<{ embedding: number[] }>;\n };\n\n return data.data.map((item) => item.embedding);\n }\n}\n\n/**\n * Calculate cosine similarity between two vectors\n */\nexport function cosineSimilarity(a: number[], b: number[]): number {\n if (a.length !== b.length) {\n throw new Error('Vectors must have the same length');\n }\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n const magnitude = Math.sqrt(normA) * Math.sqrt(normB);\n if (magnitude === 0) return 0;\n\n return dotProduct / magnitude;\n}\n\n/**\n * Calculate euclidean distance between two vectors\n */\nexport function euclideanDistance(a: number[], b: number[]): number {\n if (a.length !== b.length) {\n throw new Error('Vectors must have the same length');\n }\n\n let sum = 0;\n for (let i = 0; i < a.length; i++) {\n const diff = a[i] - b[i];\n sum += diff * diff;\n }\n\n return Math.sqrt(sum);\n}\n","/**\n * Semantic skill matcher\n * Uses embeddings to find relevant skills for a given context\n */\n\nimport type { Skill, StorageAdapter } from '../types.js';\nimport {\n EmbeddingProvider,\n SimpleHashEmbedding,\n cosineSimilarity,\n} from './embeddings.js';\n\n/**\n * Configuration for the semantic matcher\n */\nexport interface MatcherConfig {\n /** Embedding provider to use */\n embeddingProvider?: EmbeddingProvider;\n /** Minimum similarity threshold (0-1) */\n similarityThreshold?: number;\n /** Maximum number of results to return */\n maxResults?: number;\n /** Cache embeddings in memory */\n cacheEmbeddings?: boolean;\n /** Fields to include in skill embedding */\n embeddingFields?: SkillEmbeddingField[];\n}\n\nexport type SkillEmbeddingField =\n | 'name'\n | 'description'\n | 'problem'\n | 'solution'\n | 'triggerConditions'\n | 'tags';\n\n/**\n * Match result with similarity score\n */\nexport interface MatchResult {\n /** The matched skill */\n skill: Skill;\n /** Similarity score (0-1) */\n similarity: number;\n /** Which fields contributed to the match */\n matchedFields?: string[];\n}\n\n/**\n * Cached embedding entry\n */\ninterface EmbeddingCacheEntry {\n skillId: string;\n version: string;\n embedding: number[];\n updatedAt: Date;\n}\n\n/**\n * Semantic matcher for finding relevant skills\n */\nexport class SemanticMatcher {\n private provider: EmbeddingProvider;\n private config: Required<MatcherConfig>;\n private cache = new Map<string, EmbeddingCacheEntry>();\n\n constructor(config: MatcherConfig = {}) {\n this.provider = config.embeddingProvider || new SimpleHashEmbedding();\n this.config = {\n embeddingProvider: this.provider,\n similarityThreshold: config.similarityThreshold ?? 0.5,\n maxResults: config.maxResults ?? 10,\n cacheEmbeddings: config.cacheEmbeddings ?? true,\n embeddingFields: config.embeddingFields ?? [\n 'name',\n 'description',\n 'problem',\n 'triggerConditions',\n 'tags',\n ],\n };\n }\n\n /**\n * Find skills matching a query string\n */\n async findMatches(\n query: string,\n skills: Skill[],\n options?: {\n threshold?: number;\n maxResults?: number;\n }\n ): Promise<MatchResult[]> {\n const threshold = options?.threshold ?? this.config.similarityThreshold;\n const maxResults = options?.maxResults ?? this.config.maxResults;\n\n // Get query embedding\n const queryEmbedding = await this.provider.embed(query);\n\n // Get or compute skill embeddings\n const results: MatchResult[] = [];\n\n for (const skill of skills) {\n const skillEmbedding = await this.getSkillEmbedding(skill);\n const similarity = cosineSimilarity(queryEmbedding, skillEmbedding);\n\n if (similarity >= threshold) {\n results.push({\n skill,\n similarity,\n matchedFields: this.identifyMatchedFields(query, skill),\n });\n }\n }\n\n // Sort by similarity (descending) and limit results\n return results\n .sort((a, b) => b.similarity - a.similarity)\n .slice(0, maxResults);\n }\n\n /**\n * Find skills matching a context (problem description, error message, etc.)\n */\n async findByContext(\n context: MatchContext,\n skills: Skill[],\n options?: {\n threshold?: number;\n maxResults?: number;\n }\n ): Promise<MatchResult[]> {\n // Build query from context\n const queryParts: string[] = [];\n\n if (context.problemDescription) {\n queryParts.push(context.problemDescription);\n }\n if (context.errorMessage) {\n queryParts.push(`error: ${context.errorMessage}`);\n }\n if (context.keywords) {\n queryParts.push(context.keywords.join(' '));\n }\n if (context.technologies) {\n queryParts.push(context.technologies.join(' '));\n }\n if (context.codeSnippet) {\n // Extract identifiers from code\n const identifiers = this.extractIdentifiers(context.codeSnippet);\n queryParts.push(identifiers.join(' '));\n }\n\n const query = queryParts.join(' ');\n return this.findMatches(query, skills, options);\n }\n\n /**\n * Find skills similar to a given skill\n */\n async findSimilar(\n skill: Skill,\n allSkills: Skill[],\n options?: {\n threshold?: number;\n maxResults?: number;\n excludeSelf?: boolean;\n }\n ): Promise<MatchResult[]> {\n const skillText = this.skillToText(skill);\n const excludeSelf = options?.excludeSelf ?? true;\n\n const candidates = excludeSelf\n ? allSkills.filter((s) => s.id !== skill.id)\n : allSkills;\n\n return this.findMatches(skillText, candidates, options);\n }\n\n /**\n * Find skills that might apply to a trajectory\n */\n async findForTrajectory(\n trajectory: { turns: Array<{ role: string; content?: string }> },\n skills: Skill[],\n options?: {\n threshold?: number;\n maxResults?: number;\n }\n ): Promise<MatchResult[]> {\n // Extract relevant content from trajectory\n const contextParts: string[] = [];\n\n for (const turn of trajectory.turns) {\n if (turn.content) {\n // Look for error messages\n const errorMatch = turn.content.match(/error[:\\s]+([^\\n]+)/i);\n if (errorMatch) {\n contextParts.push(errorMatch[1]);\n }\n\n // Include user questions/problems\n if (turn.role === 'user') {\n contextParts.push(turn.content.substring(0, 500));\n }\n }\n }\n\n const query = contextParts.join(' ');\n return this.findMatches(query, skills, options);\n }\n\n /**\n * Pre-compute and cache embeddings for all skills\n */\n async indexSkills(skills: Skill[]): Promise<void> {\n // Batch compute embeddings for efficiency\n const texts = skills.map((s) => this.skillToText(s));\n const embeddings = await this.provider.embedBatch(texts);\n\n // Cache the embeddings\n for (let i = 0; i < skills.length; i++) {\n const skill = skills[i];\n const cacheKey = this.getCacheKey(skill);\n this.cache.set(cacheKey, {\n skillId: skill.id,\n version: skill.version,\n embedding: embeddings[i],\n updatedAt: new Date(),\n });\n }\n }\n\n /**\n * Index skills from a storage adapter\n */\n async indexFromStorage(storage: StorageAdapter): Promise<number> {\n const skills = await storage.listSkills();\n await this.indexSkills(skills);\n return skills.length;\n }\n\n /**\n * Clear the embedding cache\n */\n clearCache(): void {\n this.cache.clear();\n }\n\n /**\n * Get cache statistics\n */\n getCacheStats(): { size: number; skills: string[] } {\n return {\n size: this.cache.size,\n skills: Array.from(this.cache.values()).map((e) => `${e.skillId}@${e.version}`),\n };\n }\n\n /**\n * Update configuration\n */\n setConfig(config: Partial<MatcherConfig>): void {\n if (config.embeddingProvider) {\n this.provider = config.embeddingProvider;\n this.config.embeddingProvider = config.embeddingProvider;\n this.clearCache(); // Clear cache when provider changes\n }\n if (config.similarityThreshold !== undefined) {\n this.config.similarityThreshold = config.similarityThreshold;\n }\n if (config.maxResults !== undefined) {\n this.config.maxResults = config.maxResults;\n }\n if (config.cacheEmbeddings !== undefined) {\n this.config.cacheEmbeddings = config.cacheEmbeddings;\n }\n if (config.embeddingFields) {\n this.config.embeddingFields = config.embeddingFields;\n this.clearCache(); // Clear cache when fields change\n }\n }\n\n // ===========================================================================\n // Private helpers\n // ===========================================================================\n\n /**\n * Get or compute embedding for a skill\n */\n private async getSkillEmbedding(skill: Skill): Promise<number[]> {\n if (this.config.cacheEmbeddings) {\n const cacheKey = this.getCacheKey(skill);\n const cached = this.cache.get(cacheKey);\n\n if (cached) {\n return cached.embedding;\n }\n\n const embedding = await this.provider.embed(this.skillToText(skill));\n this.cache.set(cacheKey, {\n skillId: skill.id,\n version: skill.version,\n embedding,\n updatedAt: new Date(),\n });\n\n return embedding;\n }\n\n return this.provider.embed(this.skillToText(skill));\n }\n\n /**\n * Convert skill to text for embedding\n */\n private skillToText(skill: Skill): string {\n const parts: string[] = [];\n\n for (const field of this.config.embeddingFields) {\n switch (field) {\n case 'name':\n parts.push(skill.name);\n break;\n case 'description':\n parts.push(skill.description);\n break;\n case 'problem':\n parts.push(skill.problem);\n break;\n case 'solution':\n parts.push(skill.solution);\n break;\n case 'triggerConditions':\n parts.push(\n skill.triggerConditions\n .map((t) => `${t.type}: ${t.value}`)\n .join(' ')\n );\n break;\n case 'tags':\n parts.push(skill.tags.join(' '));\n break;\n }\n }\n\n return parts.filter(Boolean).join(' ');\n }\n\n /**\n * Get cache key for a skill\n */\n private getCacheKey(skill: Skill): string {\n return `${skill.id}:${skill.version}`;\n }\n\n /**\n * Identify which fields in the skill matched the query\n */\n private identifyMatchedFields(query: string, skill: Skill): string[] {\n const queryTerms = query.toLowerCase().split(/\\s+/);\n const matchedFields: string[] = [];\n\n const checkField = (fieldName: string, value: string) => {\n const lowerValue = value.toLowerCase();\n if (queryTerms.some((term) => lowerValue.includes(term))) {\n matchedFields.push(fieldName);\n }\n };\n\n checkField('name', skill.name);\n checkField('description', skill.description);\n checkField('problem', skill.problem);\n checkField('solution', skill.solution);\n checkField('tags', skill.tags.join(' '));\n checkField(\n 'triggerConditions',\n skill.triggerConditions.map((t) => t.value).join(' ')\n );\n\n return matchedFields;\n }\n\n /**\n * Extract identifiers from code snippet\n */\n private extractIdentifiers(code: string): string[] {\n // Simple identifier extraction - could be enhanced with proper parsing\n const identifiers = code.match(/[a-zA-Z_][a-zA-Z0-9_]*/g) || [];\n return [...new Set(identifiers)].filter((id) => id.length > 2);\n }\n}\n\n/**\n * Context for finding matching skills\n */\nexport interface MatchContext {\n /** Description of the problem */\n problemDescription?: string;\n /** Error message encountered */\n errorMessage?: string;\n /** Relevant keywords */\n keywords?: string[];\n /** Technologies/frameworks in use */\n technologies?: string[];\n /** Code snippet for context */\n codeSnippet?: string;\n}\n","/**\n * Dependency graph for skill composition\n * Tracks relationships and dependencies between skills\n */\n\nimport type { Skill } from '../types.js';\n\n/**\n * Type of dependency relationship\n */\nexport type DependencyType =\n | 'requires' // Skill A requires skill B to be present\n | 'extends' // Skill A extends/builds upon skill B\n | 'conflicts' // Skill A conflicts with skill B\n | 'enhances' // Skill A enhances skill B when used together\n | 'precedes' // Skill A should run before skill B\n | 'follows'; // Skill A should run after skill B\n\n/**\n * A node in the dependency graph\n */\nexport interface GraphNode {\n /** Skill ID */\n skillId: string;\n /** Skill version */\n version: string;\n /** Reference to the skill */\n skill: Skill;\n /** Metadata about this node */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * An edge in the dependency graph\n */\nexport interface GraphEdge {\n /** Source skill ID */\n from: string;\n /** Target skill ID */\n to: string;\n /** Type of dependency */\n type: DependencyType;\n /** Whether this dependency is required */\n required: boolean;\n /** Description of the relationship */\n description?: string;\n}\n\n/**\n * Result of cycle detection\n */\ninterface CycleResult {\n hasCycle: boolean;\n cycle?: string[];\n}\n\n/**\n * Dependency graph for managing skill relationships\n */\nexport class DependencyGraph {\n private nodes = new Map<string, GraphNode>();\n private edges: GraphEdge[] = [];\n private adjacencyList = new Map<string, Set<string>>();\n private reverseAdjacencyList = new Map<string, Set<string>>();\n\n /**\n * Add a skill to the graph\n */\n addSkill(skill: Skill): void {\n const key = this.getKey(skill.id, skill.version);\n this.nodes.set(key, {\n skillId: skill.id,\n version: skill.version,\n skill,\n });\n\n if (!this.adjacencyList.has(key)) {\n this.adjacencyList.set(key, new Set());\n }\n if (!this.reverseAdjacencyList.has(key)) {\n this.reverseAdjacencyList.set(key, new Set());\n }\n }\n\n /**\n * Remove a skill from the graph\n */\n removeSkill(skillId: string, version?: string): void {\n const keysToRemove = version\n ? [this.getKey(skillId, version)]\n : Array.from(this.nodes.keys()).filter((k) => k.startsWith(`${skillId}@`));\n\n for (const key of keysToRemove) {\n this.nodes.delete(key);\n this.adjacencyList.delete(key);\n this.reverseAdjacencyList.delete(key);\n\n // Remove edges involving this node\n this.edges = this.edges.filter(\n (e) => this.getKey(e.from) !== key && this.getKey(e.to) !== key\n );\n\n // Clean up adjacency lists\n for (const adj of this.adjacencyList.values()) {\n adj.delete(key);\n }\n for (const adj of this.reverseAdjacencyList.values()) {\n adj.delete(key);\n }\n }\n }\n\n /**\n * Add a dependency edge\n */\n addDependency(\n fromId: string,\n toId: string,\n type: DependencyType,\n options?: {\n required?: boolean;\n description?: string;\n fromVersion?: string;\n toVersion?: string;\n }\n ): void {\n const edge: GraphEdge = {\n from: fromId,\n to: toId,\n type,\n required: options?.required ?? true,\n description: options?.description,\n };\n\n this.edges.push(edge);\n\n // Update adjacency lists (use skill ID for simplicity)\n const fromKey = options?.fromVersion\n ? this.getKey(fromId, options.fromVersion)\n : fromId;\n const toKey = options?.toVersion\n ? this.getKey(toId, options.toVersion)\n : toId;\n\n if (!this.adjacencyList.has(fromKey)) {\n this.adjacencyList.set(fromKey, new Set());\n }\n this.adjacencyList.get(fromKey)!.add(toKey);\n\n if (!this.reverseAdjacencyList.has(toKey)) {\n this.reverseAdjacencyList.set(toKey, new Set());\n }\n this.reverseAdjacencyList.get(toKey)!.add(fromKey);\n }\n\n /**\n * Remove a dependency edge\n */\n removeDependency(fromId: string, toId: string, type?: DependencyType): void {\n this.edges = this.edges.filter(\n (e) =>\n !(e.from === fromId && e.to === toId && (type === undefined || e.type === type))\n );\n\n // Update adjacency lists\n const remainingEdges = this.edges.filter(\n (e) => e.from === fromId && e.to === toId\n );\n if (remainingEdges.length === 0) {\n this.adjacencyList.get(fromId)?.delete(toId);\n this.reverseAdjacencyList.get(toId)?.delete(fromId);\n }\n }\n\n /**\n * Get all dependencies of a skill\n */\n getDependencies(skillId: string): GraphEdge[] {\n return this.edges.filter((e) => e.from === skillId);\n }\n\n /**\n * Get all skills that depend on this skill\n */\n getDependents(skillId: string): GraphEdge[] {\n return this.edges.filter((e) => e.to === skillId);\n }\n\n /**\n * Get conflicts for a skill\n */\n getConflicts(skillId: string): GraphEdge[] {\n return this.edges.filter(\n (e) =>\n e.type === 'conflicts' && (e.from === skillId || e.to === skillId)\n );\n }\n\n /**\n * Check if two skills conflict\n */\n hasConflict(skillId1: string, skillId2: string): boolean {\n return this.edges.some(\n (e) =>\n e.type === 'conflicts' &&\n ((e.from === skillId1 && e.to === skillId2) ||\n (e.from === skillId2 && e.to === skillId1))\n );\n }\n\n /**\n * Get topological sort of skills (for execution order)\n */\n getTopologicalOrder(skillIds?: string[]): string[] {\n const targetIds = skillIds || Array.from(new Set(this.edges.flatMap((e) => [e.from, e.to])));\n const visited = new Set<string>();\n const result: string[] = [];\n\n const visit = (id: string) => {\n if (visited.has(id)) return;\n visited.add(id);\n\n // Visit dependencies first (for 'requires', 'precedes' types)\n const deps = this.edges.filter(\n (e) =>\n e.from === id &&\n (e.type === 'requires' || e.type === 'precedes' || e.type === 'extends')\n );\n for (const dep of deps) {\n visit(dep.to);\n }\n\n result.push(id);\n };\n\n for (const id of targetIds) {\n visit(id);\n }\n\n return result;\n }\n\n /**\n * Detect cycles in the graph\n */\n detectCycle(): CycleResult {\n const visited = new Set<string>();\n const recStack = new Set<string>();\n const path: string[] = [];\n\n const dfs = (node: string): string[] | null => {\n visited.add(node);\n recStack.add(node);\n path.push(node);\n\n const neighbors = this.adjacencyList.get(node) || new Set();\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n const cycle = dfs(neighbor);\n if (cycle) return cycle;\n } else if (recStack.has(neighbor)) {\n // Found cycle\n const cycleStart = path.indexOf(neighbor);\n return path.slice(cycleStart).concat(neighbor);\n }\n }\n\n path.pop();\n recStack.delete(node);\n return null;\n };\n\n const allNodes = new Set([\n ...this.adjacencyList.keys(),\n ...this.reverseAdjacencyList.keys(),\n ]);\n\n for (const node of allNodes) {\n if (!visited.has(node)) {\n const cycle = dfs(node);\n if (cycle) {\n return { hasCycle: true, cycle };\n }\n }\n }\n\n return { hasCycle: false };\n }\n\n /**\n * Get all required dependencies (transitive)\n */\n getTransitiveDependencies(skillId: string): string[] {\n const result = new Set<string>();\n const queue = [skillId];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const deps = this.edges.filter(\n (e) => e.from === current && e.type === 'requires' && e.required\n );\n\n for (const dep of deps) {\n if (!result.has(dep.to)) {\n result.add(dep.to);\n queue.push(dep.to);\n }\n }\n }\n\n return Array.from(result);\n }\n\n /**\n * Check if all required dependencies are satisfied\n */\n checkDependenciesSatisfied(skillIds: string[]): {\n satisfied: boolean;\n missing: string[];\n } {\n const available = new Set(skillIds);\n const missing: string[] = [];\n\n for (const id of skillIds) {\n const requiredDeps = this.edges.filter(\n (e) => e.from === id && e.type === 'requires' && e.required\n );\n\n for (const dep of requiredDeps) {\n if (!available.has(dep.to)) {\n missing.push(dep.to);\n }\n }\n }\n\n return {\n satisfied: missing.length === 0,\n missing: [...new Set(missing)],\n };\n }\n\n /**\n * Get all skills in the graph\n */\n getSkills(): Skill[] {\n return Array.from(this.nodes.values()).map((n) => n.skill);\n }\n\n /**\n * Get all edges in the graph\n */\n getEdges(): GraphEdge[] {\n return [...this.edges];\n }\n\n /**\n * Get graph statistics\n */\n getStats(): {\n nodeCount: number;\n edgeCount: number;\n edgesByType: Record<DependencyType, number>;\n } {\n const edgesByType: Record<DependencyType, number> = {\n requires: 0,\n extends: 0,\n conflicts: 0,\n enhances: 0,\n precedes: 0,\n follows: 0,\n };\n\n for (const edge of this.edges) {\n edgesByType[edge.type]++;\n }\n\n return {\n nodeCount: this.nodes.size,\n edgeCount: this.edges.length,\n edgesByType,\n };\n }\n\n /**\n * Clear the graph\n */\n clear(): void {\n this.nodes.clear();\n this.edges = [];\n this.adjacencyList.clear();\n this.reverseAdjacencyList.clear();\n }\n\n /**\n * Export graph to JSON\n */\n toJSON(): {\n nodes: Array<{ skillId: string; version: string }>;\n edges: GraphEdge[];\n } {\n return {\n nodes: Array.from(this.nodes.values()).map((n) => ({\n skillId: n.skillId,\n version: n.version,\n })),\n edges: this.edges,\n };\n }\n\n /**\n * Import graph from JSON (requires skills to be added separately)\n */\n fromJSON(data: { edges: GraphEdge[] }): void {\n for (const edge of data.edges) {\n this.addDependency(edge.from, edge.to, edge.type, {\n required: edge.required,\n description: edge.description,\n });\n }\n }\n\n // ===========================================================================\n // Private helpers\n // ===========================================================================\n\n private getKey(skillId: string, version?: string): string {\n return version ? `${skillId}@${version}` : skillId;\n }\n}\n","/**\n * Skill Composer\n * Combines atomic skills into compound skills\n */\n\nimport type { Skill, StorageAdapter } from '../types.js';\nimport { SemanticMatcher, SimpleHashEmbedding, type EmbeddingProvider } from '../matching/index.js';\nimport { DependencyGraph, type DependencyType, type GraphEdge } from './dependency-graph.js';\nimport type {\n CompoundSkill,\n SkillComponent,\n CompositionMode,\n ExecutionOrder,\n} from './types.js';\nimport { isCompoundSkill } from './types.js';\n\n/**\n * Configuration for the skill composer\n */\nexport interface ComposerConfig {\n /** Storage adapter for loading skills */\n storage?: StorageAdapter;\n /** Embedding provider for similarity detection */\n embeddingProvider?: EmbeddingProvider;\n /** Similarity threshold for suggestions */\n suggestionThreshold?: number;\n /** Maximum depth for transitive dependencies */\n maxDependencyDepth?: number;\n}\n\n/**\n * Result of a composition operation\n */\nexport interface CompositionResult {\n /** Whether composition was successful */\n success: boolean;\n /** The composed skill (if successful) */\n skill?: CompoundSkill;\n /** Conflicts detected */\n conflicts: CompositionConflict[];\n /** Warnings (non-blocking issues) */\n warnings: string[];\n /** Missing dependencies */\n missingDependencies: string[];\n}\n\n/**\n * A conflict detected during composition\n */\nexport interface CompositionConflict {\n /** Type of conflict */\n type: 'direct' | 'transitive' | 'version' | 'trigger-overlap';\n /** First skill involved */\n skillId1: string;\n /** Second skill involved */\n skillId2: string;\n /** Description of the conflict */\n description: string;\n /** Severity: error blocks composition, warning allows it */\n severity: 'error' | 'warning';\n}\n\n/**\n * A suggestion for skill composition\n */\nexport interface CompositionSuggestion {\n /** Suggested skills to compose */\n skillIds: string[];\n /** Suggested composition mode */\n mode: CompositionMode;\n /** Confidence score (0-1) */\n confidence: number;\n /** Reason for the suggestion */\n reason: string;\n /** Expected benefit */\n benefit?: string;\n}\n\n/**\n * Skill composer for creating compound skills\n */\nexport class SkillComposer {\n private config: Required<Omit<ComposerConfig, 'storage'>> & { storage?: StorageAdapter };\n private graph: DependencyGraph;\n private matcher: SemanticMatcher;\n private skillCache = new Map<string, Skill>();\n\n constructor(config: ComposerConfig = {}) {\n this.config = {\n storage: config.storage,\n embeddingProvider: config.embeddingProvider || new SimpleHashEmbedding(),\n suggestionThreshold: config.suggestionThreshold ?? 0.6,\n maxDependencyDepth: config.maxDependencyDepth ?? 10,\n };\n\n this.graph = new DependencyGraph();\n this.matcher = new SemanticMatcher({\n embeddingProvider: this.config.embeddingProvider,\n similarityThreshold: this.config.suggestionThreshold,\n });\n }\n\n /**\n * Compose multiple skills into a compound skill\n */\n async compose(\n skillIds: string[],\n options: {\n name: string;\n description?: string;\n mode?: CompositionMode;\n executionOrder?: ExecutionOrder;\n stopOnFailure?: boolean;\n }\n ): Promise<CompositionResult> {\n const conflicts: CompositionConflict[] = [];\n const warnings: string[] = [];\n const missingDependencies: string[] = [];\n\n // Load skills\n const skills: Skill[] = [];\n for (const id of skillIds) {\n const skill = await this.getSkill(id);\n if (!skill) {\n missingDependencies.push(id);\n continue;\n }\n skills.push(skill);\n }\n\n if (missingDependencies.length > 0) {\n return {\n success: false,\n conflicts,\n warnings,\n missingDependencies,\n };\n }\n\n // Check for conflicts\n const detectedConflicts = this.detectConflicts(skills);\n conflicts.push(...detectedConflicts);\n\n // Check for blocking conflicts\n const blockingConflicts = conflicts.filter((c) => c.severity === 'error');\n if (blockingConflicts.length > 0) {\n return {\n success: false,\n conflicts,\n warnings,\n missingDependencies,\n };\n }\n\n // Add warnings for non-blocking conflicts\n for (const conflict of conflicts.filter((c) => c.severity === 'warning')) {\n warnings.push(conflict.description);\n }\n\n // Check dependencies\n const depCheck = this.graph.checkDependenciesSatisfied(skillIds);\n if (!depCheck.satisfied) {\n warnings.push(\n `Missing optional dependencies: ${depCheck.missing.join(', ')}`\n );\n }\n\n // Determine execution order\n const orderedIds =\n options.mode === 'sequential'\n ? this.getExecutionOrder(skillIds, options.executionOrder)\n : skillIds;\n\n // Create components\n const components: SkillComponent[] = orderedIds.map((id, index) => ({\n skillId: id,\n priority: index,\n }));\n\n // Create compound skill\n const compoundSkill: CompoundSkill = {\n id: this.generateId(options.name),\n name: options.name,\n description: options.description || this.generateDescription(skills),\n problem: this.mergeProblemStatements(skills),\n triggerConditions: this.mergeTriggerConditions(skills),\n solution: this.generateSolutionSteps(skills, options.mode || 'sequential'),\n verification: this.mergeVerifications(skills),\n examples: [],\n notes: `Composed from: ${skillIds.join(', ')}`,\n author: 'skill-composer',\n tags: this.mergeTags(skills),\n version: '1.0.0',\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 createdAt: new Date(),\n updatedAt: new Date(),\n derivedFrom: skillIds,\n isCompound: true,\n composition: {\n mode: options.mode || 'sequential',\n executionOrder: options.executionOrder,\n components,\n stopOnFailure: options.stopOnFailure ?? true,\n },\n };\n\n return {\n success: true,\n skill: compoundSkill,\n conflicts,\n warnings,\n missingDependencies,\n };\n }\n\n /**\n * Decompose a compound skill into its components\n */\n async decompose(skill: CompoundSkill): Promise<Skill[]> {\n const skills: Skill[] = [];\n\n for (const component of skill.composition.components) {\n const componentSkill = await this.getSkill(\n component.skillId,\n component.version\n );\n if (componentSkill) {\n skills.push(componentSkill);\n }\n }\n\n return skills;\n }\n\n /**\n * Add a dependency relationship between skills\n */\n addDependency(\n fromId: string,\n toId: string,\n type: DependencyType,\n options?: { required?: boolean; description?: string }\n ): void {\n this.graph.addDependency(fromId, toId, type, options);\n }\n\n /**\n * Remove a dependency relationship\n */\n removeDependency(fromId: string, toId: string, type?: DependencyType): void {\n this.graph.removeDependency(fromId, toId, type);\n }\n\n /**\n * Get dependencies for a skill\n */\n getDependencies(skillId: string): GraphEdge[] {\n return this.graph.getDependencies(skillId);\n }\n\n /**\n * Get skills that depend on this skill\n */\n getDependents(skillId: string): GraphEdge[] {\n return this.graph.getDependents(skillId);\n }\n\n /**\n * Detect conflicts between skills\n */\n detectConflicts(skills: Skill[]): CompositionConflict[] {\n const conflicts: CompositionConflict[] = [];\n\n for (let i = 0; i < skills.length; i++) {\n for (let j = i + 1; j < skills.length; j++) {\n const skill1 = skills[i];\n const skill2 = skills[j];\n\n // Check explicit conflicts in graph\n if (this.graph.hasConflict(skill1.id, skill2.id)) {\n conflicts.push({\n type: 'direct',\n skillId1: skill1.id,\n skillId2: skill2.id,\n description: `Skills \"${skill1.name}\" and \"${skill2.name}\" have declared conflicts`,\n severity: 'error',\n });\n }\n\n // Check trigger condition overlaps\n const triggerOverlap = this.checkTriggerOverlap(skill1, skill2);\n if (triggerOverlap) {\n conflicts.push({\n type: 'trigger-overlap',\n skillId1: skill1.id,\n skillId2: skill2.id,\n description: `Skills have overlapping trigger conditions: ${triggerOverlap}`,\n severity: 'warning',\n });\n }\n }\n }\n\n return conflicts;\n }\n\n /**\n * Validate a composition without creating it\n */\n async validateComposition(skillIds: string[]): Promise<{\n valid: boolean;\n conflicts: CompositionConflict[];\n missingDependencies: string[];\n warnings: string[];\n }> {\n const skills: Skill[] = [];\n const missingDependencies: string[] = [];\n const warnings: string[] = [];\n\n for (const id of skillIds) {\n const skill = await this.getSkill(id);\n if (!skill) {\n missingDependencies.push(id);\n } else {\n skills.push(skill);\n }\n }\n\n const conflicts = this.detectConflicts(skills);\n const blockingConflicts = conflicts.filter((c) => c.severity === 'error');\n\n // Check for cycles\n const cycleResult = this.graph.detectCycle();\n if (cycleResult.hasCycle) {\n warnings.push(\n `Circular dependency detected: ${cycleResult.cycle?.join(' -> ')}`\n );\n }\n\n return {\n valid: blockingConflicts.length === 0 && missingDependencies.length === 0,\n conflicts,\n missingDependencies,\n warnings,\n };\n }\n\n /**\n * Suggest skill compositions based on usage patterns and similarity\n */\n async suggestCompositions(\n skills: Skill[],\n options?: {\n maxSuggestions?: number;\n minConfidence?: number;\n }\n ): Promise<CompositionSuggestion[]> {\n const suggestions: CompositionSuggestion[] = [];\n const maxSuggestions = options?.maxSuggestions ?? 5;\n const minConfidence = options?.minConfidence ?? this.config.suggestionThreshold;\n\n // Find skills with similar problems/triggers\n for (let i = 0; i < skills.length; i++) {\n const similar = await this.matcher.findSimilar(skills[i], skills, {\n threshold: minConfidence,\n maxResults: 3,\n });\n\n for (const match of similar) {\n if (match.skill.id === skills[i].id) continue;\n\n // Check if they're already suggested\n const existing = suggestions.find(\n (s) =>\n s.skillIds.includes(skills[i].id) &&\n s.skillIds.includes(match.skill.id)\n );\n if (existing) continue;\n\n // Determine best composition mode\n const mode = this.suggestCompositionMode(skills[i], match.skill);\n\n suggestions.push({\n skillIds: [skills[i].id, match.skill.id],\n mode,\n confidence: match.similarity,\n reason: `Similar ${this.getSimilarityReason(skills[i], match.skill)}`,\n benefit: this.estimateBenefit(skills[i], match.skill, mode),\n });\n }\n }\n\n // Find skills that commonly occur together (via dependencies)\n const dependencyPairs = this.findCommonDependencyPairs(skills);\n for (const pair of dependencyPairs) {\n const existing = suggestions.find(\n (s) => s.skillIds.includes(pair[0]) && s.skillIds.includes(pair[1])\n );\n if (!existing) {\n suggestions.push({\n skillIds: pair,\n mode: 'sequential',\n confidence: 0.7,\n reason: 'Frequently used together based on dependency patterns',\n benefit: 'Streamlined workflow',\n });\n }\n }\n\n // Sort by confidence and limit\n return suggestions\n .sort((a, b) => b.confidence - a.confidence)\n .slice(0, maxSuggestions);\n }\n\n /**\n * Index skills from storage for composition suggestions\n */\n async indexFromStorage(storage: StorageAdapter): Promise<number> {\n const skills = await storage.listSkills();\n\n for (const skill of skills) {\n this.graph.addSkill(skill);\n this.skillCache.set(skill.id, skill);\n\n // Add dependencies from derivedFrom\n if (skill.derivedFrom) {\n for (const parentId of skill.derivedFrom) {\n this.graph.addDependency(skill.id, parentId, 'extends');\n }\n }\n }\n\n await this.matcher.indexSkills(skills);\n return skills.length;\n }\n\n /**\n * Get dependency graph\n */\n getGraph(): DependencyGraph {\n return this.graph;\n }\n\n /**\n * Clear caches and graph\n */\n clear(): void {\n this.graph.clear();\n this.skillCache.clear();\n this.matcher.clearCache();\n }\n\n // ===========================================================================\n // Private helpers\n // ===========================================================================\n\n private async getSkill(id: string, version?: string): Promise<Skill | null> {\n // Check cache first\n const cacheKey = version ? `${id}@${version}` : id;\n if (this.skillCache.has(cacheKey)) {\n return this.skillCache.get(cacheKey)!;\n }\n\n // Load from storage\n if (this.config.storage) {\n const skill = await this.config.storage.getSkill(id, version);\n if (skill) {\n this.skillCache.set(cacheKey, skill);\n return skill;\n }\n }\n\n return null;\n }\n\n private generateId(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n }\n\n private generateDescription(skills: Skill[]): string {\n return `Combines: ${skills.map((s) => s.name).join(', ')}`;\n }\n\n private mergeProblemStatements(skills: Skill[]): string {\n const problems = skills.map((s) => `- ${s.problem}`);\n return `This compound skill addresses:\\n${problems.join('\\n')}`;\n }\n\n private mergeTriggerConditions(\n skills: Skill[]\n ): Skill['triggerConditions'] {\n const seen = new Set<string>();\n const triggers: Skill['triggerConditions'] = [];\n\n for (const skill of skills) {\n for (const trigger of skill.triggerConditions) {\n const key = `${trigger.type}:${trigger.value}`;\n if (!seen.has(key)) {\n seen.add(key);\n triggers.push(trigger);\n }\n }\n }\n\n return triggers;\n }\n\n private generateSolutionSteps(\n skills: Skill[],\n mode: CompositionMode\n ): string {\n const steps: string[] = [];\n\n switch (mode) {\n case 'sequential':\n steps.push('Execute the following skills in order:');\n skills.forEach((s, i) => {\n steps.push(`\\n## Step ${i + 1}: ${s.name}\\n${s.solution}`);\n });\n break;\n\n case 'parallel':\n steps.push('Execute the following skills (can be done in parallel):');\n skills.forEach((s) => {\n steps.push(`\\n## ${s.name}\\n${s.solution}`);\n });\n break;\n\n case 'conditional':\n steps.push('Execute skills based on conditions:');\n skills.forEach((s) => {\n const triggers = s.triggerConditions\n .map((t) => t.value)\n .join(' OR ');\n steps.push(`\\n## If ${triggers}:\\n${s.solution}`);\n });\n break;\n\n case 'fallback':\n steps.push('Try skills in order until one succeeds:');\n skills.forEach((s, i) => {\n steps.push(`\\n## Option ${i + 1}: ${s.name}\\n${s.solution}`);\n });\n break;\n }\n\n return steps.join('\\n');\n }\n\n private mergeVerifications(skills: Skill[]): string {\n const verifications = skills.map(\n (s) => `- ${s.name}: ${s.verification}`\n );\n return `Verify all components:\\n${verifications.join('\\n')}`;\n }\n\n private mergeTags(skills: Skill[]): string[] {\n const tags = new Set<string>();\n for (const skill of skills) {\n for (const tag of skill.tags) {\n tags.add(tag);\n }\n }\n tags.add('compound');\n return Array.from(tags);\n }\n\n private getExecutionOrder(\n skillIds: string[],\n order?: ExecutionOrder\n ): string[] {\n switch (order) {\n case 'dependency':\n return this.graph.getTopologicalOrder(skillIds);\n case 'priority':\n // Would need priority info, default to original order\n return skillIds;\n case 'fixed':\n default:\n return skillIds;\n }\n }\n\n private checkTriggerOverlap(skill1: Skill, skill2: Skill): string | null {\n const triggers1 = skill1.triggerConditions.map((t) => t.value.toLowerCase());\n const triggers2 = skill2.triggerConditions.map((t) => t.value.toLowerCase());\n\n for (const t1 of triggers1) {\n for (const t2 of triggers2) {\n if (t1 === t2 || t1.includes(t2) || t2.includes(t1)) {\n return t1;\n }\n }\n }\n\n return null;\n }\n\n private suggestCompositionMode(skill1: Skill, skill2: Skill): CompositionMode {\n // If one skill's solution mentions the other's problem, they're sequential\n if (\n skill1.solution.toLowerCase().includes(skill2.problem.toLowerCase().slice(0, 20)) ||\n skill2.solution.toLowerCase().includes(skill1.problem.toLowerCase().slice(0, 20))\n ) {\n return 'sequential';\n }\n\n // If they have completely different trigger conditions, they might be conditional\n const overlap = this.checkTriggerOverlap(skill1, skill2);\n if (!overlap) {\n return 'conditional';\n }\n\n // If they address similar problems, they might be fallbacks\n return 'fallback';\n }\n\n private getSimilarityReason(skill1: Skill, skill2: Skill): string {\n // Check what makes them similar\n const reasons: string[] = [];\n\n // Check problem similarity\n const problem1Words = new Set(skill1.problem.toLowerCase().split(/\\s+/));\n const problem2Words = new Set(skill2.problem.toLowerCase().split(/\\s+/));\n const problemOverlap = [...problem1Words].filter((w) => problem2Words.has(w));\n if (problemOverlap.length > 3) {\n reasons.push('problem statements');\n }\n\n // Check tag overlap\n const tagOverlap = skill1.tags.filter((t) => skill2.tags.includes(t));\n if (tagOverlap.length > 0) {\n reasons.push(`tags (${tagOverlap.join(', ')})`);\n }\n\n // Check trigger overlap\n if (this.checkTriggerOverlap(skill1, skill2)) {\n reasons.push('trigger conditions');\n }\n\n return reasons.length > 0 ? reasons.join(', ') : 'content';\n }\n\n private estimateBenefit(\n skill1: Skill,\n skill2: Skill,\n mode: CompositionMode\n ): string {\n switch (mode) {\n case 'sequential':\n return 'Combined workflow reduces manual steps';\n case 'parallel':\n return 'Parallel execution saves time';\n case 'conditional':\n return 'Smart routing to appropriate skill';\n case 'fallback':\n return 'Increased reliability with backup options';\n default:\n return 'Unified skill management';\n }\n }\n\n private findCommonDependencyPairs(skills: Skill[]): string[][] {\n const pairs: string[][] = [];\n const skillIds = new Set(skills.map((s) => s.id));\n\n for (const skill of skills) {\n const deps = this.graph.getDependencies(skill.id);\n for (const dep of deps) {\n if (skillIds.has(dep.to) && dep.type !== 'conflicts') {\n pairs.push([skill.id, dep.to]);\n }\n }\n }\n\n return pairs;\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 problem: this.extractSection(body, 'Problem') || '',\n solution: this.extractSection(body, 'Solution') || '',\n verification: this.extractSection(body, 'Verification') || '',\n triggerConditions: this.parseTriggerConditions(metadata.triggers),\n examples: this.parseExamples(body),\n notes: this.extractSection(body, 'Notes'),\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 * Extract a section from markdown body\n */\n private extractSection(content: string, heading: string): string | undefined {\n const regex = new RegExp(`## ${heading}\\\\n([\\\\s\\\\S]*?)(?=\\\\n## |$)`, 'i');\n const match = content.match(regex);\n return match ? match[1].trim() : undefined;\n }\n\n /**\n * Parse trigger conditions from metadata\n */\n private parseTriggerConditions(\n triggers: string | undefined\n ): Array<{ type: 'error' | 'pattern' | 'context' | 'keyword' | 'custom'; value: string }> {\n if (!triggers) return [];\n\n try {\n // Try to parse as JSON array\n if (triggers.startsWith('[')) {\n return JSON.parse(triggers);\n }\n // Single trigger as string\n return [{ type: 'keyword', value: triggers }];\n } catch {\n return [];\n }\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 * Parse examples from body\n */\n private parseExamples(\n body: string\n ): Array<{ scenario: string; before: string; after: string }> {\n // TODO: Implement example parsing\n return [];\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 '## Problem',\n '',\n skill.problem,\n '',\n '## Solution',\n '',\n skill.solution,\n '',\n '## Verification',\n '',\n skill.verification,\n ];\n\n if (skill.notes) {\n body.push('', '## Notes', '', skill.notes);\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 * .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 '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 = path.join(repoRoot, '.skilltree');\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 path.join(repoRoot, '.skilltree');\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(repoRoot, '.skilltree', '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 // 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 notes if they were modified\n notes: local.notes !== remote.notes ? `${local.notes}\\n\\n---\\n\\n${remote.notes}` : remote.notes,\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 * Base session adapter interface and utilities\n */\n\nimport type { SessionAdapter, Trajectory } from '../types.js';\n\n/**\n * Abstract base class for session adapters\n */\nexport abstract class BaseSessionAdapter implements SessionAdapter {\n abstract name: string;\n abstract supportedExtensions: string[];\n\n abstract canHandle(input: string | Buffer): boolean;\n abstract parse(input: string | Buffer): Promise<Trajectory>;\n\n /**\n * Parse multiple sessions from a directory or concatenated file\n */\n async parseMany(input: string): Promise<Trajectory[]> {\n // Default implementation: try to parse as single trajectory\n // Subclasses can override for directory scanning, etc.\n const trajectory = await this.parse(input);\n return [trajectory];\n }\n\n /**\n * Generate a unique session ID if none provided\n */\n protected generateSessionId(): string {\n return `session_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n }\n\n /**\n * Safely parse JSON with error handling\n */\n protected safeJsonParse<T>(input: string): T | null {\n try {\n return JSON.parse(input) as T;\n } catch {\n return null;\n }\n }\n}\n\n/**\n * Registry for session adapters\n */\nexport class AdapterRegistry {\n private adapters: Map<string, SessionAdapter> = new Map();\n\n register(adapter: SessionAdapter): void {\n this.adapters.set(adapter.name, adapter);\n }\n\n unregister(name: string): boolean {\n return this.adapters.delete(name);\n }\n\n get(name: string): SessionAdapter | undefined {\n return this.adapters.get(name);\n }\n\n /**\n * Find an adapter that can handle the given input\n */\n findAdapter(input: string | Buffer): SessionAdapter | undefined {\n for (const adapter of this.adapters.values()) {\n if (adapter.canHandle(input)) {\n return adapter;\n }\n }\n return undefined;\n }\n\n /**\n * Find adapter by file extension\n */\n findByExtension(extension: string): SessionAdapter | undefined {\n const ext = extension.startsWith('.') ? extension : `.${extension}`;\n for (const adapter of this.adapters.values()) {\n if (adapter.supportedExtensions.includes(ext)) {\n return adapter;\n }\n }\n return undefined;\n }\n\n listAdapters(): SessionAdapter[] {\n return Array.from(this.adapters.values());\n }\n}\n\n// Global adapter registry\nexport const adapterRegistry = new AdapterRegistry();\n","/**\n * Claude Code session adapter\n * Parses Claude Code JSONL session files into Trajectories\n */\n\nimport { BaseSessionAdapter } from './base.js';\nimport type {\n Trajectory,\n Turn,\n ToolCall,\n ToolResult,\n TrajectoryMetadata,\n TrajectoryOutcome,\n} from '../types.js';\n\n/**\n * Raw Claude Code message format (JSONL)\n */\ninterface ClaudeCodeMessage {\n type: 'user' | 'assistant' | 'system' | 'result';\n message?: {\n role: 'user' | 'assistant' | 'system';\n content: string | ClaudeCodeContent[];\n };\n // Tool use fields\n toolUseId?: string;\n toolName?: string;\n // Result fields (for tool results)\n result?: string;\n // Session metadata\n sessionId?: string;\n timestamp?: string;\n // Additional metadata\n cwd?: string;\n model?: string;\n costUSD?: number;\n durationMs?: number;\n // Summary/stats messages\n summary?: {\n totalCost?: number;\n totalDuration?: number;\n turnCount?: number;\n };\n}\n\ninterface ClaudeCodeContent {\n type: 'text' | 'tool_use' | 'tool_result';\n text?: string;\n // Tool use\n id?: string;\n name?: string;\n input?: Record<string, unknown>;\n // Tool result\n tool_use_id?: string;\n content?: string | ClaudeCodeToolResultContent[];\n is_error?: boolean;\n}\n\ninterface ClaudeCodeToolResultContent {\n type: 'text';\n text: string;\n}\n\nexport class ClaudeCodeAdapter extends BaseSessionAdapter {\n name = 'claude-code';\n supportedExtensions = ['.jsonl', '.json'];\n\n canHandle(input: string | Buffer): boolean {\n const str = typeof input === 'string' ? input : input.toString('utf-8');\n\n // Check if it looks like JSONL with Claude Code structure\n const firstLine = str.split('\\n')[0]?.trim();\n if (!firstLine) return false;\n\n const parsed = this.safeJsonParse<ClaudeCodeMessage>(firstLine);\n if (!parsed) return false;\n\n // Check for Claude Code specific fields\n return (\n parsed.type !== undefined ||\n parsed.message?.role !== undefined ||\n parsed.sessionId !== undefined\n );\n }\n\n async parse(input: string | Buffer): Promise<Trajectory> {\n const str = typeof input === 'string' ? input : input.toString('utf-8');\n const lines = str.split('\\n').filter((line) => line.trim());\n\n const messages: ClaudeCodeMessage[] = [];\n for (const line of lines) {\n const parsed = this.safeJsonParse<ClaudeCodeMessage>(line);\n if (parsed) {\n messages.push(parsed);\n }\n }\n\n return this.convertToTrajectory(messages);\n }\n\n async parseMany(input: string): Promise<Trajectory[]> {\n // If input is a directory path, we'd scan for .jsonl files\n // For now, assume input is file content and parse as single trajectory\n const trajectory = await this.parse(input);\n return [trajectory];\n }\n\n private convertToTrajectory(messages: ClaudeCodeMessage[]): Trajectory {\n const turns: Turn[] = [];\n let sessionId = this.generateSessionId();\n let startedAt = new Date();\n let endedAt: Date | undefined;\n const metadata: TrajectoryMetadata = {\n agentType: 'claude-code',\n custom: {},\n };\n\n // Track tool calls to match with results\n const pendingToolCalls = new Map<string, ToolCall>();\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n\n // Extract session metadata\n if (msg.sessionId) sessionId = msg.sessionId;\n if (msg.timestamp) {\n const ts = new Date(msg.timestamp);\n if (i === 0) startedAt = ts;\n endedAt = ts;\n }\n if (msg.cwd) metadata.workingDirectory = msg.cwd;\n if (msg.model) metadata.model = msg.model;\n\n // Skip summary/stats messages\n if (msg.summary) continue;\n\n // Handle result type (tool results)\n if (msg.type === 'result' && msg.toolUseId) {\n // Find the last assistant turn and add tool result\n const lastAssistantTurn = [...turns].reverse().find((t) => t.role === 'assistant');\n if (lastAssistantTurn) {\n if (!lastAssistantTurn.toolResults) {\n lastAssistantTurn.toolResults = [];\n }\n lastAssistantTurn.toolResults.push({\n callId: msg.toolUseId,\n name: msg.toolName || 'unknown',\n output: msg.result || '',\n success: true, // Claude Code doesn't always indicate errors explicitly\n });\n }\n continue;\n }\n\n // Handle message type\n if (msg.message) {\n const turn = this.convertMessageToTurn(msg, turns.length, pendingToolCalls);\n if (turn) {\n turns.push(turn);\n }\n }\n }\n\n // Determine outcome from the session\n const outcome = this.inferOutcome(turns);\n\n return {\n sessionId,\n startedAt,\n endedAt,\n turns,\n metadata,\n outcome,\n };\n }\n\n private convertMessageToTurn(\n msg: ClaudeCodeMessage,\n index: number,\n pendingToolCalls: Map<string, ToolCall>\n ): Turn | null {\n if (!msg.message) return null;\n\n const { role, content } = msg.message;\n const turn: Turn = {\n index,\n role: role as Turn['role'],\n content: '',\n timestamp: msg.timestamp ? new Date(msg.timestamp) : undefined,\n };\n\n if (typeof content === 'string') {\n turn.content = content;\n } else if (Array.isArray(content)) {\n // Process content blocks\n const textParts: string[] = [];\n const toolCalls: ToolCall[] = [];\n const toolResults: ToolResult[] = [];\n\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n textParts.push(block.text);\n } else if (block.type === 'tool_use' && block.name) {\n const toolCall: ToolCall = {\n name: block.name,\n input: block.input || {},\n callId: block.id,\n };\n toolCalls.push(toolCall);\n if (block.id) {\n pendingToolCalls.set(block.id, toolCall);\n }\n } else if (block.type === 'tool_result') {\n const resultContent = this.extractToolResultContent(block.content);\n toolResults.push({\n callId: block.tool_use_id,\n name: pendingToolCalls.get(block.tool_use_id || '')?.name || 'unknown',\n output: resultContent,\n success: !block.is_error,\n error: block.is_error ? resultContent : undefined,\n });\n }\n }\n\n turn.content = textParts.join('\\n');\n if (toolCalls.length > 0) turn.toolCalls = toolCalls;\n if (toolResults.length > 0) turn.toolResults = toolResults;\n }\n\n return turn;\n }\n\n private extractToolResultContent(\n content: string | ClaudeCodeToolResultContent[] | undefined\n ): string {\n if (!content) return '';\n if (typeof content === 'string') return content;\n if (Array.isArray(content)) {\n return content\n .filter((c) => c.type === 'text')\n .map((c) => c.text)\n .join('\\n');\n }\n return '';\n }\n\n private inferOutcome(turns: Turn[]): TrajectoryOutcome {\n const outcome: TrajectoryOutcome = {\n success: true, // Default to success, look for failure signals\n filesModified: [],\n errors: [],\n };\n\n // Look for patterns that indicate success/failure\n for (const turn of turns) {\n // Check for error patterns in content\n if (turn.content) {\n const lowerContent = turn.content.toLowerCase();\n if (\n lowerContent.includes('error') ||\n lowerContent.includes('failed') ||\n lowerContent.includes(\"couldn't\") ||\n lowerContent.includes(\"can't complete\")\n ) {\n outcome.errors?.push(turn.content.substring(0, 200));\n }\n }\n\n // Check tool results for errors\n if (turn.toolResults) {\n for (const result of turn.toolResults) {\n if (!result.success && result.error) {\n outcome.errors?.push(result.error.substring(0, 200));\n outcome.success = false;\n }\n }\n }\n\n // Track file modifications from tool calls\n if (turn.toolCalls) {\n for (const call of turn.toolCalls) {\n if (['Write', 'Edit', 'MultiEdit'].includes(call.name)) {\n const filePath = call.input.file_path || call.input.filePath;\n if (typeof filePath === 'string') {\n outcome.filesModified?.push(filePath);\n }\n }\n }\n }\n }\n\n // Deduplicate files modified\n outcome.filesModified = [...new Set(outcome.filesModified)];\n\n // If no explicit errors and session completed, assume success\n if (outcome.errors?.length === 0) {\n outcome.success = true;\n }\n\n return outcome;\n }\n}\n\n// Export singleton instance\nexport const claudeCodeAdapter = new ClaudeCodeAdapter();\n","/**\n * OpenAI Chat Completions adapter\n * Parses OpenAI API format sessions into Trajectories\n */\n\nimport { BaseSessionAdapter } from './base.js';\nimport type {\n Trajectory,\n Turn,\n ToolCall,\n ToolResult,\n TrajectoryMetadata,\n} from '../types.js';\n\n/**\n * OpenAI message format\n */\ninterface OpenAIMessage {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string | null;\n name?: string;\n tool_calls?: OpenAIToolCall[];\n tool_call_id?: string;\n}\n\ninterface OpenAIToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * OpenAI conversation/completion format\n */\ninterface OpenAIConversation {\n id?: string;\n model?: string;\n messages: OpenAIMessage[];\n created?: number;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Adapter for OpenAI Chat Completions format\n */\nexport class OpenAIAdapter extends BaseSessionAdapter {\n name = 'openai';\n supportedExtensions = ['.json', '.jsonl'];\n\n canHandle(input: string | Buffer): boolean {\n const str = typeof input === 'string' ? input : input.toString('utf-8');\n\n try {\n // Try parsing as single JSON object\n const parsed = JSON.parse(str);\n\n // Check for OpenAI conversation format\n if (parsed.messages && Array.isArray(parsed.messages)) {\n return this.looksLikeOpenAIMessages(parsed.messages);\n }\n\n // Check for array of messages\n if (Array.isArray(parsed)) {\n return this.looksLikeOpenAIMessages(parsed);\n }\n\n return false;\n } catch {\n // Try as JSONL\n const firstLine = str.split('\\n')[0]?.trim();\n if (!firstLine) return false;\n\n try {\n const parsed = JSON.parse(firstLine);\n return (\n parsed.role !== undefined &&\n ['system', 'user', 'assistant', 'tool'].includes(parsed.role)\n );\n } catch {\n return false;\n }\n }\n }\n\n async parse(input: string | Buffer): Promise<Trajectory> {\n const str = typeof input === 'string' ? input : input.toString('utf-8');\n\n let conversation: OpenAIConversation;\n\n try {\n const parsed = JSON.parse(str);\n\n if (parsed.messages && Array.isArray(parsed.messages)) {\n // Full conversation object\n conversation = parsed as OpenAIConversation;\n } else if (Array.isArray(parsed)) {\n // Array of messages\n conversation = { messages: parsed };\n } else {\n throw new Error('Invalid OpenAI format');\n }\n } catch {\n // Try as JSONL\n const lines = str.split('\\n').filter((l) => l.trim());\n const messages: OpenAIMessage[] = [];\n\n for (const line of lines) {\n try {\n messages.push(JSON.parse(line));\n } catch {\n // Skip invalid lines\n }\n }\n\n conversation = { messages };\n }\n\n return this.convertToTrajectory(conversation);\n }\n\n async parseMany(input: string): Promise<Trajectory[]> {\n // For JSONL with multiple conversations, split by empty lines\n const sections = input.split(/\\n\\n+/);\n const trajectories: Trajectory[] = [];\n\n for (const section of sections) {\n if (section.trim()) {\n try {\n trajectories.push(await this.parse(section));\n } catch {\n // Skip invalid sections\n }\n }\n }\n\n return trajectories.length > 0 ? trajectories : [await this.parse(input)];\n }\n\n private looksLikeOpenAIMessages(messages: unknown[]): boolean {\n if (messages.length === 0) return false;\n\n const first = messages[0] as Record<string, unknown>;\n return (\n first.role !== undefined &&\n ['system', 'user', 'assistant', 'tool'].includes(first.role as string)\n );\n }\n\n private convertToTrajectory(conversation: OpenAIConversation): Trajectory {\n const turns: Turn[] = [];\n const pendingToolCalls = new Map<string, ToolCall>();\n\n const metadata: TrajectoryMetadata = {\n agentType: 'openai',\n model: conversation.model,\n custom: conversation.metadata,\n };\n\n for (let i = 0; i < conversation.messages.length; i++) {\n const msg = conversation.messages[i];\n\n // Handle tool results separately\n if (msg.role === 'tool' && msg.tool_call_id) {\n // Find the last assistant turn and add tool result\n const lastAssistantTurn = [...turns]\n .reverse()\n .find((t) => t.role === 'assistant');\n if (lastAssistantTurn) {\n if (!lastAssistantTurn.toolResults) {\n lastAssistantTurn.toolResults = [];\n }\n const pendingCall = pendingToolCalls.get(msg.tool_call_id);\n lastAssistantTurn.toolResults.push({\n callId: msg.tool_call_id,\n name: pendingCall?.name || msg.name || 'unknown',\n output: msg.content || '',\n success: true,\n });\n }\n continue;\n }\n\n const turn: Turn = {\n index: turns.length,\n role: msg.role as Turn['role'],\n content: msg.content || '',\n };\n\n // Extract tool calls from assistant messages\n if (msg.role === 'assistant' && msg.tool_calls) {\n turn.toolCalls = msg.tool_calls.map((tc) => {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(tc.function.arguments);\n } catch {\n parsedArgs = { raw: tc.function.arguments };\n }\n\n const toolCall: ToolCall = {\n callId: tc.id,\n name: tc.function.name,\n input: parsedArgs,\n };\n\n pendingToolCalls.set(tc.id, toolCall);\n return toolCall;\n });\n }\n\n turns.push(turn);\n }\n\n return {\n sessionId: conversation.id || this.generateSessionId(),\n startedAt: conversation.created\n ? new Date(conversation.created * 1000)\n : new Date(),\n turns,\n metadata,\n };\n }\n}\n\nexport const openAIAdapter = new OpenAIAdapter();\n","/**\n * Anthropic Messages API adapter\n * Parses Anthropic API format sessions into Trajectories\n */\n\nimport { BaseSessionAdapter } from './base.js';\nimport type {\n Trajectory,\n Turn,\n ToolCall,\n ToolResult,\n TrajectoryMetadata,\n} from '../types.js';\n\n/**\n * Anthropic content block types\n */\ntype AnthropicContentBlock =\n | AnthropicTextBlock\n | AnthropicToolUseBlock\n | AnthropicToolResultBlock;\n\ninterface AnthropicTextBlock {\n type: 'text';\n text: string;\n}\n\ninterface AnthropicToolUseBlock {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n}\n\ninterface AnthropicToolResultBlock {\n type: 'tool_result';\n tool_use_id: string;\n content: string | AnthropicContentBlock[];\n is_error?: boolean;\n}\n\n/**\n * Anthropic message format\n */\ninterface AnthropicMessage {\n role: 'user' | 'assistant';\n content: string | AnthropicContentBlock[];\n}\n\n/**\n * Anthropic conversation format\n */\ninterface AnthropicConversation {\n id?: string;\n model?: string;\n system?: string | AnthropicContentBlock[];\n messages: AnthropicMessage[];\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Adapter for Anthropic Messages API format\n */\nexport class AnthropicAdapter extends BaseSessionAdapter {\n name = 'anthropic';\n supportedExtensions = ['.json', '.jsonl'];\n\n canHandle(input: string | Buffer): boolean {\n const str = typeof input === 'string' ? input : input.toString('utf-8');\n\n try {\n const parsed = JSON.parse(str);\n\n // Check for Anthropic conversation format\n if (parsed.messages && Array.isArray(parsed.messages)) {\n return this.looksLikeAnthropicMessages(parsed.messages);\n }\n\n // Check for array of messages\n if (Array.isArray(parsed)) {\n return this.looksLikeAnthropicMessages(parsed);\n }\n\n return false;\n } catch {\n // Try as JSONL\n const firstLine = str.split('\\n')[0]?.trim();\n if (!firstLine) return false;\n\n try {\n const parsed = JSON.parse(firstLine);\n // Anthropic only uses 'user' and 'assistant' roles in messages\n return (\n parsed.role !== undefined &&\n ['user', 'assistant'].includes(parsed.role) &&\n (typeof parsed.content === 'string' || Array.isArray(parsed.content))\n );\n } catch {\n return false;\n }\n }\n }\n\n async parse(input: string | Buffer): Promise<Trajectory> {\n const str = typeof input === 'string' ? input : input.toString('utf-8');\n\n let conversation: AnthropicConversation;\n\n try {\n const parsed = JSON.parse(str);\n\n if (parsed.messages && Array.isArray(parsed.messages)) {\n conversation = parsed as AnthropicConversation;\n } else if (Array.isArray(parsed)) {\n conversation = { messages: parsed };\n } else {\n throw new Error('Invalid Anthropic format');\n }\n } catch {\n // Try as JSONL\n const lines = str.split('\\n').filter((l) => l.trim());\n const messages: AnthropicMessage[] = [];\n\n for (const line of lines) {\n try {\n messages.push(JSON.parse(line));\n } catch {\n // Skip invalid lines\n }\n }\n\n conversation = { messages };\n }\n\n return this.convertToTrajectory(conversation);\n }\n\n async parseMany(input: string): Promise<Trajectory[]> {\n const sections = input.split(/\\n\\n+/);\n const trajectories: Trajectory[] = [];\n\n for (const section of sections) {\n if (section.trim()) {\n try {\n trajectories.push(await this.parse(section));\n } catch {\n // Skip invalid sections\n }\n }\n }\n\n return trajectories.length > 0 ? trajectories : [await this.parse(input)];\n }\n\n private looksLikeAnthropicMessages(messages: unknown[]): boolean {\n if (messages.length === 0) return false;\n\n const first = messages[0] as Record<string, unknown>;\n\n // Anthropic messages only have 'user' or 'assistant' role\n // and content can be string or array of content blocks\n return (\n first.role !== undefined &&\n ['user', 'assistant'].includes(first.role as string) &&\n first.content !== undefined &&\n (typeof first.content === 'string' || Array.isArray(first.content))\n );\n }\n\n private convertToTrajectory(conversation: AnthropicConversation): Trajectory {\n const turns: Turn[] = [];\n const pendingToolCalls = new Map<string, ToolCall>();\n\n const metadata: TrajectoryMetadata = {\n agentType: 'anthropic',\n model: conversation.model,\n custom: conversation.metadata,\n };\n\n // Add system message as first turn if present\n if (conversation.system) {\n const systemContent =\n typeof conversation.system === 'string'\n ? conversation.system\n : this.extractTextContent(conversation.system);\n\n turns.push({\n index: 0,\n role: 'system',\n content: systemContent,\n });\n }\n\n for (const msg of conversation.messages) {\n const turn: Turn = {\n index: turns.length,\n role: msg.role,\n content: '',\n };\n\n if (typeof msg.content === 'string') {\n turn.content = msg.content;\n } else if (Array.isArray(msg.content)) {\n // Process content blocks\n const textParts: string[] = [];\n const toolCalls: ToolCall[] = [];\n const toolResults: ToolResult[] = [];\n\n for (const block of msg.content) {\n switch (block.type) {\n case 'text':\n textParts.push(block.text);\n break;\n\n case 'tool_use': {\n const toolCall: ToolCall = {\n callId: block.id,\n name: block.name,\n input: block.input,\n };\n toolCalls.push(toolCall);\n pendingToolCalls.set(block.id, toolCall);\n break;\n }\n\n case 'tool_result': {\n const pendingCall = pendingToolCalls.get(block.tool_use_id);\n const resultContent =\n typeof block.content === 'string'\n ? block.content\n : this.extractTextContent(block.content);\n\n toolResults.push({\n callId: block.tool_use_id,\n name: pendingCall?.name || 'unknown',\n output: resultContent,\n success: !block.is_error,\n error: block.is_error ? resultContent : undefined,\n });\n break;\n }\n }\n }\n\n turn.content = textParts.join('\\n');\n if (toolCalls.length > 0) {\n turn.toolCalls = toolCalls;\n }\n if (toolResults.length > 0) {\n turn.toolResults = toolResults;\n }\n }\n\n turns.push(turn);\n }\n\n return {\n sessionId: conversation.id || this.generateSessionId(),\n startedAt: new Date(),\n turns,\n metadata,\n };\n }\n\n private extractTextContent(blocks: AnthropicContentBlock[]): string {\n return blocks\n .filter((b): b is AnthropicTextBlock => b.type === 'text')\n .map((b) => b.text)\n .join('\\n');\n }\n}\n\nexport const anthropicAdapter = new AnthropicAdapter();\n","/**\n * Generic JSON/JSONL adapter with configurable field mapping\n * Allows adapting any JSON format to Trajectory\n */\n\nimport { BaseSessionAdapter } from './base.js';\nimport type {\n Trajectory,\n Turn,\n ToolCall,\n TrajectoryMetadata,\n} from '../types.js';\n\n/**\n * Configuration for field mapping\n */\nexport interface GenericAdapterConfig {\n /** Path to messages array (dot notation, e.g., \"conversation.messages\") */\n messagesPath?: string;\n /** Field name for role */\n roleField?: string;\n /** Field name for content */\n contentField?: string;\n /** Mapping of role values to standard roles */\n roleMapping?: Record<string, Turn['role']>;\n /** Field name for timestamp */\n timestampField?: string;\n /** Field name for session ID */\n sessionIdField?: string;\n /** Path to tool calls array within a message */\n toolCallsPath?: string;\n /** Field names within tool call objects */\n toolCallFields?: {\n name?: string;\n input?: string;\n id?: string;\n };\n /** Path to metadata */\n metadataPath?: string;\n /** Custom field extractors */\n customExtractors?: Record<string, (obj: unknown) => unknown>;\n}\n\nconst DEFAULT_CONFIG: Required<Omit<GenericAdapterConfig, 'customExtractors'>> & {\n customExtractors?: GenericAdapterConfig['customExtractors'];\n} = {\n messagesPath: 'messages',\n roleField: 'role',\n contentField: 'content',\n roleMapping: {\n user: 'user',\n assistant: 'assistant',\n system: 'system',\n tool: 'tool',\n human: 'user',\n ai: 'assistant',\n bot: 'assistant',\n },\n timestampField: 'timestamp',\n sessionIdField: 'id',\n toolCallsPath: 'tool_calls',\n toolCallFields: {\n name: 'name',\n input: 'arguments',\n id: 'id',\n },\n metadataPath: 'metadata',\n};\n\n/**\n * Generic adapter for arbitrary JSON/JSONL formats\n */\nexport class GenericAdapter extends BaseSessionAdapter {\n name = 'generic';\n supportedExtensions = ['.json', '.jsonl'];\n private config: typeof DEFAULT_CONFIG;\n\n constructor(config: GenericAdapterConfig = {}) {\n super();\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n roleMapping: { ...DEFAULT_CONFIG.roleMapping, ...config.roleMapping },\n toolCallFields: { ...DEFAULT_CONFIG.toolCallFields, ...config.toolCallFields },\n };\n }\n\n /**\n * Update configuration\n */\n setConfig(config: GenericAdapterConfig): void {\n this.config = {\n ...this.config,\n ...config,\n roleMapping: { ...this.config.roleMapping, ...config.roleMapping },\n toolCallFields: { ...this.config.toolCallFields, ...config.toolCallFields },\n };\n }\n\n /**\n * Get current configuration\n */\n getConfig(): GenericAdapterConfig {\n return { ...this.config };\n }\n\n canHandle(input: string | Buffer): boolean {\n const str = typeof input === 'string' ? input : input.toString('utf-8');\n\n try {\n // Try as JSON\n const parsed = JSON.parse(str);\n return this.canExtractMessages(parsed);\n } catch {\n // Try as JSONL\n const firstLine = str.split('\\n')[0]?.trim();\n if (!firstLine) return false;\n\n try {\n const parsed = JSON.parse(firstLine);\n // Check if it has role and content fields\n return this.looksLikeMessage(parsed);\n } catch {\n return false;\n }\n }\n }\n\n async parse(input: string | Buffer): Promise<Trajectory> {\n const str = typeof input === 'string' ? input : input.toString('utf-8');\n\n try {\n // Try as JSON\n const parsed = JSON.parse(str);\n return this.convertToTrajectory(parsed);\n } catch {\n // Try as JSONL\n const lines = str.split('\\n').filter((l) => l.trim());\n const messages: unknown[] = [];\n\n for (const line of lines) {\n try {\n messages.push(JSON.parse(line));\n } catch {\n // Skip invalid lines\n }\n }\n\n return this.convertToTrajectory({ messages });\n }\n }\n\n async parseMany(input: string): Promise<Trajectory[]> {\n // Try to split by empty lines for multiple conversations\n const sections = input.split(/\\n\\n+/);\n const trajectories: Trajectory[] = [];\n\n for (const section of sections) {\n if (section.trim()) {\n try {\n trajectories.push(await this.parse(section));\n } catch {\n // Skip invalid sections\n }\n }\n }\n\n return trajectories.length > 0 ? trajectories : [await this.parse(input)];\n }\n\n private canExtractMessages(obj: unknown): boolean {\n if (!obj || typeof obj !== 'object') return false;\n\n // Try to get messages using the configured path\n const messages = this.getNestedValue(obj, this.config.messagesPath);\n if (Array.isArray(messages) && messages.length > 0) {\n return this.looksLikeMessage(messages[0]);\n }\n\n // Check if it's directly an array of messages\n if (Array.isArray(obj) && obj.length > 0) {\n return this.looksLikeMessage(obj[0]);\n }\n\n return false;\n }\n\n private looksLikeMessage(obj: unknown): boolean {\n if (!obj || typeof obj !== 'object') return false;\n\n const record = obj as Record<string, unknown>;\n\n // Check for role field\n const role = record[this.config.roleField];\n if (role === undefined) return false;\n\n // Check for content field (can be null for tool calls)\n const content = record[this.config.contentField];\n if (content === undefined) return false;\n\n return true;\n }\n\n private convertToTrajectory(data: unknown): Trajectory {\n const obj = data as Record<string, unknown>;\n\n // Extract messages\n let messages: unknown[];\n const messagesFromPath = this.getNestedValue(obj, this.config.messagesPath);\n\n if (Array.isArray(messagesFromPath)) {\n messages = messagesFromPath;\n } else if (Array.isArray(data)) {\n messages = data;\n } else {\n throw new Error('Could not find messages array');\n }\n\n // Extract session ID\n const sessionId =\n (this.getNestedValue(obj, this.config.sessionIdField) as string) ||\n this.generateSessionId();\n\n // Extract metadata\n const customMetadata = this.getNestedValue(obj, this.config.metadataPath) as\n | Record<string, unknown>\n | undefined;\n\n const metadata: TrajectoryMetadata = {\n agentType: 'generic',\n custom: customMetadata,\n };\n\n // Convert messages to turns\n const turns: Turn[] = [];\n\n for (const msg of messages) {\n const turn = this.convertMessageToTurn(msg as Record<string, unknown>, turns.length);\n if (turn) {\n turns.push(turn);\n }\n }\n\n return {\n sessionId,\n startedAt: this.extractTimestamp(messages[0]) || new Date(),\n endedAt: this.extractTimestamp(messages[messages.length - 1]),\n turns,\n metadata,\n };\n }\n\n private convertMessageToTurn(\n msg: Record<string, unknown>,\n index: number\n ): Turn | null {\n // Extract role\n const rawRole = msg[this.config.roleField];\n if (rawRole === undefined) return null;\n\n const role = this.mapRole(String(rawRole));\n\n // Extract content\n let content = '';\n const rawContent = msg[this.config.contentField];\n if (typeof rawContent === 'string') {\n content = rawContent;\n } else if (rawContent !== null && rawContent !== undefined) {\n content = JSON.stringify(rawContent);\n }\n\n const turn: Turn = {\n index,\n role,\n content,\n timestamp: this.extractTimestamp(msg),\n };\n\n // Extract tool calls\n const toolCallsData = this.getNestedValue(msg, this.config.toolCallsPath);\n if (Array.isArray(toolCallsData) && toolCallsData.length > 0) {\n turn.toolCalls = toolCallsData.map((tc) =>\n this.convertToolCall(tc as Record<string, unknown>)\n );\n }\n\n // Apply custom extractors\n if (this.config.customExtractors) {\n for (const [key, extractor] of Object.entries(this.config.customExtractors)) {\n try {\n const value = extractor(msg);\n if (value !== undefined) {\n turn[key] = value;\n }\n } catch {\n // Skip failed extractors\n }\n }\n }\n\n return turn;\n }\n\n private convertToolCall(tc: Record<string, unknown>): ToolCall {\n const fields = this.config.toolCallFields;\n\n let input: Record<string, unknown> = {};\n const rawInput = tc[fields.input || 'arguments'];\n if (typeof rawInput === 'string') {\n try {\n input = JSON.parse(rawInput);\n } catch {\n input = { raw: rawInput };\n }\n } else if (rawInput && typeof rawInput === 'object') {\n input = rawInput as Record<string, unknown>;\n }\n\n return {\n callId: tc[fields.id || 'id'] as string | undefined,\n name: (tc[fields.name || 'name'] as string) || 'unknown',\n input,\n };\n }\n\n private mapRole(rawRole: string): Turn['role'] {\n const normalized = rawRole.toLowerCase();\n return this.config.roleMapping[normalized] || 'user';\n }\n\n private extractTimestamp(msg: unknown): Date | undefined {\n if (!msg || typeof msg !== 'object') return undefined;\n\n const record = msg as Record<string, unknown>;\n const tsValue = record[this.config.timestampField];\n\n if (!tsValue) return undefined;\n\n if (typeof tsValue === 'number') {\n // Unix timestamp (seconds or milliseconds)\n return new Date(tsValue > 1e12 ? tsValue : tsValue * 1000);\n }\n\n if (typeof tsValue === 'string') {\n const parsed = new Date(tsValue);\n return isNaN(parsed.getTime()) ? undefined : parsed;\n }\n\n return undefined;\n }\n\n private getNestedValue(obj: unknown, path: string): unknown {\n if (!obj || typeof obj !== 'object') return undefined;\n\n const parts = path.split('.');\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n if (typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[part];\n }\n\n return current;\n }\n}\n\n/**\n * Create a generic adapter with custom configuration\n */\nexport function createGenericAdapter(config: GenericAdapterConfig): GenericAdapter {\n return new GenericAdapter(config);\n}\n\nexport const genericAdapter = new GenericAdapter();\n","/**\n * Session adapters for parsing different agent trajectory formats\n */\n\nexport { BaseSessionAdapter, AdapterRegistry, adapterRegistry } from './base.js';\nexport { ClaudeCodeAdapter, claudeCodeAdapter } from './claude-code.js';\nexport { OpenAIAdapter, openAIAdapter } from './openai.js';\nexport { AnthropicAdapter, anthropicAdapter } from './anthropic.js';\nexport {\n GenericAdapter,\n genericAdapter,\n createGenericAdapter,\n type GenericAdapterConfig,\n} from './generic.js';\n\n// Re-export types\nexport type { SessionAdapter } from '../types.js';\n\n// Register all adapters with the global registry\nimport { adapterRegistry } from './base.js';\nimport { claudeCodeAdapter } from './claude-code.js';\nimport { openAIAdapter } from './openai.js';\nimport { anthropicAdapter } from './anthropic.js';\nimport { genericAdapter } from './generic.js';\n\n// Note: Order matters - more specific adapters should be registered first\n// so they get priority in auto-detection\nadapterRegistry.register(claudeCodeAdapter);\nadapterRegistry.register(openAIAdapter);\nadapterRegistry.register(anthropicAdapter);\nadapterRegistry.register(genericAdapter);\n","/**\n * Quality gates for skill extraction\n * Inspired by Claudeception's quality criteria\n */\n\nimport type {\n QualityGate,\n QualityGateResult,\n Skill,\n Trajectory,\n Turn,\n} from '../types.js';\n\n/**\n * Default quality gates based on Claudeception criteria\n */\nexport const DEFAULT_QUALITY_GATES: QualityGate[] = [\n {\n name: 'reusability',\n type: 'reusability',\n description: 'Skill should be applicable across multiple future tasks, not one-off',\n required: true,\n },\n {\n name: 'non-trivial',\n type: 'non-trivial',\n description: 'Skill should involve discovery beyond basic documentation lookup',\n required: true,\n },\n {\n name: 'specific-triggers',\n type: 'specific',\n description: 'Skill should have clear, specific trigger conditions',\n required: true,\n },\n {\n name: 'verified',\n type: 'verified',\n description: 'Skill solution should be verified to actually work',\n required: false,\n },\n];\n\n/**\n * Quality gate evaluator\n */\nexport class QualityGateEvaluator {\n private gates: QualityGate[];\n\n constructor(gates: QualityGate[] = DEFAULT_QUALITY_GATES) {\n this.gates = gates;\n }\n\n /**\n * Evaluate all quality gates for a skill candidate\n */\n async evaluate(\n skill: Partial<Skill>,\n trajectory: Trajectory,\n turnRange: [number, number]\n ): Promise<{ passed: boolean; results: QualityGateResult[] }> {\n const results: QualityGateResult[] = [];\n\n for (const gate of this.gates) {\n const result = await this.evaluateGate(gate, skill, trajectory, turnRange);\n results.push(result);\n }\n\n // Check if all required gates passed\n const passed = results.every((r) => {\n const gate = this.gates.find((g) => g.name === r.gateName);\n return !gate?.required || r.passed;\n });\n\n return { passed, results };\n }\n\n private async evaluateGate(\n gate: QualityGate,\n skill: Partial<Skill>,\n trajectory: Trajectory,\n turnRange: [number, number]\n ): Promise<QualityGateResult> {\n const turns = trajectory.turns.slice(turnRange[0], turnRange[1] + 1);\n\n switch (gate.type) {\n case 'reusability':\n return this.evaluateReusability(gate, skill, turns);\n case 'non-trivial':\n return this.evaluateNonTrivial(gate, skill, turns);\n case 'specific':\n return this.evaluateSpecificTriggers(gate, skill);\n case 'verified':\n return this.evaluateVerified(gate, trajectory);\n case 'custom':\n return this.evaluateCustom(gate, skill, trajectory, turns);\n default:\n return {\n gateName: gate.name,\n passed: true,\n score: 1.0,\n explanation: 'Unknown gate type, passing by default',\n };\n }\n }\n\n private evaluateReusability(\n gate: QualityGate,\n skill: Partial<Skill>,\n turns: Turn[]\n ): QualityGateResult {\n let score = 0;\n const reasons: string[] = [];\n\n // Check if skill has generic patterns vs project-specific\n const description = skill.description || '';\n const problem = skill.problem || '';\n const combined = `${description} ${problem}`.toLowerCase();\n\n // Positive signals for reusability\n const reusabilitySignals = [\n 'error',\n 'bug',\n 'fix',\n 'pattern',\n 'when',\n 'if',\n 'always',\n 'common',\n 'typical',\n 'usually',\n ];\n const signalCount = reusabilitySignals.filter((s) => combined.includes(s)).length;\n score += Math.min(signalCount * 0.15, 0.45);\n\n // Negative signals (too project-specific)\n const specificSignals = [\n 'this project',\n 'this repo',\n 'our codebase',\n 'specific to',\n 'only in',\n ];\n const specificCount = specificSignals.filter((s) => combined.includes(s)).length;\n score -= specificCount * 0.2;\n\n // Check if triggers are generic enough\n if (skill.triggerConditions && skill.triggerConditions.length > 0) {\n const hasGenericTrigger = skill.triggerConditions.some(\n (t) => t.type === 'error' || t.type === 'pattern'\n );\n if (hasGenericTrigger) {\n score += 0.25;\n reasons.push('Has generic trigger conditions');\n }\n }\n\n // Check tool usage patterns (more diverse = more reusable learning)\n const toolNames = new Set<string>();\n for (const turn of turns) {\n turn.toolCalls?.forEach((tc) => toolNames.add(tc.name));\n }\n if (toolNames.size > 2) {\n score += 0.15;\n reasons.push(`Uses ${toolNames.size} different tools`);\n }\n\n score = Math.max(0, Math.min(1, score + 0.3)); // Base score of 0.3\n\n return {\n gateName: gate.name,\n passed: score >= 0.5,\n score,\n explanation:\n reasons.length > 0\n ? reasons.join('; ')\n : score >= 0.5\n ? 'Skill appears reusable'\n : 'Skill may be too project-specific',\n };\n }\n\n private evaluateNonTrivial(\n gate: QualityGate,\n skill: Partial<Skill>,\n turns: Turn[]\n ): QualityGateResult {\n let score = 0;\n const reasons: string[] = [];\n\n // Check turn count (more turns = more investigation)\n if (turns.length >= 5) {\n score += 0.2;\n reasons.push(`${turns.length} turns of investigation`);\n } else if (turns.length >= 3) {\n score += 0.1;\n }\n\n // Check for error-recovery patterns\n const hasErrors = turns.some(\n (t) => t.toolResults?.some((r) => !r.success) || t.content?.toLowerCase().includes('error')\n );\n if (hasErrors) {\n score += 0.25;\n reasons.push('Involves error diagnosis/recovery');\n }\n\n // Check for iteration/refinement\n const toolCallCounts = new Map<string, number>();\n for (const turn of turns) {\n turn.toolCalls?.forEach((tc) => {\n toolCallCounts.set(tc.name, (toolCallCounts.get(tc.name) || 0) + 1);\n });\n }\n const hasIteration = Array.from(toolCallCounts.values()).some((count) => count >= 3);\n if (hasIteration) {\n score += 0.2;\n reasons.push('Shows iterative refinement');\n }\n\n // Check solution complexity\n const solutionLength = (skill.solution || '').length;\n if (solutionLength > 500) {\n score += 0.2;\n reasons.push('Detailed solution');\n } else if (solutionLength > 200) {\n score += 0.1;\n }\n\n // Check for non-obvious keywords in problem/solution\n const nonObviousSignals = [\n 'workaround',\n 'trick',\n 'gotcha',\n 'subtle',\n 'hidden',\n 'unexpected',\n 'actually',\n 'turns out',\n 'discovered',\n 'realized',\n ];\n const content = `${skill.problem || ''} ${skill.solution || ''}`.toLowerCase();\n const nonObviousCount = nonObviousSignals.filter((s) => content.includes(s)).length;\n score += Math.min(nonObviousCount * 0.1, 0.25);\n if (nonObviousCount > 0) {\n reasons.push('Contains non-obvious discoveries');\n }\n\n score = Math.max(0, Math.min(1, score));\n\n return {\n gateName: gate.name,\n passed: score >= 0.4,\n score,\n explanation:\n reasons.length > 0\n ? reasons.join('; ')\n : score >= 0.4\n ? 'Skill involves non-trivial discovery'\n : 'Skill may be too trivial (basic documentation lookup)',\n };\n }\n\n private evaluateSpecificTriggers(gate: QualityGate, skill: Partial<Skill>): QualityGateResult {\n const triggers = skill.triggerConditions || [];\n\n if (triggers.length === 0) {\n return {\n gateName: gate.name,\n passed: false,\n score: 0,\n explanation: 'No trigger conditions defined',\n };\n }\n\n let score = 0;\n const reasons: string[] = [];\n\n // Check trigger quality\n for (const trigger of triggers) {\n // Has a meaningful value\n if (trigger.value && trigger.value.length > 10) {\n score += 0.2;\n }\n\n // Has a description\n if (trigger.description) {\n score += 0.1;\n }\n\n // Error triggers with specific messages are valuable\n if (trigger.type === 'error' && trigger.value.length > 20) {\n score += 0.15;\n reasons.push('Has specific error trigger');\n }\n\n // Pattern triggers with regex are valuable\n if (trigger.type === 'pattern') {\n score += 0.15;\n reasons.push('Has pattern-based trigger');\n }\n }\n\n score = Math.min(1, score);\n\n return {\n gateName: gate.name,\n passed: score >= 0.4,\n score,\n explanation:\n reasons.length > 0\n ? reasons.join('; ')\n : score >= 0.4\n ? 'Has specific trigger conditions'\n : 'Trigger conditions need more specificity',\n };\n }\n\n private evaluateVerified(gate: QualityGate, trajectory: Trajectory): QualityGateResult {\n // Check if the trajectory ended successfully\n const success = trajectory.outcome?.success ?? false;\n const hasVerification = trajectory.turns.some((t) => {\n const content = t.content?.toLowerCase() || '';\n return (\n content.includes('works') ||\n content.includes('fixed') ||\n content.includes('solved') ||\n content.includes('success')\n );\n });\n\n const score = success ? 0.7 : hasVerification ? 0.5 : 0.2;\n\n return {\n gateName: gate.name,\n passed: score >= 0.5,\n score,\n explanation: success\n ? 'Session completed successfully'\n : hasVerification\n ? 'Solution appears verified in conversation'\n : 'Solution verification unclear',\n };\n }\n\n private evaluateCustom(\n gate: QualityGate,\n _skill: Partial<Skill>,\n _trajectory: Trajectory,\n _turns: Turn[]\n ): QualityGateResult {\n // Custom gates would be implemented by subclasses or callbacks\n return {\n gateName: gate.name,\n passed: true,\n score: 1.0,\n explanation: 'Custom gate - no implementation provided',\n };\n }\n\n /**\n * Add a custom quality gate\n */\n addGate(gate: QualityGate): void {\n this.gates.push(gate);\n }\n\n /**\n * Remove a quality gate by name\n */\n removeGate(name: string): boolean {\n const index = this.gates.findIndex((g) => g.name === name);\n if (index >= 0) {\n this.gates.splice(index, 1);\n return true;\n }\n return false;\n }\n\n /**\n * Get all configured gates\n */\n getGates(): QualityGate[] {\n return [...this.gates];\n }\n}\n","/**\n * Base skill extractor\n */\n\nimport type {\n Skill,\n Trajectory,\n ExtractionConfig,\n ExtractionResult,\n QualityGate,\n SkillMetrics,\n SkillSource,\n SkillServingMetadata,\n ExpandTriggerConfig,\n} from '../types.js';\nimport { QualityGateEvaluator, DEFAULT_QUALITY_GATES } from './quality-gates.js';\n\n/**\n * Abstract base class for skill extractors\n */\nexport abstract class BaseExtractor {\n protected config: ExtractionConfig;\n protected gateEvaluator: QualityGateEvaluator;\n\n constructor(config?: Partial<ExtractionConfig>) {\n this.config = {\n mode: config?.mode || 'manual',\n qualityGates: config?.qualityGates || DEFAULT_QUALITY_GATES,\n minConfidence: config?.minConfidence ?? 0.6,\n llmProvider: config?.llmProvider,\n };\n this.gateEvaluator = new QualityGateEvaluator(this.config.qualityGates);\n }\n\n /**\n * Extract skill(s) from a trajectory\n */\n abstract extract(\n trajectory: Trajectory,\n options?: ExtractOptions\n ): Promise<ExtractionResult[]>;\n\n /**\n * Create initial skill metrics\n */\n protected createInitialMetrics(): SkillMetrics {\n return {\n usageCount: 0,\n successRate: 0,\n feedbackScores: [],\n };\n }\n\n /**\n * Create skill source info for extracted skills\n */\n protected createSource(trajectory: Trajectory, type: SkillSource['type']): SkillSource {\n return {\n type,\n sessionId: trajectory.sessionId,\n importedAt: new Date(),\n };\n }\n\n /**\n * Generate a skill ID from name\n */\n protected generateSkillId(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n }\n\n /**\n * Validate and run quality gates on extracted skill\n */\n protected async validateWithGates(\n skill: Partial<Skill>,\n trajectory: Trajectory,\n turnRange: [number, number]\n ): Promise<{ passed: boolean; results: ExtractionResult['gateResults'] }> {\n return this.gateEvaluator.evaluate(skill, trajectory, turnRange);\n }\n\n /**\n * Add or update quality gates\n */\n setQualityGates(gates: QualityGate[]): void {\n this.config.qualityGates = gates;\n this.gateEvaluator = new QualityGateEvaluator(gates);\n }\n\n /**\n * Get current configuration\n */\n getConfig(): ExtractionConfig {\n return { ...this.config };\n }\n\n /**\n * Compute serving metadata for a skill\n * Estimates token count and infers auto-expand triggers from content\n */\n protected computeServingMetadata(skill: Partial<Skill>): SkillServingMetadata {\n return computeServingMetadata(skill);\n }\n}\n\n/**\n * Compute serving metadata for a skill.\n * Exported for use outside of extractors (e.g., promoteToSkill).\n */\nexport function computeServingMetadata(skill: Partial<Skill>): SkillServingMetadata {\n // Estimate token count (~4 chars per token for English text)\n const textContent = [\n skill.problem || '',\n skill.solution || '',\n skill.verification || '',\n skill.notes || '',\n skill.description || '',\n ...(skill.examples || []).map((e) => `${e.scenario} ${e.before} ${e.after}`),\n ...(skill.triggerConditions || []).map((t) => `${t.type} ${t.value} ${t.description || ''}`),\n ].join(' ');\n const tokenEstimate = Math.ceil(textContent.length / 4);\n\n // Infer auto-expand triggers from trigger conditions\n const autoExpand: ExpandTriggerConfig[] = [];\n\n const errorTriggers = (skill.triggerConditions || []).filter((t) => t.type === 'error');\n if (errorTriggers.length > 0) {\n autoExpand.push({\n on: 'error-match',\n conditions: {\n errorPatterns: errorTriggers.map((t) => t.value),\n },\n });\n }\n\n const keywordTriggers = (skill.triggerConditions || []).filter(\n (t) => t.type === 'keyword' || t.type === 'pattern'\n );\n if (keywordTriggers.length > 0) {\n autoExpand.push({\n on: 'mention',\n conditions: {\n keywords: keywordTriggers.map((t) => t.value),\n },\n });\n }\n\n return {\n summary: skill.description?.substring(0, 150),\n tokenEstimate,\n ...(autoExpand.length > 0 ? { autoExpand } : {}),\n };\n}\n\nexport interface ExtractOptions {\n /** Turn range to extract from [start, end] */\n turnRange?: [number, number];\n /** Skip quality gate validation */\n skipValidation?: boolean;\n /** Override minimum confidence */\n minConfidence?: number;\n /** Suggested skill name */\n suggestedName?: string;\n /** Additional context for extraction */\n context?: string;\n}\n","/**\n * Manual skill extractor\n * For explicit/targeted skill extraction with user guidance\n */\n\nimport type {\n Skill,\n Trajectory,\n ExtractionResult,\n TriggerCondition,\n SkillExample,\n ManualExtractionRequest,\n ToolCall,\n} from '../types.js';\nimport { BaseExtractor, ExtractOptions } from './base.js';\n\n/**\n * Manual extractor for explicit skill extraction\n * User provides guidance on what to extract\n */\nexport class ManualExtractor extends BaseExtractor {\n constructor(config?: Parameters<typeof BaseExtractor['prototype']['setQualityGates']>[0]) {\n super({ mode: 'manual', qualityGates: config });\n }\n\n /**\n * Extract a skill from a trajectory with manual guidance\n */\n async extract(\n trajectory: Trajectory,\n options?: ExtractOptions & ManualExtractionRequest\n ): Promise<ExtractionResult[]> {\n const turnRange: [number, number] = options?.turnRange || [\n 0,\n trajectory.turns.length - 1,\n ];\n const turns = trajectory.turns.slice(turnRange[0], turnRange[1] + 1);\n\n // Build skill from trajectory content\n const skill = this.buildSkillFromTurns(trajectory, turns, options);\n\n // Run quality gates unless skipped\n if (!options?.skipValidation) {\n const validation = await this.validateWithGates(skill, trajectory, turnRange);\n\n if (!validation.passed) {\n return [\n {\n success: false,\n confidence: this.calculateConfidence(validation.results),\n gateResults: validation.results,\n failureReason: 'Quality gates not passed',\n sourceTrajectory: {\n sessionId: trajectory.sessionId,\n turnRange,\n },\n },\n ];\n }\n\n return [\n {\n success: true,\n skill: skill as Skill,\n confidence: this.calculateConfidence(validation.results),\n gateResults: validation.results,\n sourceTrajectory: {\n sessionId: trajectory.sessionId,\n turnRange,\n },\n },\n ];\n }\n\n // Skip validation, return with high confidence\n return [\n {\n success: true,\n skill: skill as Skill,\n confidence: 0.8,\n gateResults: [],\n sourceTrajectory: {\n sessionId: trajectory.sessionId,\n turnRange,\n },\n },\n ];\n }\n\n /**\n * Build a skill object from trajectory turns\n */\n private buildSkillFromTurns(\n trajectory: Trajectory,\n turns: Trajectory['turns'],\n options?: ExtractOptions & Partial<ManualExtractionRequest>\n ): Partial<Skill> {\n // Extract problem from initial user message\n const firstUserTurn = turns.find((t) => t.role === 'user');\n const problem = firstUserTurn?.content || 'Problem not specified';\n\n // Extract solution from assistant turns\n const assistantTurns = turns.filter((t) => t.role === 'assistant');\n const solution = this.buildSolutionFromTurns(assistantTurns);\n\n // Infer trigger conditions\n const triggerConditions = this.inferTriggerConditions(turns);\n\n // Build example from the trajectory itself\n const example = this.buildExampleFromTurns(turns);\n\n // Generate name\n const name = options?.suggestedName || this.inferSkillName(problem, solution);\n const id = this.generateSkillId(name);\n\n // Generate description optimized for semantic matching\n const description =\n options?.description || this.generateDescription(problem, triggerConditions);\n\n const partialSkill: Partial<Skill> = {\n id,\n name,\n version: '1.0.0',\n description,\n problem: this.truncate(problem, 1000),\n triggerConditions,\n solution,\n verification: this.inferVerification(trajectory),\n examples: example ? [example] : [],\n notes: this.extractNotes(turns),\n author: 'extracted',\n tags: options?.tags || this.inferTags(problem, solution),\n createdAt: new Date(),\n updatedAt: new Date(),\n status: 'draft',\n metrics: this.createInitialMetrics(),\n source: this.createSource(trajectory, 'extracted'),\n };\n\n // Populate serving metadata for context budgeting and auto-expansion\n partialSkill.serving = this.computeServingMetadata(partialSkill);\n\n return partialSkill;\n }\n\n /**\n * Build solution text from assistant turns\n */\n private buildSolutionFromTurns(assistantTurns: Trajectory['turns']): string {\n const steps: string[] = [];\n\n for (let i = 0; i < assistantTurns.length; i++) {\n const turn = assistantTurns[i];\n\n // Add text content\n if (turn.content && turn.content.trim()) {\n steps.push(turn.content.trim());\n }\n\n // Add tool actions as steps\n if (turn.toolCalls) {\n for (const call of turn.toolCalls) {\n const toolStep = this.formatToolCallAsStep(call);\n if (toolStep) {\n steps.push(toolStep);\n }\n }\n }\n }\n\n // Number the steps\n return steps\n .filter((s) => s.length > 10) // Filter out trivial steps\n .slice(0, 10) // Limit to 10 steps\n .map((step, i) => `${i + 1}. ${step}`)\n .join('\\n\\n');\n }\n\n /**\n * Format a tool call as a solution step\n */\n private formatToolCallAsStep(call: ToolCall): string | null {\n const { name, input } = call;\n\n switch (name) {\n case 'Read':\n return `Read file: \\`${input.file_path || input.path}\\``;\n case 'Write':\n return `Create/write file: \\`${input.file_path || input.path}\\``;\n case 'Edit':\n return `Edit file: \\`${input.file_path || input.path}\\``;\n case 'Bash':\n return `Run command: \\`${this.truncate(String(input.command || ''), 100)}\\``;\n case 'Grep':\n return `Search for: \\`${input.pattern}\\``;\n case 'Glob':\n return `Find files matching: \\`${input.pattern}\\``;\n default:\n return null; // Skip unknown tools\n }\n }\n\n /**\n * Infer trigger conditions from turns\n */\n private inferTriggerConditions(turns: Trajectory['turns']): TriggerCondition[] {\n const conditions: TriggerCondition[] = [];\n\n for (const turn of turns) {\n // Look for error messages in tool results\n if (turn.toolResults) {\n for (const result of turn.toolResults) {\n if (!result.success && result.error) {\n conditions.push({\n type: 'error',\n value: this.extractErrorSignature(result.error),\n description: `Error from ${result.name}`,\n });\n }\n }\n }\n\n // Look for error patterns in content\n const content = turn.content || '';\n const errorMatch = content.match(/error[:\\s]+([^\\n]+)/i);\n if (errorMatch) {\n conditions.push({\n type: 'error',\n value: errorMatch[1].trim(),\n });\n }\n }\n\n // Add keyword triggers from problem description\n const firstUserTurn = turns.find((t) => t.role === 'user');\n if (firstUserTurn?.content) {\n const keywords = this.extractKeywords(firstUserTurn.content);\n if (keywords.length > 0) {\n conditions.push({\n type: 'keyword',\n value: keywords.join(', '),\n description: 'Keywords from original problem',\n });\n }\n }\n\n // Deduplicate\n return this.deduplicateTriggers(conditions);\n }\n\n /**\n * Extract a representative error signature\n */\n private extractErrorSignature(error: string): string {\n // Try to extract the core error message\n const lines = error.split('\\n');\n const errorLine = lines.find(\n (l) =>\n l.toLowerCase().includes('error') ||\n l.toLowerCase().includes('exception') ||\n l.toLowerCase().includes('failed')\n );\n return this.truncate(errorLine || lines[0] || error, 200);\n }\n\n /**\n * Extract meaningful keywords from text\n */\n private extractKeywords(text: string): string[] {\n // Simple keyword extraction - could be enhanced with NLP\n const words = text.toLowerCase().split(/\\W+/);\n const stopWords = new Set([\n 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been',\n 'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will',\n 'would', 'could', 'should', 'may', 'might', 'can', 'this',\n 'that', 'these', 'those', 'i', 'you', 'he', 'she', 'it',\n 'we', 'they', 'what', 'which', 'who', 'when', 'where', 'how',\n 'to', 'from', 'in', 'on', 'at', 'by', 'for', 'with', 'about',\n 'into', 'through', 'during', 'before', 'after', 'above', 'below',\n 'and', 'or', 'but', 'if', 'then', 'else', 'so', 'because',\n 'as', 'until', 'while', 'of', 'not', 'no', 'just', 'only',\n ]);\n\n const keywords = words\n .filter((w) => w.length > 3 && !stopWords.has(w))\n .slice(0, 5);\n\n return [...new Set(keywords)];\n }\n\n /**\n * Deduplicate trigger conditions\n */\n private deduplicateTriggers(triggers: TriggerCondition[]): TriggerCondition[] {\n const seen = new Set<string>();\n return triggers.filter((t) => {\n const key = `${t.type}:${t.value}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n }\n\n /**\n * Build an example from the trajectory\n */\n private buildExampleFromTurns(turns: Trajectory['turns']): SkillExample | null {\n const firstUserTurn = turns.find((t) => t.role === 'user');\n const lastAssistantTurn = [...turns].reverse().find((t) => t.role === 'assistant');\n\n if (!firstUserTurn || !lastAssistantTurn) return null;\n\n return {\n scenario: 'Original extraction context',\n before: this.truncate(firstUserTurn.content || '', 500),\n after: this.truncate(lastAssistantTurn.content || '', 500),\n };\n }\n\n /**\n * Infer skill name from problem and solution\n */\n private inferSkillName(problem: string, solution: string): string {\n // Try to extract a meaningful name from the content\n const combined = `${problem} ${solution}`.toLowerCase();\n\n // Look for common patterns\n const patterns = [\n /fix(?:ing|ed)?\\s+(\\w+(?:\\s+\\w+)?)/i,\n /solv(?:e|ing|ed)\\s+(\\w+(?:\\s+\\w+)?)/i,\n /handl(?:e|ing|ed)\\s+(\\w+(?:\\s+\\w+)?)/i,\n /(\\w+)\\s+error/i,\n /(\\w+)\\s+issue/i,\n /(\\w+)\\s+problem/i,\n ];\n\n for (const pattern of patterns) {\n const match = combined.match(pattern);\n if (match && match[1]) {\n return `${match[1].trim()}-fix`;\n }\n }\n\n // Fallback to first few words\n const words = problem.split(/\\s+/).slice(0, 4).join('-');\n return words.toLowerCase().replace(/[^a-z0-9-]/g, '') || 'extracted-skill';\n }\n\n /**\n * Generate a description optimized for semantic matching\n */\n private generateDescription(problem: string, triggers: TriggerCondition[]): string {\n // Start with the problem summary\n let desc = this.truncate(problem, 150);\n\n // Add trigger hints\n const errorTriggers = triggers.filter((t) => t.type === 'error');\n if (errorTriggers.length > 0) {\n desc += ` Triggered by: ${errorTriggers[0].value}`;\n }\n\n return desc;\n }\n\n /**\n * Infer verification steps\n */\n private inferVerification(trajectory: Trajectory): string {\n if (trajectory.outcome?.success) {\n return 'Verified: Session completed successfully.';\n }\n return 'Verify by checking that the original error no longer occurs.';\n }\n\n /**\n * Extract notes from turns (warnings, caveats, etc.)\n */\n private extractNotes(turns: Trajectory['turns']): string | undefined {\n const notes: string[] = [];\n\n for (const turn of turns) {\n const content = turn.content || '';\n\n // Look for warning/caveat patterns\n if (\n content.toLowerCase().includes('note:') ||\n content.toLowerCase().includes('warning:') ||\n content.toLowerCase().includes('caveat:') ||\n content.toLowerCase().includes('important:')\n ) {\n const match = content.match(/(note|warning|caveat|important):\\s*([^\\n]+)/i);\n if (match) {\n notes.push(match[0]);\n }\n }\n }\n\n return notes.length > 0 ? notes.join('\\n') : undefined;\n }\n\n /**\n * Infer tags from content\n */\n private inferTags(problem: string, solution: string): string[] {\n const tags: string[] = [];\n const content = `${problem} ${solution}`.toLowerCase();\n\n // Technology tags\n const techPatterns: [RegExp, string][] = [\n [/typescript|\\.ts\\b/i, 'typescript'],\n [/javascript|\\.js\\b/i, 'javascript'],\n [/python|\\.py\\b/i, 'python'],\n [/react/i, 'react'],\n [/node\\.?js/i, 'nodejs'],\n [/docker/i, 'docker'],\n [/git\\b/i, 'git'],\n [/npm|yarn|pnpm/i, 'package-manager'],\n [/test|jest|vitest|mocha/i, 'testing'],\n [/database|sql|postgres|mysql|mongo/i, 'database'],\n [/api|rest|graphql/i, 'api'],\n ];\n\n for (const [pattern, tag] of techPatterns) {\n if (pattern.test(content)) {\n tags.push(tag);\n }\n }\n\n // Problem type tags\n if (content.includes('error') || content.includes('fix')) {\n tags.push('debugging');\n }\n if (content.includes('performance') || content.includes('slow')) {\n tags.push('performance');\n }\n if (content.includes('security') || content.includes('auth')) {\n tags.push('security');\n }\n\n return [...new Set(tags)].slice(0, 5);\n }\n\n /**\n * Calculate confidence from gate results\n */\n private calculateConfidence(\n gateResults: ExtractionResult['gateResults']\n ): number {\n if (gateResults.length === 0) return 0.5;\n const avgScore =\n gateResults.reduce((sum, r) => sum + r.score, 0) / gateResults.length;\n return Math.round(avgScore * 100) / 100;\n }\n\n /**\n * Truncate text to max length\n */\n private truncate(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n return text.substring(0, maxLength - 3) + '...';\n }\n}\n","/**\n * Automatic skill extractor\n * Uses LLM to identify and extract skills from trajectories\n */\n\nimport type {\n Skill,\n Trajectory,\n ExtractionResult,\n LLMProvider,\n TriggerCondition,\n SkillExample,\n} from '../types.js';\nimport { BaseExtractor, ExtractOptions } from './base.js';\n\n/**\n * Skill candidate identified by LLM analysis\n */\ninterface SkillCandidate {\n name: string;\n description: string;\n problem: string;\n solution: string;\n triggerConditions: TriggerCondition[];\n verification: string;\n turnRange: [number, number];\n confidence: number;\n reasoning: string;\n}\n\n/**\n * Automatic extractor using LLM for skill identification\n */\nexport class AutomaticExtractor extends BaseExtractor {\n private llmProvider: LLMProvider | null;\n\n constructor(config?: {\n llmProvider?: LLMProvider;\n qualityGates?: Parameters<typeof BaseExtractor['prototype']['setQualityGates']>[0];\n minConfidence?: number;\n }) {\n super({\n mode: 'automatic',\n qualityGates: config?.qualityGates,\n minConfidence: config?.minConfidence,\n llmProvider: config?.llmProvider,\n });\n this.llmProvider = config?.llmProvider || null;\n }\n\n /**\n * Set the LLM provider for automatic extraction\n */\n setLLMProvider(provider: LLMProvider): void {\n this.llmProvider = provider;\n this.config.llmProvider = provider;\n }\n\n /**\n * Extract skills automatically from a trajectory\n */\n async extract(\n trajectory: Trajectory,\n options?: ExtractOptions\n ): Promise<ExtractionResult[]> {\n if (!this.llmProvider) {\n return [\n {\n success: false,\n confidence: 0,\n gateResults: [],\n failureReason: 'No LLM provider configured for automatic extraction',\n sourceTrajectory: {\n sessionId: trajectory.sessionId,\n turnRange: options?.turnRange || [0, trajectory.turns.length - 1],\n },\n },\n ];\n }\n\n // Step 1: Analyze trajectory to identify skill candidates\n const candidates = await this.identifySkillCandidates(trajectory, options);\n\n if (candidates.length === 0) {\n return [\n {\n success: false,\n confidence: 0,\n gateResults: [],\n failureReason: 'No extractable skills identified in trajectory',\n sourceTrajectory: {\n sessionId: trajectory.sessionId,\n turnRange: options?.turnRange || [0, trajectory.turns.length - 1],\n },\n },\n ];\n }\n\n // Step 2: Extract and validate each candidate\n const results: ExtractionResult[] = [];\n const minConfidence = options?.minConfidence ?? this.config.minConfidence ?? 0.6;\n\n for (const candidate of candidates) {\n // Skip low-confidence candidates\n if (candidate.confidence < minConfidence) {\n results.push({\n success: false,\n confidence: candidate.confidence,\n gateResults: [],\n failureReason: `Confidence ${candidate.confidence} below threshold ${minConfidence}`,\n sourceTrajectory: {\n sessionId: trajectory.sessionId,\n turnRange: candidate.turnRange,\n },\n });\n continue;\n }\n\n // Build skill from candidate\n const skill = this.buildSkillFromCandidate(candidate, trajectory);\n\n // Run quality gates\n if (!options?.skipValidation) {\n const validation = await this.validateWithGates(\n skill,\n trajectory,\n candidate.turnRange\n );\n\n if (!validation.passed) {\n results.push({\n success: false,\n skill: skill as Skill,\n confidence: candidate.confidence,\n gateResults: validation.results,\n failureReason: 'Quality gates not passed',\n sourceTrajectory: {\n sessionId: trajectory.sessionId,\n turnRange: candidate.turnRange,\n },\n });\n continue;\n }\n\n results.push({\n success: true,\n skill: skill as Skill,\n confidence: candidate.confidence,\n gateResults: validation.results,\n sourceTrajectory: {\n sessionId: trajectory.sessionId,\n turnRange: candidate.turnRange,\n },\n });\n } else {\n results.push({\n success: true,\n skill: skill as Skill,\n confidence: candidate.confidence,\n gateResults: [],\n sourceTrajectory: {\n sessionId: trajectory.sessionId,\n turnRange: candidate.turnRange,\n },\n });\n }\n }\n\n return results;\n }\n\n /**\n * Identify skill candidates using LLM analysis\n */\n private async identifySkillCandidates(\n trajectory: Trajectory,\n options?: ExtractOptions\n ): Promise<SkillCandidate[]> {\n const prompt = this.buildAnalysisPrompt(trajectory, options);\n\n try {\n const response = await this.llmProvider!.completeStructured<{\n candidates: SkillCandidate[];\n }>(prompt, SKILL_CANDIDATE_SCHEMA, { temperature: 0.3 });\n\n return response.candidates || [];\n } catch (error) {\n // Fallback to text completion if structured fails\n try {\n const textResponse = await this.llmProvider!.complete(prompt, {\n temperature: 0.3,\n });\n return this.parseTextResponse(textResponse);\n } catch {\n return [];\n }\n }\n }\n\n /**\n * Build the analysis prompt for skill identification\n */\n private buildAnalysisPrompt(trajectory: Trajectory, options?: ExtractOptions): string {\n const turns = options?.turnRange\n ? trajectory.turns.slice(options.turnRange[0], options.turnRange[1] + 1)\n : trajectory.turns;\n\n const trajectoryText = this.formatTrajectoryForPrompt(turns);\n\n return `Analyze the following agent conversation trajectory and identify any reusable skills that could be extracted.\n\nA skill is extractable if it meets these criteria:\n1. **Reusability**: The solution applies to multiple future tasks, not just this specific case\n2. **Non-trivial**: It involves discovery beyond basic documentation lookup\n3. **Specific triggers**: Has clear conditions for when to apply (error messages, patterns, contexts)\n4. **Verified**: The solution demonstrably worked in this trajectory\n\nFor each skill you identify, provide:\n- name: A descriptive kebab-case name\n- description: 1-2 sentences optimized for semantic search/matching\n- problem: What problem does this skill solve?\n- solution: Step-by-step instructions to apply this skill\n- triggerConditions: Array of {type, value, description} for when to use this skill\n- verification: How to verify the skill worked\n- turnRange: [startTurn, endTurn] indices in the trajectory\n- confidence: 0-1 score for how extractable this skill is\n- reasoning: Why this is or isn't a good skill candidate\n\nIf no skills are extractable, return an empty candidates array.\n\nTRAJECTORY:\n${trajectoryText}\n\n${options?.context ? `ADDITIONAL CONTEXT: ${options.context}` : ''}\n\nRespond with a JSON object containing a \"candidates\" array.`;\n }\n\n /**\n * Format trajectory turns for the prompt\n */\n private formatTrajectoryForPrompt(turns: Trajectory['turns']): string {\n return turns\n .map((turn, i) => {\n let text = `[Turn ${i}] ${turn.role.toUpperCase()}:\\n${turn.content || '(no content)'}`;\n\n if (turn.toolCalls && turn.toolCalls.length > 0) {\n text += '\\nTool calls:';\n for (const call of turn.toolCalls) {\n text += `\\n - ${call.name}: ${JSON.stringify(call.input).substring(0, 200)}`;\n }\n }\n\n if (turn.toolResults && turn.toolResults.length > 0) {\n text += '\\nTool results:';\n for (const result of turn.toolResults) {\n const status = result.success ? 'SUCCESS' : 'ERROR';\n text += `\\n - ${result.name} [${status}]: ${result.output.substring(0, 200)}`;\n }\n }\n\n return text;\n })\n .join('\\n\\n---\\n\\n');\n }\n\n /**\n * Parse text response into skill candidates (fallback)\n */\n private parseTextResponse(response: string): SkillCandidate[] {\n try {\n // Try to extract JSON from the response\n const jsonMatch = response.match(/\\{[\\s\\S]*\"candidates\"[\\s\\S]*\\}/);\n if (jsonMatch) {\n const parsed = JSON.parse(jsonMatch[0]);\n return parsed.candidates || [];\n }\n } catch {\n // Failed to parse\n }\n return [];\n }\n\n /**\n * Build a Skill from a candidate\n */\n private buildSkillFromCandidate(\n candidate: SkillCandidate,\n trajectory: Trajectory\n ): Partial<Skill> {\n const id = candidate.name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n\n // Build example from the relevant turns\n const turns = trajectory.turns.slice(candidate.turnRange[0], candidate.turnRange[1] + 1);\n const example = this.buildExample(turns);\n\n const partialSkill: Partial<Skill> = {\n id,\n name: candidate.name,\n version: '1.0.0',\n description: candidate.description,\n problem: candidate.problem,\n triggerConditions: candidate.triggerConditions,\n solution: candidate.solution,\n verification: candidate.verification,\n examples: example ? [example] : [],\n author: 'auto-extracted',\n tags: this.inferTags(candidate),\n createdAt: new Date(),\n updatedAt: new Date(),\n status: 'draft',\n metrics: this.createInitialMetrics(),\n source: {\n type: 'extracted',\n sessionId: trajectory.sessionId,\n importedAt: new Date(),\n },\n };\n\n // Populate serving metadata for context budgeting and auto-expansion\n partialSkill.serving = this.computeServingMetadata(partialSkill);\n\n return partialSkill;\n }\n\n /**\n * Build an example from turns\n */\n private buildExample(turns: Trajectory['turns']): SkillExample | null {\n const firstUser = turns.find((t) => t.role === 'user');\n const lastAssistant = [...turns].reverse().find((t) => t.role === 'assistant');\n\n if (!firstUser || !lastAssistant) return null;\n\n return {\n scenario: 'Extracted from conversation',\n before: (firstUser.content || '').substring(0, 500),\n after: (lastAssistant.content || '').substring(0, 500),\n };\n }\n\n /**\n * Infer tags from candidate\n */\n private inferTags(candidate: SkillCandidate): string[] {\n const tags: string[] = [];\n const content = `${candidate.problem} ${candidate.solution}`.toLowerCase();\n\n const techPatterns: [RegExp, string][] = [\n [/typescript/i, 'typescript'],\n [/javascript/i, 'javascript'],\n [/python/i, 'python'],\n [/react/i, 'react'],\n [/node/i, 'nodejs'],\n [/docker/i, 'docker'],\n [/git\\b/i, 'git'],\n [/test/i, 'testing'],\n [/error/i, 'debugging'],\n ];\n\n for (const [pattern, tag] of techPatterns) {\n if (pattern.test(content)) {\n tags.push(tag);\n }\n }\n\n return [...new Set(tags)];\n }\n}\n\n/**\n * JSON schema for skill candidates (for structured output)\n */\nconst SKILL_CANDIDATE_SCHEMA = {\n type: 'object',\n properties: {\n candidates: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n description: { type: 'string' },\n problem: { type: 'string' },\n solution: { type: 'string' },\n triggerConditions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n type: { type: 'string', enum: ['error', 'pattern', 'context', 'keyword', 'custom'] },\n value: { type: 'string' },\n description: { type: 'string' },\n },\n required: ['type', 'value'],\n },\n },\n verification: { type: 'string' },\n turnRange: {\n type: 'array',\n items: { type: 'number' },\n minItems: 2,\n maxItems: 2,\n },\n confidence: { type: 'number', minimum: 0, maximum: 1 },\n reasoning: { type: 'string' },\n },\n required: ['name', 'description', 'problem', 'solution', 'turnRange', 'confidence'],\n },\n },\n },\n required: ['candidates'],\n};\n","/**\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.problem,\n skill.solution,\n ...skill.tags,\n skill.triggerConditions.map((t) => t.value).join(' '),\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 problem: skill.problem,\n solution: skill.solution,\n triggerConditions: skill.triggerConditions,\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 * 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 const body = this.buildBody(skill);\n return `---\\n${frontmatter}---\\n\\n${body}`;\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 return lines.join('\\n') + '\\n';\n }\n\n /**\n * Build Markdown body (Claudeception-inspired structure)\n */\n private buildBody(skill: Skill): string {\n const sections: string[] = [];\n\n // Problem section\n sections.push('## Problem\\n');\n sections.push(skill.problem);\n sections.push('');\n\n // Trigger Conditions section\n if (skill.triggerConditions.length > 0) {\n sections.push('## Trigger Conditions\\n');\n for (const trigger of skill.triggerConditions) {\n const desc = trigger.description ? ` - ${trigger.description}` : '';\n sections.push(`- **${trigger.type}**: \\`${trigger.value}\\`${desc}`);\n }\n sections.push('');\n }\n\n // Solution section\n sections.push('## Solution\\n');\n sections.push(skill.solution);\n sections.push('');\n\n // Verification section\n sections.push('## Verification\\n');\n sections.push(skill.verification);\n sections.push('');\n\n // Examples section\n if (skill.examples.length > 0) {\n sections.push('## Examples\\n');\n for (const example of skill.examples) {\n sections.push(`### ${example.scenario}\\n`);\n sections.push('**Before:**');\n sections.push('```');\n sections.push(example.before);\n sections.push('```\\n');\n sections.push('**After:**');\n sections.push('```');\n sections.push(example.after);\n sections.push('```');\n sections.push('');\n }\n }\n\n // Notes section\n if (skill.notes) {\n sections.push('## Notes\\n');\n sections.push(skill.notes);\n sections.push('');\n }\n\n return sections.join('\\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 const sections = this.parseBodySections(body);\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\n // Parse body sections\n const problem = sections['problem'] || '';\n const solution = sections['solution'] || '';\n const verification = sections['verification'] || '';\n const notes = sections['notes'];\n const triggerConditions = this.parseTriggerConditions(sections['trigger conditions'] || '');\n const examples = this.parseExamples(sections['examples'] || '');\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 problem,\n triggerConditions,\n solution,\n verification,\n examples,\n notes,\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 * Parse body into sections by ## headers\n */\n private parseBodySections(body: string): Record<string, string> {\n const sections: Record<string, string> = {};\n const parts = body.split(/^## /m);\n\n for (const part of parts) {\n if (!part.trim()) continue;\n\n const lines = part.split('\\n');\n const header = lines[0]?.trim().toLowerCase();\n const content = lines.slice(1).join('\\n').trim();\n\n if (header) {\n sections[header] = content;\n }\n }\n\n return sections;\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 * Parse trigger conditions from markdown\n */\n private parseTriggerConditions(content: string): Skill['triggerConditions'] {\n const conditions: Skill['triggerConditions'] = [];\n const lines = content.split('\\n');\n\n for (const line of lines) {\n // Match: - **type**: `value` - description\n const match = line.match(/^-\\s+\\*\\*(\\w+)\\*\\*:\\s*`([^`]+)`(?:\\s*-\\s*(.+))?/);\n if (match) {\n conditions.push({\n type: match[1] as Skill['triggerConditions'][0]['type'],\n value: match[2],\n description: match[3]?.trim(),\n });\n }\n }\n\n return conditions;\n }\n\n /**\n * Parse examples from markdown\n */\n private parseExamples(content: string): Skill['examples'] {\n const examples: Skill['examples'] = [];\n const parts = content.split(/^### /m);\n\n for (const part of parts) {\n if (!part.trim()) continue;\n\n const lines = part.split('\\n');\n const scenario = lines[0]?.trim() || 'Example';\n const rest = lines.slice(1).join('\\n');\n\n const beforeMatch = rest.match(/\\*\\*Before:\\*\\*\\n```\\n?([\\s\\S]*?)```/);\n const afterMatch = rest.match(/\\*\\*After:\\*\\*\\n```\\n?([\\s\\S]*?)```/);\n\n if (beforeMatch || afterMatch) {\n examples.push({\n scenario,\n before: beforeMatch?.[1]?.trim() || '',\n after: afterMatch?.[1]?.trim() || '',\n });\n }\n }\n\n return examples;\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 problem: skill.problem,\n solution: skill.solution,\n triggerConditions: skill.triggerConditions,\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 * 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 = 2;\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 problem TEXT NOT NULL,\n trigger_conditions TEXT NOT NULL,\n solution TEXT NOT NULL,\n verification TEXT NOT NULL,\n examples TEXT NOT NULL,\n notes 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 problem,\n solution,\n tags,\n trigger_values\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 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, problem, trigger_conditions, solution,\n verification, examples, notes, author, tags, created_at, updated_at,\n status, parent_version, derived_from, metrics, 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.problem,\n JSON.stringify(skill.triggerConditions),\n skill.solution,\n skill.verification,\n JSON.stringify(skill.examples),\n skill.notes || 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 triggerValues = skill.triggerConditions.map(t => t.value).join(' ');\n const tags = skill.tags.join(' ');\n\n db.prepare(`\n INSERT INTO skills_fts (skill_id, name, description, problem, solution, tags, trigger_values)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `).run(skill.id, skill.name, skill.description, skill.problem, skill.solution, tags, triggerValues);\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 problem: row.problem,\n triggerConditions: JSON.parse(row.trigger_conditions),\n solution: row.solution,\n verification: row.verification,\n examples: JSON.parse(row.examples),\n notes: row.notes || 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 problem: skill.problem,\n solution: skill.solution,\n triggerConditions: skill.triggerConditions,\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 problem: string;\n trigger_conditions: string;\n solution: string;\n verification: string;\n examples: string;\n notes: 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 * 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 'solution',\n 'triggerConditions',\n 'examples',\n 'notes',\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 === 'triggerConditions') {\n updates.triggerConditions = this.mergeTriggerConditions(\n targetSkill.triggerConditions,\n sourceSkill.triggerConditions\n );\n } else if (field === 'examples') {\n updates.examples = this.mergeExamples(\n targetSkill.examples,\n sourceSkill.examples\n );\n } else if (field === 'tags') {\n updates.tags = [...new Set([...targetSkill.tags, ...sourceSkill.tags])];\n } else if (field === 'solution' || field === 'notes') {\n updates[field] = this.mergeText(\n targetSkill[field] || '',\n sourceSkill[field] || '',\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 existing notes for auditability\n const rollbackNote = `[rollback] ${currentSkill.version} → ${toVersion} (${rollbackReason})`;\n const notes = targetSkill.notes\n ? `${targetSkill.notes}\\n${rollbackNote}`\n : rollbackNote;\n\n const rolledBackSkill: Skill = {\n ...targetSkill,\n version: newVersion,\n parentVersion: currentSkill.version,\n notes,\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 mergeTriggerConditions(\n target: Skill['triggerConditions'],\n source: Skill['triggerConditions']\n ): Skill['triggerConditions'] {\n const seen = new Set(target.map((t) => `${t.type}:${t.value}`));\n const merged = [...target];\n\n for (const trigger of source) {\n const key = `${trigger.type}:${trigger.value}`;\n if (!seen.has(key)) {\n merged.push(trigger);\n seen.add(key);\n }\n }\n\n return merged;\n }\n\n private mergeExamples(\n target: Skill['examples'],\n source: Skill['examples']\n ): Skill['examples'] {\n const seen = new Set(target.map((e) => e.scenario));\n const merged = [...target];\n\n for (const example of source) {\n if (!seen.has(example.scenario)) {\n merged.push(example);\n seen.add(example.scenario);\n }\n }\n\n return merged;\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 'problem',\n 'solution',\n 'verification',\n 'notes',\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 trigger conditions\n const triggersA = new Set(skillA.triggerConditions.map((t) => `${t.type}:${t.value}`));\n const triggersB = new Set(skillB.triggerConditions.map((t) => `${t.type}:${t.value}`));\n\n for (const trigger of triggersB) {\n if (!triggersA.has(trigger)) {\n changes.added.push({ type: 'triggerCondition', value: trigger });\n }\n }\n for (const trigger of triggersA) {\n if (!triggersB.has(trigger)) {\n changes.removed.push({ type: 'triggerCondition', value: trigger });\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 * 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 * Activation Manager for auto-triggering skill extraction\n */\n\nimport { randomUUID } from 'crypto';\nimport type { Trajectory, Turn } from '../types.js';\nimport type {\n ActivationConfig,\n ActivationState,\n ActivationTrigger,\n SessionHookContext,\n SessionConfig,\n} from './types.js';\nimport { DEFAULT_ACTIVATION_CONFIG } from './types.js';\nimport { HookRegistry } from './registry.js';\n\n/**\n * Result of an activation check\n */\nexport interface ActivationCheckResult {\n /** Whether to activate extraction */\n shouldActivate: boolean;\n /** Trigger type that caused activation */\n trigger?: ActivationTrigger;\n /** Reason for the decision */\n reason: string;\n /** Confidence score (0-1) */\n confidence: number;\n /** Matched patterns (if pattern-match trigger) */\n matchedPatterns?: string[];\n}\n\n/**\n * Callback for when extraction is activated\n */\nexport type ActivationCallback = (\n trajectory: Trajectory,\n trigger: ActivationTrigger\n) => Promise<void>;\n\n/**\n * Manages activation triggers for automatic skill extraction\n */\nexport class ActivationManager {\n private config: ActivationConfig;\n private state: ActivationState;\n private callbacks: ActivationCallback[] = [];\n private hookRegistry: HookRegistry;\n\n constructor(\n config: Partial<ActivationConfig> = {},\n hookRegistry?: HookRegistry\n ) {\n this.config = { ...DEFAULT_ACTIVATION_CONFIG, ...config };\n this.state = {\n sessionActivations: 0,\n pendingExtractions: [],\n };\n this.hookRegistry = hookRegistry || new HookRegistry();\n this.setupHooks();\n }\n\n /**\n * Update configuration\n */\n setConfig(config: Partial<ActivationConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Get current configuration\n */\n getConfig(): ActivationConfig {\n return { ...this.config };\n }\n\n /**\n * Register an activation callback\n */\n onActivate(callback: ActivationCallback): () => void {\n this.callbacks.push(callback);\n return () => {\n const index = this.callbacks.indexOf(callback);\n if (index !== -1) {\n this.callbacks.splice(index, 1);\n }\n };\n }\n\n /**\n * Start a new session\n * @param config Session configuration with agent ID, or just a session ID for backward compatibility\n */\n startSession(config?: string | SessionConfig): string {\n // Handle backward compatibility - string is just sessionId\n const sessionConfig: SessionConfig =\n typeof config === 'string'\n ? { sessionId: config, agentId: 'unknown' }\n : config ?? { agentId: 'unknown' };\n\n const id = sessionConfig.sessionId || randomUUID();\n this.state.currentSessionId = id;\n this.state.currentAgentId = sessionConfig.agentId;\n this.state.agentMetadata = {\n ...sessionConfig.agentMetadata,\n agentName: sessionConfig.agentName,\n };\n this.state.sessionActivations = 0;\n this.state.pendingExtractions = [];\n\n this.hookRegistry.execute('session:start', {\n event: 'session:start',\n sessionId: id,\n metadata: {\n agentId: sessionConfig.agentId,\n agentName: sessionConfig.agentName,\n ...sessionConfig.agentMetadata,\n },\n } as Omit<SessionHookContext, 'invocationId' | 'timestamp'>);\n\n return id;\n }\n\n /**\n * Get current agent ID\n */\n getCurrentAgentId(): string | undefined {\n return this.state.currentAgentId;\n }\n\n /**\n * Get current agent metadata\n */\n getAgentMetadata(): Record<string, unknown> | undefined {\n return this.state.agentMetadata;\n }\n\n /**\n * End the current session\n */\n async endSession(trajectory?: Trajectory): Promise<ActivationCheckResult> {\n const sessionId = this.state.currentSessionId;\n if (!sessionId) {\n return {\n shouldActivate: false,\n reason: 'No active session',\n confidence: 0,\n };\n }\n\n // Trigger session:end hook\n await this.hookRegistry.execute('session:end', {\n event: 'session:end',\n sessionId,\n trajectory,\n } as SessionHookContext);\n\n // Check for auto-extraction\n let result: ActivationCheckResult = {\n shouldActivate: false,\n reason: 'Auto-extraction disabled',\n confidence: 0,\n };\n\n if (this.config.autoExtractOnSessionEnd && trajectory) {\n result = this.checkActivation(trajectory, 'session-end');\n\n if (result.shouldActivate) {\n await this.activate(trajectory, 'session-end');\n }\n }\n\n // Clear session state\n this.state.currentSessionId = undefined;\n\n return result;\n }\n\n /**\n * Process a message in the current session\n */\n async processMessage(\n role: 'user' | 'assistant',\n content: string,\n trajectory?: Trajectory\n ): Promise<ActivationCheckResult> {\n // Trigger message hook\n await this.hookRegistry.execute('session:message', {\n event: 'session:message',\n sessionId: this.state.currentSessionId || 'unknown',\n message: { role, content },\n } as SessionHookContext);\n\n // Check for pattern-based activation\n if (role === 'assistant' && trajectory) {\n const result = this.checkPatternMatch(content, trajectory);\n if (result.shouldActivate) {\n await this.activate(trajectory, 'pattern-match');\n return result;\n }\n }\n\n return {\n shouldActivate: false,\n reason: 'No activation trigger detected',\n confidence: 0,\n };\n }\n\n /**\n * Manually trigger extraction\n */\n async manualActivate(trajectory: Trajectory): Promise<void> {\n await this.activate(trajectory, 'manual');\n }\n\n /**\n * Check if extraction should be activated\n */\n checkActivation(\n trajectory: Trajectory,\n trigger: ActivationTrigger\n ): ActivationCheckResult {\n // Check cooldown\n if (this.state.lastActivation) {\n const elapsed = Date.now() - this.state.lastActivation.getTime();\n if (elapsed < this.config.activationCooldown) {\n return {\n shouldActivate: false,\n reason: `Cooldown active (${Math.ceil((this.config.activationCooldown - elapsed) / 1000)}s remaining)`,\n confidence: 0,\n };\n }\n }\n\n // Check session limit\n if (this.state.sessionActivations >= this.config.maxExtractionsPerSession) {\n return {\n shouldActivate: false,\n reason: `Session limit reached (${this.config.maxExtractionsPerSession} extractions)`,\n confidence: 0,\n };\n }\n\n // Check minimum session length\n if (trajectory.turns.length < this.config.minSessionLength) {\n return {\n shouldActivate: false,\n reason: `Session too short (${trajectory.turns.length} < ${this.config.minSessionLength} turns)`,\n confidence: 0,\n };\n }\n\n // Calculate confidence based on trajectory quality\n const confidence = this.calculateConfidence(trajectory);\n if (confidence < this.config.minConfidence) {\n return {\n shouldActivate: false,\n reason: `Confidence too low (${(confidence * 100).toFixed(1)}% < ${(this.config.minConfidence * 100).toFixed(1)}%)`,\n confidence,\n };\n }\n\n return {\n shouldActivate: true,\n trigger,\n reason: 'Activation criteria met',\n confidence,\n };\n }\n\n /**\n * Check for pattern matches in content\n */\n private checkPatternMatch(\n content: string,\n trajectory: Trajectory\n ): ActivationCheckResult {\n const lowerContent = content.toLowerCase();\n const matchedPatterns = this.config.triggerPatterns.filter((pattern) =>\n lowerContent.includes(pattern.toLowerCase())\n );\n\n if (matchedPatterns.length === 0) {\n return {\n shouldActivate: false,\n reason: 'No trigger patterns matched',\n confidence: 0,\n };\n }\n\n // Still need to pass other checks\n const baseCheck = this.checkActivation(trajectory, 'pattern-match');\n if (!baseCheck.shouldActivate) {\n return baseCheck;\n }\n\n return {\n shouldActivate: true,\n trigger: 'pattern-match',\n reason: `Matched patterns: ${matchedPatterns.join(', ')}`,\n confidence: baseCheck.confidence,\n matchedPatterns,\n };\n }\n\n /**\n * Calculate confidence score for a trajectory\n */\n private calculateConfidence(trajectory: Trajectory): number {\n let score = 0;\n const maxScore = 5;\n\n // Has problem-solution structure\n const hasUserTurn = trajectory.turns.some((t) => t.role === 'user');\n const hasAssistantTurn = trajectory.turns.some((t) => t.role === 'assistant');\n if (hasUserTurn && hasAssistantTurn) score += 1;\n\n // Has tool usage (indicates actual work done)\n const hasToolCalls = trajectory.turns.some((t) => t.toolCalls && t.toolCalls.length > 0);\n if (hasToolCalls) score += 1;\n\n // Has successful tool results\n const hasSuccessfulResults = trajectory.turns.some(\n (t) => t.toolResults && t.toolResults.some((r) => r.success)\n );\n if (hasSuccessfulResults) score += 1;\n\n // Has outcome with success\n if (trajectory.outcome?.success) score += 1;\n\n // Has file modifications (indicates tangible changes)\n if (trajectory.outcome?.filesModified && trajectory.outcome.filesModified.length > 0) {\n score += 1;\n }\n\n return score / maxScore;\n }\n\n /**\n * Perform the activation\n */\n private async activate(\n trajectory: Trajectory,\n trigger: ActivationTrigger\n ): Promise<void> {\n // Update state\n this.state.lastActivation = new Date();\n this.state.sessionActivations++;\n\n // Call all registered callbacks\n for (const callback of this.callbacks) {\n try {\n await callback(trajectory, trigger);\n } catch (error) {\n console.error('Activation callback error:', error);\n }\n }\n }\n\n /**\n * Setup internal hooks\n */\n private setupHooks(): void {\n // Could register default hooks here for logging, etc.\n }\n\n /**\n * Get current state\n */\n getState(): ActivationState {\n return { ...this.state };\n }\n\n /**\n * Reset state\n */\n reset(): void {\n this.state = {\n sessionActivations: 0,\n pendingExtractions: [],\n };\n }\n}\n\n/**\n * Create an activation manager with configuration\n */\nexport function createActivationManager(\n config?: Partial<ActivationConfig>,\n hookRegistry?: HookRegistry\n): ActivationManager {\n return new ActivationManager(config, hookRegistry);\n}\n","/**\n * Types for the hooks and activation system\n */\n\nimport type { Skill, Trajectory, ExtractionResult, QualityGateResult } from '../types.js';\n\n// =============================================================================\n// Hook Event Types\n// =============================================================================\n\n/**\n * Events that can trigger hooks\n */\nexport type HookEvent =\n // Extraction lifecycle\n | 'extraction:before'\n | 'extraction:after'\n | 'extraction:error'\n // Quality gate events\n | 'quality:before'\n | 'quality:after'\n | 'quality:failed'\n // Storage lifecycle\n | 'storage:before-save'\n | 'storage:after-save'\n | 'storage:before-delete'\n | 'storage:after-delete'\n // Session lifecycle\n | 'session:start'\n | 'session:end'\n | 'session:message'\n // Skill runtime lifecycle (usage/matching)\n | 'skill:activated'\n | 'skill:matched'\n | 'skill:applied'\n | 'skill:feedback'\n // Skill CRUD lifecycle (creation/modification)\n | 'skill:created'\n | 'skill:updated'\n | 'skill:deprecated'\n | 'skill:deleted'\n // Validation lifecycle\n | 'validation:before'\n | 'validation:after'\n | 'validation:failed'\n // Composition lifecycle\n | 'composition:suggested'\n | 'composition:approved'\n | 'composition:created';\n\n/**\n * Priority levels for hook execution\n */\nexport type HookPriority = 'high' | 'normal' | 'low';\n\n// =============================================================================\n// Hook Context Types\n// =============================================================================\n\n/**\n * Base context shared by all hooks\n */\nexport interface BaseHookContext {\n /** Unique ID for this hook invocation */\n invocationId: string;\n /** Timestamp when the hook was triggered */\n timestamp: Date;\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Context for extraction hooks\n */\nexport interface ExtractionHookContext extends BaseHookContext {\n event: 'extraction:before' | 'extraction:after' | 'extraction:error';\n trajectory: Trajectory;\n /** Available after extraction:after */\n result?: ExtractionResult;\n /** Available when extraction:error */\n error?: Error;\n}\n\n/**\n * Context for quality gate hooks\n */\nexport interface QualityHookContext extends BaseHookContext {\n event: 'quality:before' | 'quality:after' | 'quality:failed';\n skill: Skill;\n /** Available after quality:after or quality:failed */\n results?: QualityGateResult[];\n /** Whether all gates passed (after quality:after) */\n passed?: boolean;\n}\n\n/**\n * Context for storage hooks\n */\nexport interface StorageHookContext extends BaseHookContext {\n event: 'storage:before-save' | 'storage:after-save' | 'storage:before-delete' | 'storage:after-delete';\n skill: Skill;\n /** Operation type */\n operation: 'save' | 'delete';\n /** Whether the operation was successful */\n success?: boolean;\n}\n\n/**\n * Context for session hooks\n */\nexport interface SessionHookContext extends BaseHookContext {\n event: 'session:start' | 'session:end' | 'session:message';\n sessionId: string;\n /** Available on session:end */\n trajectory?: Trajectory;\n /** Message content (on session:message) */\n message?: {\n role: 'user' | 'assistant';\n content: string;\n };\n}\n\n/**\n * Context for skill runtime hooks (activation/matching/usage)\n */\nexport interface SkillRuntimeHookContext extends BaseHookContext {\n event: 'skill:activated' | 'skill:matched' | 'skill:applied' | 'skill:feedback';\n skill: Skill;\n /** Match score (on skill:matched) */\n matchScore?: number;\n /** Application result (on skill:applied) */\n applicationResult?: {\n success: boolean;\n output?: string;\n };\n /** Feedback data (on skill:feedback) */\n feedback?: {\n type: 'positive' | 'negative' | 'neutral';\n comment?: string;\n };\n}\n\n/**\n * Context for skill CRUD hooks (create/update/deprecate/delete)\n */\nexport interface SkillCrudHookContext extends BaseHookContext {\n event: 'skill:created' | 'skill:updated' | 'skill:deprecated' | 'skill:deleted';\n skill: Skill;\n /** Previous version (on skill:updated) */\n previousVersion?: string;\n /** Deprecation reason (on skill:deprecated) */\n deprecationReason?: string;\n}\n\n/**\n * Context for validation hooks\n */\nexport interface ValidationHookContext extends BaseHookContext {\n event: 'validation:before' | 'validation:after' | 'validation:failed';\n skill: Skill;\n /** Validation result (on validation:after or validation:failed) */\n result?: {\n passed: boolean;\n testsPassed: number;\n testsFailed: number;\n errors: string[];\n };\n}\n\n/**\n * Composition suggestion\n */\nexport interface CompositionSuggestion {\n skillIds: string[];\n mode: 'sequential' | 'conditional' | 'parallel';\n reason: string;\n confidence: number;\n}\n\n/**\n * Context for composition hooks\n */\nexport interface CompositionHookContext extends BaseHookContext {\n event: 'composition:suggested' | 'composition:approved' | 'composition:created';\n /** The skill that triggered the suggestion (on composition:suggested) */\n triggerSkill?: Skill;\n /** Suggested compositions (on composition:suggested) */\n suggestions?: CompositionSuggestion[];\n /** The approved suggestion (on composition:approved) */\n approvedSuggestion?: CompositionSuggestion;\n /** The created compound skill (on composition:created) */\n compoundSkill?: Skill;\n}\n\n/**\n * Union of all hook contexts\n */\nexport type HookContext =\n | ExtractionHookContext\n | QualityHookContext\n | StorageHookContext\n | SessionHookContext\n | SkillRuntimeHookContext\n | SkillCrudHookContext\n | ValidationHookContext\n | CompositionHookContext;\n\n/**\n * Legacy alias for backward compatibility\n * @deprecated Use SkillRuntimeHookContext instead\n */\nexport type SkillHookContext = SkillRuntimeHookContext;\n\n// =============================================================================\n// Hook Handler Types\n// =============================================================================\n\n/**\n * Result from a hook handler\n */\nexport interface HookResult {\n /** Whether to continue processing (false to abort) */\n continue: boolean;\n /** Modified data (for before hooks that can transform data) */\n modified?: unknown;\n /** Message explaining the result */\n message?: string;\n /** Error if the hook failed */\n error?: Error;\n}\n\n/**\n * Hook handler function\n */\nexport type HookHandler<T extends HookContext = HookContext> = (\n context: T\n) => Promise<HookResult> | HookResult;\n\n/**\n * Registered hook definition\n */\nexport interface RegisteredHook {\n /** Unique hook ID */\n id: string;\n /** Hook name for display */\n name: string;\n /** Events this hook listens to */\n events: HookEvent[];\n /** Handler function */\n handler: HookHandler;\n /** Execution priority */\n priority: HookPriority;\n /** Whether the hook is enabled */\n enabled: boolean;\n /** Optional filter to control when hook runs */\n filter?: (context: HookContext) => boolean;\n}\n\n// =============================================================================\n// Activation Types\n// =============================================================================\n\n/**\n * Activation trigger types\n */\nexport type ActivationTrigger =\n | 'manual' // User explicitly triggered\n | 'session-end' // Triggered when session ends\n | 'threshold' // Triggered when certain thresholds are met\n | 'scheduled' // Triggered on a schedule\n | 'pattern-match'; // Triggered when patterns are detected\n\n/**\n * Configuration for auto-activation\n */\nexport interface ActivationConfig {\n /** Enable auto-extraction on session end */\n autoExtractOnSessionEnd: boolean;\n /** Minimum session length (turns) before auto-extract */\n minSessionLength: number;\n /** Minimum confidence threshold for auto-extraction */\n minConfidence: number;\n /** Patterns that trigger extraction */\n triggerPatterns: string[];\n /** Cooldown between activations (ms) */\n activationCooldown: number;\n /** Maximum extractions per session */\n maxExtractionsPerSession: number;\n}\n\n/**\n * Default activation configuration\n */\nexport const DEFAULT_ACTIVATION_CONFIG: ActivationConfig = {\n autoExtractOnSessionEnd: false,\n minSessionLength: 3,\n minConfidence: 0.7,\n triggerPatterns: [\n 'fixed the issue',\n 'solved the problem',\n 'that worked',\n 'successfully',\n ],\n activationCooldown: 60000, // 1 minute\n maxExtractionsPerSession: 5,\n};\n\n/**\n * Activation state tracking\n */\nexport interface ActivationState {\n /** Last activation timestamp */\n lastActivation?: Date;\n /** Number of activations this session */\n sessionActivations: number;\n /** Current session ID */\n currentSessionId?: string;\n /** Current agent ID */\n currentAgentId?: string;\n /** Agent metadata */\n agentMetadata?: Record<string, unknown>;\n /** Pending extractions */\n pendingExtractions: Trajectory[];\n}\n\n/**\n * Configuration for starting a session\n */\nexport interface SessionConfig {\n /** Optional session ID (auto-generated if not provided) */\n sessionId?: string;\n /** Agent ID that owns this session */\n agentId: string;\n /** Human-readable agent name */\n agentName?: string;\n /** Additional agent metadata */\n agentMetadata?: Record<string, unknown>;\n}\n","/**\n * SkillBank - Main orchestrator for skill-tree library\n *\n * Provides a unified interface for:\n * - Loading and parsing agent sessions\n * - Extracting skills (manual or automatic)\n * - Storing and retrieving skills\n * - Version management and lineage tracking\n */\n\nimport type {\n Skill,\n Trajectory,\n ExtractionResult,\n SkillFilter,\n SkillVersion,\n SkillLineage,\n StorageAdapter,\n SessionAdapter,\n LLMProvider,\n SkillTreeEvent,\n SkillTreeEventHandler,\n ManualExtractionRequest,\n SkillScope,\n SkillVisibility,\n SkillNamespace,\n SkillValidationSummary,\n} from './types.js';\nimport { hasTaxonomySupport, hasSyncSupport } from './types.js';\nimport { SkillValidator } from './validation/validator.js';\nimport type { ValidatorConfig, SkillValidationResult } from './validation/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 { SkillComposer, type ComposerConfig, type CompositionSuggestion } from './composer/index.js';\nimport type { CompositionHookContext } from './hooks/types.js';\nimport {\n FederationManager,\n type FederatedRemoteConfig,\n type RemoteState,\n type ImportOptions,\n type ImportResult,\n type ShareOptions,\n type ShareResult,\n type UpstreamUpdate,\n type PullUpstreamOptions,\n type PullUpstreamResult,\n} from './federation/index.js';\nimport { AdapterRegistry, adapterRegistry, claudeCodeAdapter } from './adapters/index.js';\nimport { ManualExtractor, AutomaticExtractor, type ExtractOptions } from './extraction/index.js';\nimport { MemoryStorageAdapter, FilesystemStorageAdapter } from './storage/index.js';\nimport { LineageTracker, type NewVersionOptions, type ForkOptions, type RollbackOptions } from './versioning/index.js';\nimport {\n SemanticMatcher,\n type MatcherConfig,\n type MatchResult,\n type MatchContext,\n type EmbeddingProvider,\n} from './matching/index.js';\nimport { HookRegistry } from './hooks/registry.js';\nimport { ActivationManager } from './hooks/activation.js';\nimport type {\n HookEvent,\n HookContext,\n SkillCrudHookContext,\n ExtractionHookContext,\n SessionConfig,\n ActivationConfig,\n} from './hooks/types.js';\n\n/**\n * Configuration for SkillBank\n */\nexport interface SkillBankConfig {\n /** Storage configuration */\n storage?:\n | { type: 'memory' }\n | { type: 'filesystem'; basePath: string; openSkillsCompatible?: boolean };\n /** LLM provider for automatic extraction */\n llmProvider?: LLMProvider;\n /** Custom session adapters to register */\n adapters?: SessionAdapter[];\n /** Minimum confidence for automatic extraction */\n minExtractionConfidence?: number;\n /** Semantic matching configuration */\n matching?: {\n /** Embedding provider for semantic search */\n embeddingProvider?: EmbeddingProvider;\n /** Minimum similarity threshold (0-1) */\n similarityThreshold?: number;\n /** Auto-index skills on initialize */\n autoIndex?: boolean;\n };\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 /** Activation configuration for auto-extraction triggers */\n activation?: Partial<ActivationConfig>;\n /** Validation configuration */\n validation?: {\n /** Enable validation on skill creation */\n enabled?: boolean;\n /** Validation mode: advisory (default, non-blocking) or blocking (fails extraction if validation fails) */\n mode?: 'advisory' | 'blocking';\n /** Validator configuration */\n config?: ValidatorConfig;\n };\n /** Composition configuration */\n composition?: {\n /** Enable composition suggestions on skill creation */\n enabled?: boolean;\n /** Composer configuration */\n config?: ComposerConfig;\n };\n}\n\n/**\n * Unified query input for findSkills().\n * Accepts either a plain string or a structured MatchContext.\n */\nexport type SkillQuery = string | MatchContext;\n\n/**\n * Main SkillBank class\n */\nexport class SkillBank {\n private storage: StorageAdapter;\n private adapterRegistry: AdapterRegistry;\n private manualExtractor: ManualExtractor;\n private automaticExtractor: AutomaticExtractor;\n private lineageTracker: LineageTracker;\n private semanticMatcher: SemanticMatcher;\n private eventHandlers: SkillTreeEventHandler[] = [];\n private initialized = false;\n private autoIndexOnInit = 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 /** Activation manager for session tracking and auto-extraction */\n private activationManager: ActivationManager;\n\n /** Skill validator for validation integration */\n private validator?: SkillValidator;\n\n /** Validation mode: advisory (non-blocking) or blocking */\n private validationMode: 'advisory' | 'blocking' = 'advisory';\n\n /** Whether validation is enabled */\n private validationEnabled = false;\n\n /** Skill composer for composition suggestions */\n private composer?: SkillComposer;\n\n /** Whether composition suggestions are enabled */\n private compositionEnabled = false;\n\n /** Pending composition suggestions */\n private compositionSuggestions = new Map<string, CompositionSuggestion[]>();\n\n constructor(config: SkillBankConfig = {}) {\n // Initialize hook registry (use provided or create new)\n this.hookRegistry = config.hookRegistry ?? new HookRegistry();\n\n // Initialize activation manager with shared hook registry\n this.activationManager = new ActivationManager(config.activation, this.hookRegistry);\n // Initialize storage\n if (config.storage?.type === 'filesystem') {\n this.basePath = config.storage.basePath;\n this.storage = new FilesystemStorageAdapter({\n basePath: config.storage.basePath,\n openSkillsCompatible: config.storage.openSkillsCompatible ?? true,\n });\n } else {\n this.storage = new MemoryStorageAdapter();\n }\n\n // Initialize adapter registry with default adapters\n this.adapterRegistry = new AdapterRegistry();\n this.adapterRegistry.register(claudeCodeAdapter);\n\n // Register custom adapters\n if (config.adapters) {\n for (const adapter of config.adapters) {\n this.adapterRegistry.register(adapter);\n }\n }\n\n // Initialize extractors\n this.manualExtractor = new ManualExtractor();\n this.automaticExtractor = new AutomaticExtractor({\n llmProvider: config.llmProvider,\n minConfidence: config.minExtractionConfidence,\n });\n\n // Initialize lineage tracker\n this.lineageTracker = new LineageTracker(this.storage);\n\n // Initialize semantic matcher\n this.semanticMatcher = new SemanticMatcher({\n embeddingProvider: config.matching?.embeddingProvider,\n similarityThreshold: config.matching?.similarityThreshold,\n });\n this.autoIndexOnInit = config.matching?.autoIndex ?? false;\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 validation if enabled\n if (config.validation?.enabled) {\n this.validationEnabled = true;\n this.validationMode = config.validation.mode ?? 'advisory';\n this.validator = new SkillValidator(config.validation.config);\n }\n\n // Initialize composition if enabled\n if (config.composition?.enabled) {\n this.compositionEnabled = true;\n this.composer = new SkillComposer({\n ...config.composition.config,\n storage: undefined, // Will be set after storage is initialized\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 // Set storage on validator if enabled\n if (this.validator) {\n this.validator.setStorage(this.storage);\n }\n\n this.initialized = true;\n\n // Auto-index skills for semantic matching if configured\n if (this.autoIndexOnInit) {\n await this.indexSkills();\n }\n }\n\n /**\n * Shutdown the skill bank cleanly\n */\n async shutdown(): Promise<void> {\n // Nothing to shutdown currently\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 // Session Parsing\n // ==========================================================================\n\n /**\n * Parse a session from raw content\n */\n async parseSession(content: string | Buffer, adapterName?: string): Promise<Trajectory> {\n let adapter: SessionAdapter | undefined;\n\n if (adapterName) {\n adapter = this.adapterRegistry.get(adapterName);\n if (!adapter) {\n throw new Error(`Adapter not found: ${adapterName}`);\n }\n } else {\n adapter = this.adapterRegistry.findAdapter(content);\n if (!adapter) {\n throw new Error('No suitable adapter found for this content');\n }\n }\n\n return adapter.parse(content);\n }\n\n /**\n * Parse multiple sessions\n */\n async parseSessions(\n input: string,\n adapterName?: string\n ): Promise<Trajectory[]> {\n let adapter: SessionAdapter | undefined;\n\n if (adapterName) {\n adapter = this.adapterRegistry.get(adapterName);\n } else {\n adapter = this.adapterRegistry.findAdapter(input);\n }\n\n if (!adapter) {\n throw new Error('No suitable adapter found');\n }\n\n return adapter.parseMany(input);\n }\n\n /**\n * Register a custom session adapter\n */\n registerAdapter(adapter: SessionAdapter): void {\n this.adapterRegistry.register(adapter);\n }\n\n // ==========================================================================\n // Skill Extraction\n // ==========================================================================\n\n /**\n * Extract a skill manually from a trajectory\n */\n async extractManual(\n trajectory: Trajectory,\n request?: ManualExtractionRequest & ExtractOptions\n ): Promise<ExtractionResult> {\n this.ensureInitialized();\n\n this.emit({ type: 'extraction:started', sessionId: trajectory.sessionId });\n\n const results = await this.manualExtractor.extract(trajectory, {\n turnRange: request?.turnRange,\n suggestedName: request?.suggestedName,\n skipValidation: request?.skipValidation,\n });\n\n const result = results[0];\n if (!result) {\n const failedResult: ExtractionResult = {\n success: false,\n confidence: 0,\n gateResults: [],\n failureReason: 'No extraction result',\n sourceTrajectory: {\n sessionId: trajectory.sessionId,\n turnRange: request?.turnRange || [0, trajectory.turns.length - 1],\n },\n };\n this.emit({ type: 'extraction:failed', error: 'No extraction result' });\n return failedResult;\n }\n\n if (result.success && result.skill) {\n // Check for semantic duplicates before saving\n const duplicate = await this.findSemanticDuplicate(result.skill);\n if (duplicate) {\n result.success = false;\n result.failureReason = `Duplicate of existing skill: ${duplicate.skill.id} (similarity: ${duplicate.similarity.toFixed(2)})`;\n } else {\n // Save the extracted skill\n await this.storage.saveSkill(result.skill);\n this.emit({ type: 'skill:created', skill: result.skill });\n }\n }\n\n this.emit({ type: 'extraction:completed', result });\n return result;\n }\n\n /**\n * Extract skills automatically from a trajectory\n */\n async extractAutomatic(\n trajectory: Trajectory,\n options?: ExtractOptions\n ): Promise<ExtractionResult[]> {\n this.ensureInitialized();\n\n this.emit({ type: 'extraction:started', sessionId: trajectory.sessionId });\n\n const results = await this.automaticExtractor.extract(trajectory, options);\n\n for (const result of results) {\n if (result.success && result.skill) {\n // Check for semantic duplicates before saving\n const duplicate = await this.findSemanticDuplicate(result.skill);\n if (duplicate) {\n result.success = false;\n result.failureReason = `Duplicate of existing skill: ${duplicate.skill.id} (similarity: ${duplicate.similarity.toFixed(2)})`;\n } else {\n await this.storage.saveSkill(result.skill);\n this.emit({ type: 'skill:created', skill: result.skill });\n }\n }\n this.emit({ type: 'extraction:completed', result });\n }\n\n return results;\n }\n\n /**\n * Unified extraction entry point.\n *\n * Supports both manual (targeted) and automatic (LLM-driven) extraction\n * from a Trajectory. Use this instead of calling extractManual/extractAutomatic\n * directly.\n *\n * @example\n * ```typescript\n * // Manual extraction with defaults\n * const results = await bank.extract(trajectory);\n *\n * // Automatic extraction\n * const results = await bank.extract(trajectory, { mode: 'automatic' });\n *\n * // Manual with specific turn range\n * const results = await bank.extract(trajectory, {\n * mode: 'manual',\n * turnRange: [0, 5],\n * suggestedName: 'fix-auth-error',\n * });\n * ```\n */\n async extract(\n trajectory: Trajectory,\n options?: {\n mode?: 'manual' | 'automatic';\n } & ExtractOptions & ManualExtractionRequest\n ): Promise<ExtractionResult[]> {\n if (options?.mode === 'automatic') {\n return this.extractAutomatic(trajectory, options);\n }\n const result = await this.extractManual(trajectory, options);\n return [result];\n }\n\n /**\n * Extract from raw session content (convenience method)\n */\n async extractFromSession(\n content: string | Buffer,\n options?: {\n mode?: 'manual' | 'automatic';\n adapterName?: string;\n } & ExtractOptions & ManualExtractionRequest\n ): Promise<ExtractionResult[]> {\n const trajectory = await this.parseSession(content, options?.adapterName);\n return this.extract(trajectory, options);\n }\n\n /**\n * Set LLM provider for automatic extraction\n */\n setLLMProvider(provider: LLMProvider): void {\n this.automaticExtractor.setLLMProvider(provider);\n }\n\n /**\n * Validate a skill and store the result\n * Returns the validation result, or null if validation is not enabled\n */\n async validateSkill(skillId: string): Promise<SkillValidationResult | null> {\n if (!this.validator) {\n return null;\n }\n\n const skill = await this.storage.getSkill(skillId);\n if (!skill) {\n throw new Error(`Skill not found: ${skillId}`);\n }\n\n const result = await this.validator.validateSkill(skill);\n\n // Store validation summary in skill\n await this.storeValidationResult(skill, result);\n\n // Emit validation event\n this.emitValidationEvent(skill, result);\n\n return result;\n }\n\n /**\n * Run validation asynchronously and store result\n * Used for advisory mode validation after skill creation\n */\n private async runValidationAsync(skill: Skill): Promise<void> {\n if (!this.validator) return;\n\n try {\n // Emit validation:before hook\n await this.hookRegistry.execute('validation:before', {\n event: 'validation:before',\n skill,\n } as Omit<HookContext, 'invocationId' | 'timestamp'>);\n\n const result = await this.validator.validateSkill(skill);\n\n // Store validation summary in skill\n await this.storeValidationResult(skill, result);\n\n // Emit appropriate validation event\n this.emitValidationEvent(skill, result);\n } catch (error) {\n console.error('Async validation error:', error);\n }\n }\n\n /**\n * Store validation result in skill metadata\n */\n private async storeValidationResult(skill: Skill, result: SkillValidationResult): Promise<void> {\n const summary: SkillValidationSummary = {\n status: result.status,\n passRate: result.passRate,\n passedCount: result.passedCount,\n failedCount: result.failedCount,\n validatedAt: result.validatedAt,\n recommendedAction: result.recommendation?.action,\n };\n\n skill.lastValidation = summary;\n skill.updatedAt = new Date();\n await this.storage.saveSkill(skill);\n }\n\n /**\n * Emit validation hook event\n */\n private emitValidationEvent(skill: Skill, result: SkillValidationResult): void {\n const event = result.status === 'failed' ? 'validation:failed' : 'validation:after';\n\n this.hookRegistry.execute(event, {\n event,\n skill,\n result: {\n passed: result.status === 'passed',\n testsPassed: result.passedCount,\n testsFailed: result.failedCount,\n errors: result.testResults.filter((t) => !t.passed).map((t) => t.error || 'Test failed'),\n },\n } as Omit<HookContext, 'invocationId' | 'timestamp'>).catch((err) => {\n console.error('Validation hook error:', err);\n });\n }\n\n /**\n * Get the validator instance (for advanced usage)\n */\n getValidator(): SkillValidator | undefined {\n return this.validator;\n }\n\n // ==========================================================================\n // Composition Integration\n // ==========================================================================\n\n /**\n * Get composition suggestions for a skill\n * Suggestions are generated when skills are created (if composition is enabled)\n */\n getCompositionSuggestions(skillId: string): CompositionSuggestion[] {\n return this.compositionSuggestions.get(skillId) || [];\n }\n\n /**\n * Get all pending composition suggestions\n */\n getAllCompositionSuggestions(): Map<string, CompositionSuggestion[]> {\n return new Map(this.compositionSuggestions);\n }\n\n /**\n * Clear composition suggestions for a skill\n */\n clearCompositionSuggestions(skillId: string): void {\n this.compositionSuggestions.delete(skillId);\n }\n\n /**\n * Approve a composition suggestion and create the compound skill\n */\n async approveComposition(\n suggestion: CompositionSuggestion,\n options: {\n name: string;\n description?: string;\n }\n ): Promise<Skill | null> {\n if (!this.composer) {\n throw new Error('Composition is not enabled. Set composition.enabled: true in config.');\n }\n\n // Compose the skills\n const result = await this.composer.compose(suggestion.skillIds, {\n name: options.name,\n description: options.description,\n mode: suggestion.mode,\n });\n\n if (!result.success || !result.skill) {\n console.error('Composition failed:', result.conflicts, result.warnings);\n return null;\n }\n\n // Save the compound skill\n await this.storage.saveSkill(result.skill);\n this.emit({ type: 'skill:created', skill: result.skill });\n\n // Emit composition:created event\n this.hookRegistry.execute('composition:created', {\n event: 'composition:created',\n compoundSkill: result.skill,\n approvedSuggestion: suggestion,\n } as Omit<CompositionHookContext, 'invocationId' | 'timestamp'>).catch((err) => {\n console.error('Composition hook error:', err);\n });\n\n return result.skill;\n }\n\n /**\n * Manually trigger composition suggestions for existing skills\n */\n async suggestCompositions(skillIds?: string[]): Promise<Map<string, CompositionSuggestion[]>> {\n if (!this.composer) {\n throw new Error('Composition is not enabled. Set composition.enabled: true in config.');\n }\n\n // Get skills\n let skills: Skill[];\n if (skillIds) {\n const skillPromises = skillIds.map((id) => this.storage.getSkill(id));\n const results = await Promise.all(skillPromises);\n skills = results.filter((s): s is Skill => s !== null);\n } else {\n skills = await this.storage.listSkills({ status: ['active'] });\n }\n\n if (skills.length < 2) {\n return new Map();\n }\n\n // Generate suggestions\n const suggestions = await this.composer.suggestCompositions(skills);\n\n // Group by first skill ID\n const grouped = new Map<string, CompositionSuggestion[]>();\n for (const suggestion of suggestions) {\n const key = suggestion.skillIds[0];\n const existing = grouped.get(key) || [];\n existing.push(suggestion);\n grouped.set(key, existing);\n }\n\n // Store and emit events\n for (const [skillId, skillSuggestions] of grouped) {\n this.compositionSuggestions.set(skillId, skillSuggestions);\n\n // Emit composition:suggested event\n const skill = skills.find((s) => s.id === skillId);\n if (skill && skillSuggestions.length > 0) {\n this.hookRegistry.execute('composition:suggested', {\n event: 'composition:suggested',\n triggerSkill: skill,\n suggestions: skillSuggestions.map((s) => ({\n skillIds: s.skillIds,\n mode: s.mode,\n reason: s.reason,\n confidence: s.confidence,\n })),\n } as Omit<CompositionHookContext, 'invocationId' | 'timestamp'>).catch((err) => {\n console.error('Composition hook error:', err);\n });\n }\n }\n\n return grouped;\n }\n\n /**\n * Get the composer instance (for advanced usage)\n */\n getComposer(): SkillComposer | undefined {\n return this.composer;\n }\n\n /**\n * Run composition suggestions asynchronously after skill creation\n */\n private async runCompositionSuggestionsAsync(skill: Skill): Promise<void> {\n if (!this.composer) return;\n\n try {\n // Get other active skills\n const allSkills = await this.storage.listSkills({ status: ['active'] });\n\n // Only suggest if we have multiple skills\n if (allSkills.length < 2) return;\n\n // Generate suggestions including the new skill\n const suggestions = await this.composer.suggestCompositions(allSkills, {\n maxSuggestions: 3,\n minConfidence: 0.6,\n });\n\n // Filter to suggestions involving the new skill\n const relevantSuggestions = suggestions.filter((s) =>\n s.skillIds.includes(skill.id)\n );\n\n if (relevantSuggestions.length > 0) {\n this.compositionSuggestions.set(skill.id, relevantSuggestions);\n\n // Emit composition:suggested event\n this.hookRegistry.execute('composition:suggested', {\n event: 'composition:suggested',\n triggerSkill: skill,\n suggestions: relevantSuggestions.map((s) => ({\n skillIds: s.skillIds,\n mode: s.mode,\n reason: s.reason,\n confidence: s.confidence,\n })),\n } as Omit<CompositionHookContext, 'invocationId' | 'timestamp'>).catch((err) => {\n console.error('Composition hook error:', err);\n });\n }\n } catch (error) {\n console.error('Async composition suggestion error:', error);\n }\n }\n\n // ==========================================================================\n // Semantic Matching\n // ==========================================================================\n\n /**\n * Unified skill search: accepts a plain string or a structured MatchContext.\n *\n * This is the recommended entry point for skill matching. It dispatches to\n * embedding-based search (SemanticMatcher) when available, falling back to\n * keyword search (StorageAdapter.searchSkills) when the query is a plain string.\n *\n * @example\n * ```typescript\n * // String query\n * const results = await bank.findSkills('fix typescript compilation error');\n *\n * // Structured context\n * const results = await bank.findSkills({\n * errorMessage: 'TS2322: Type string is not assignable',\n * technologies: ['typescript'],\n * });\n * ```\n */\n async findSkills(\n query: SkillQuery,\n options?: {\n threshold?: number;\n maxResults?: number;\n }\n ): Promise<MatchResult[]> {\n this.ensureInitialized();\n const skills = await this.storage.listSkills({ status: ['active'] });\n\n if (typeof query === 'string') {\n return this.semanticMatcher.findMatches(query, skills, options);\n }\n\n // Structured MatchContext\n return this.semanticMatcher.findByContext(query, skills, options);\n }\n\n /**\n * Find skills matching a query using semantic similarity\n */\n async findMatchingSkills(\n query: string,\n options?: {\n threshold?: number;\n maxResults?: number;\n }\n ): Promise<MatchResult[]> {\n this.ensureInitialized();\n const skills = await this.storage.listSkills({ status: ['active'] });\n return this.semanticMatcher.findMatches(query, skills, options);\n }\n\n /**\n * Find skills matching a context (problem, error, keywords)\n */\n async findSkillsByContext(\n context: MatchContext,\n options?: {\n threshold?: number;\n maxResults?: number;\n }\n ): Promise<MatchResult[]> {\n this.ensureInitialized();\n const skills = await this.storage.listSkills({ status: ['active'] });\n return this.semanticMatcher.findByContext(context, skills, options);\n }\n\n /**\n * Find skills similar to a given skill\n */\n async findSimilarSkills(\n skillId: string,\n options?: {\n threshold?: number;\n maxResults?: number;\n }\n ): Promise<MatchResult[]> {\n this.ensureInitialized();\n const skill = await this.storage.getSkill(skillId);\n if (!skill) {\n throw new Error(`Skill not found: ${skillId}`);\n }\n const allSkills = await this.storage.listSkills({ status: ['active'] });\n return this.semanticMatcher.findSimilar(skill, allSkills, {\n ...options,\n excludeSelf: true,\n });\n }\n\n /**\n * Find skills that might apply to a trajectory\n */\n async findSkillsForTrajectory(\n trajectory: Trajectory,\n options?: {\n threshold?: number;\n maxResults?: number;\n }\n ): Promise<MatchResult[]> {\n this.ensureInitialized();\n const skills = await this.storage.listSkills({ status: ['active'] });\n return this.semanticMatcher.findForTrajectory(trajectory, skills, options);\n }\n\n /**\n * Index all skills for faster semantic matching\n */\n async indexSkills(): Promise<number> {\n this.ensureInitialized();\n return this.semanticMatcher.indexFromStorage(this.storage);\n }\n\n /**\n * Set embedding provider for semantic matching\n */\n setEmbeddingProvider(provider: EmbeddingProvider): void {\n this.semanticMatcher.setConfig({ embeddingProvider: provider });\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 * List skills accessible to the current agent\n * Only returns skills the agent can see based on namespace visibility rules\n */\n async listAccessibleSkills(filter?: Omit<SkillFilter, 'accessibleBy'>): Promise<Skill[]> {\n this.ensureInitialized();\n\n if (!this.namespaceConfig) {\n // No namespace config, return all skills\n return this.storage.listSkills(filter);\n }\n\n return this.storage.listSkills({\n ...filter,\n accessibleBy: this.namespaceConfig.agentId,\n accessibleByTeam: this.namespaceConfig.team,\n });\n }\n\n /**\n * List skills by scope\n */\n async listSkillsByScope(scope: SkillScope, filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n return this.storage.listSkills({\n ...filter,\n scope,\n });\n }\n\n /**\n * List personal skills for the current agent\n */\n async listPersonalSkills(filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n\n if (!this.namespaceConfig) {\n throw new Error('Namespace configuration required for personal skills');\n }\n\n return this.storage.listSkills({\n ...filter,\n scope: 'personal',\n owner: this.namespaceConfig.agentId,\n });\n }\n\n /**\n * List team skills for the current agent's team\n */\n async listTeamSkills(filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n\n if (!this.namespaceConfig?.team) {\n throw new Error('Team configuration required for team skills');\n }\n\n return this.storage.listSkills({\n ...filter,\n scope: 'team',\n team: this.namespaceConfig.team,\n });\n }\n\n /**\n * List global/public skills\n */\n async listGlobalSkills(filter?: SkillFilter): Promise<Skill[]> {\n this.ensureInitialized();\n\n return this.storage.listSkills({\n ...filter,\n scope: 'global',\n visibility: 'public',\n });\n }\n\n /**\n * Search skills by query\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 async saveSkill(skill: Skill): Promise<void> {\n this.ensureInitialized();\n\n // Apply namespace if configured and skill doesn't have one\n const namespacedSkill = this.ensureNamespace(skill);\n\n const existing = await this.storage.getSkill(namespacedSkill.id);\n await this.storage.saveSkill(namespacedSkill);\n\n if (existing) {\n this.emit({ type: 'skill:updated', skill: namespacedSkill, previousVersion: existing.version });\n } else {\n this.emit({ type: 'skill:created', skill: namespacedSkill });\n }\n }\n\n /**\n * Save a skill with explicit namespace\n */\n async saveSkillWithNamespace(\n skill: Skill,\n namespace: SkillNamespace\n ): Promise<void> {\n this.ensureInitialized();\n\n const namespacedSkill: Skill = {\n ...skill,\n namespace,\n };\n\n await this.saveSkill(namespacedSkill);\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 * Add a new skill (alias for saveSkill with validation)\n * This is the primary method for adding imported skills\n */\n async addSkill(skill: Skill): Promise<Skill> {\n this.ensureInitialized();\n\n // Check if skill already exists\n const existing = await this.storage.getSkill(skill.id);\n if (existing) {\n // Update instead of failing\n skill.updatedAt = new Date();\n await this.storage.saveSkill(skill);\n this.emit({ type: 'skill:updated', skill, previousVersion: existing.version });\n } else {\n // Set created timestamp if not present\n if (!skill.createdAt) {\n skill.createdAt = new Date();\n }\n skill.updatedAt = new Date();\n await this.storage.saveSkill(skill);\n this.emit({ type: 'skill:created', skill });\n }\n\n // Place in taxonomy if available and storage supports it\n if (skill.taxonomy && hasTaxonomySupport(this.storage)) {\n try {\n await this.storage.placeInTaxonomy(skill.id, skill.taxonomy);\n } catch {\n // Taxonomy placement is optional\n }\n }\n\n return skill;\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 (legacy API)\n * Returns an unsubscribe function\n *\n * Note: For more control (async, priority, filtering), use getHookRegistry().register()\n */\n on(handler: SkillTreeEventHandler): () => void {\n this.eventHandlers.push(handler);\n return () => {\n this.off(handler);\n };\n }\n\n /**\n * Subscribe to a specific event type (legacy API)\n * Type-safe subscription for a single event type\n */\n onEvent<T extends SkillTreeEvent['type']>(\n eventType: T,\n handler: (event: Extract<SkillTreeEvent, { type: T }>) => void\n ): () => void {\n const wrappedHandler: SkillTreeEventHandler = (event) => {\n if (event.type === eventType) {\n handler(event as Extract<SkillTreeEvent, { type: T }>);\n }\n };\n\n this.eventHandlers.push(wrappedHandler);\n return () => {\n this.off(wrappedHandler);\n };\n }\n\n /**\n * Subscribe to events via hooks (recommended for async/advanced usage)\n * Provides hook features (async, priority, filtering)\n *\n * @example\n * ```typescript\n * bank.onHook('skill:created', async (context) => {\n * console.log('Created:', context.skill.name);\n * return { continue: true };\n * });\n * ```\n */\n onHook(\n eventType: HookEvent,\n handler: (context: HookContext) => Promise<{ continue: boolean }> | { continue: boolean },\n options?: { priority?: 'high' | 'normal' | 'low'; name?: string }\n ): () => void {\n const hookId = this.hookRegistry.register({\n name: options?.name || `event-handler-${eventType}`,\n events: [eventType],\n priority: options?.priority || 'normal',\n handler: handler as (ctx: HookContext) => Promise<{ continue: boolean }>,\n });\n\n return () => {\n this.hookRegistry.unregister(hookId);\n };\n }\n\n /**\n * Subscribe to skill creation events via hooks\n */\n onSkillCreated(\n handler: (skill: Skill) => void | Promise<void>,\n options?: { priority?: 'high' | 'normal' | 'low' }\n ): () => void {\n return this.onHook(\n 'skill:created',\n async (context) => {\n const ctx = context as SkillCrudHookContext;\n await handler(ctx.skill);\n return { continue: true };\n },\n { ...options, name: 'on-skill-created' }\n );\n }\n\n /**\n * Subscribe to skill update events via hooks\n */\n onSkillUpdated(\n handler: (skill: Skill, previousVersion: string) => void | Promise<void>,\n options?: { priority?: 'high' | 'normal' | 'low' }\n ): () => void {\n return this.onHook(\n 'skill:updated',\n async (context) => {\n const ctx = context as SkillCrudHookContext;\n await handler(ctx.skill, ctx.previousVersion || '');\n return { continue: true };\n },\n { ...options, name: 'on-skill-updated' }\n );\n }\n\n /**\n * Subscribe to extraction completion events via hooks\n */\n onExtractionCompleted(\n handler: (result: ExtractionResult) => void | Promise<void>,\n options?: { priority?: 'high' | 'normal' | 'low' }\n ): () => void {\n return this.onHook(\n 'extraction:after',\n async (context) => {\n const ctx = context as ExtractionHookContext;\n if (ctx.result) {\n await handler(ctx.result);\n }\n return { continue: true };\n },\n { ...options, name: 'on-extraction-completed' }\n );\n }\n\n /**\n * Unsubscribe a handler from events (legacy API)\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 legacy 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 // Map SkillTreeEvent types to HookEvent types\n const hookEvent = this.mapEventToHook(event);\n if (hookEvent) {\n const context = this.buildHookContext(event, hookEvent);\n // Execute async but don't block - errors logged by HookRegistry\n this.hookRegistry.execute(hookEvent, context).catch((err) => {\n console.error('Hook execution 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 'extraction:started': 'extraction:before',\n 'extraction:completed': 'extraction:after',\n 'extraction:failed': 'extraction:error',\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 // Need to fetch skill for context - use a placeholder\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 case 'extraction:started':\n return {\n event: hookEvent as 'extraction:before',\n trajectory: {\n sessionId: event.sessionId,\n startedAt: new Date(),\n turns: [],\n metadata: { agentType: 'unknown' },\n },\n } as Omit<ExtractionHookContext, 'invocationId' | 'timestamp'>;\n\n case 'extraction:completed':\n return {\n event: hookEvent as 'extraction:after',\n trajectory: {\n sessionId: event.result.sourceTrajectory.sessionId,\n startedAt: new Date(),\n turns: [],\n metadata: { agentType: 'unknown' },\n },\n result: event.result,\n } as Omit<ExtractionHookContext, 'invocationId' | 'timestamp'>;\n\n case 'extraction:failed':\n return {\n event: hookEvent as 'extraction:error',\n trajectory: {\n sessionId: 'unknown',\n startedAt: new Date(),\n turns: [],\n metadata: { agentType: 'unknown' },\n },\n error: new Error(event.error),\n } as Omit<ExtractionHookContext, 'invocationId' | 'timestamp'>;\n\n default:\n return { event: hookEvent } as Omit<HookContext, 'invocationId' | 'timestamp'>;\n }\n }\n\n /**\n * Check if a skill is a semantic duplicate of an existing skill.\n * Returns the best match above 0.9 similarity, or null if no duplicate found.\n */\n private async findSemanticDuplicate(skill: Skill): Promise<MatchResult | null> {\n try {\n const existingSkills = await this.storage.listSkills({ status: ['active', 'draft'] });\n // Exclude the skill itself (in case it was already saved)\n const candidates = existingSkills.filter((s) => s.id !== skill.id);\n if (candidates.length === 0) return null;\n\n const matches = await this.semanticMatcher.findSimilar(skill, candidates, {\n threshold: 0.9,\n maxResults: 1,\n });\n\n return matches.length > 0 ? matches[0] : null;\n } catch {\n // Dedup is best-effort; don't block extraction on matcher failures\n return null;\n }\n }\n\n /**\n * Get the underlying storage adapter (for advanced use cases)\n * This is exposed for IndexerService integration\n */\n getStorage(): StorageAdapter {\n return this.storage;\n }\n\n /**\n * Get the hook registry for registering custom hooks\n * Use this to add hooks that respond to skill bank events\n */\n getHookRegistry(): HookRegistry {\n return this.hookRegistry;\n }\n\n /**\n * Get the activation manager for session and trigger management\n */\n getActivationManager(): ActivationManager {\n return this.activationManager;\n }\n\n // ==========================================================================\n // Session Management (for agent context tracking)\n // ==========================================================================\n\n /**\n * Start a session with agent context\n * Skills extracted during this session will be attributed to the agent\n *\n * @example\n * ```typescript\n * bank.startSession({\n * agentId: 'my-agent-001',\n * agentName: 'Code Assistant',\n * agentMetadata: { version: '2.0' },\n * });\n * ```\n */\n startSession(config: SessionConfig): string {\n return this.activationManager.startSession(config);\n }\n\n /**\n * End the current session\n * May trigger auto-extraction if configured\n */\n async endSession(trajectory?: Trajectory): Promise<void> {\n await this.activationManager.endSession(trajectory);\n }\n\n /**\n * Get current agent ID (if session is active)\n */\n getCurrentAgentId(): string | undefined {\n return this.activationManager.getCurrentAgentId();\n }\n\n /**\n * Get current agent metadata (if session is active)\n */\n getCurrentAgentMetadata(): Record<string, unknown> | undefined {\n return this.activationManager.getAgentMetadata();\n }\n\n // ==========================================================================\n // Serving Layer Integration\n // ==========================================================================\n\n /**\n * Create a serving layer (SkillGraphServer) wired to this SkillBank\n *\n * The serving layer provides:\n * - Dynamic skill loadouts\n * - Skill expansion/collapse management\n * - Bidirectional event flow with SkillBank\n *\n * @example\n * ```typescript\n * const { server, eventBridge, storageView } = await bank.createServingLayer({\n * initialLoadout: { tags: ['typescript'] },\n * maxExpanded: 5,\n * });\n *\n * // Server is now ready to use\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, this.semanticMatcher);\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 // Keep only last 50 feedback scores\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 // Log or track skill requests (could emit hook)\n break;\n\n case 'loadout:changed':\n // Could emit a hook or log loadout changes\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 // Status counts\n stats.byStatus[skill.status]++;\n\n // Tag counts\n for (const tag of skill.tags) {\n stats.byTag[tag] = (stats.byTag[tag] || 0) + 1;\n }\n\n // Metrics\n stats.totalUsage += skill.metrics.usageCount;\n if (skill.metrics.successRate > 0) {\n successRateSum += skill.metrics.successRate;\n successRateCount++;\n }\n\n // Namespace stats\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 // Federation (Remote Repository Connections)\n // ==========================================================================\n\n /**\n * Ensure federation manager is available.\n * Lazily initializes federation on first use.\n */\n private async ensureFederation(): Promise<FederationManager> {\n this.ensureInitialized();\n\n if (!this.basePath) {\n throw new Error(\n 'Federation requires filesystem storage. Configure storage: { type: \"filesystem\", basePath: \"...\" }'\n );\n }\n\n if (!this.federationManager) {\n this.federationManager = new FederationManager({\n basePath: this.basePath,\n storage: this.storage,\n });\n await this.federationManager.initialize();\n }\n\n return this.federationManager;\n }\n\n /**\n * Add a remote skill repository.\n *\n * Once added, you can browse and import skills from this remote.\n *\n * @example\n * ```typescript\n * bank.addRemote('team', {\n * url: 'git@github.com:org/team-skills.git',\n * access: 'read-write',\n * });\n * ```\n */\n async addRemote(name: string, config: FederatedRemoteConfig): Promise<void> {\n const federation = await this.ensureFederation();\n await federation.addRemote(name, config);\n }\n\n /**\n * Remove a remote skill repository.\n */\n async removeRemote(name: string): Promise<boolean> {\n const federation = await this.ensureFederation();\n return federation.removeRemote(name);\n }\n\n /**\n * List configured remotes.\n */\n async listRemotes(): Promise<string[]> {\n const federation = await this.ensureFederation();\n return federation.listRemotes();\n }\n\n /**\n * Check if a remote exists.\n */\n async hasRemote(name: string): Promise<boolean> {\n const federation = await this.ensureFederation();\n return federation.hasRemote(name);\n }\n\n /**\n * Get the status of a remote.\n */\n async getRemoteState(name: string): Promise<RemoteState> {\n const federation = await this.ensureFederation();\n return federation.getRemoteState(name);\n }\n\n /**\n * Refresh a remote (fetch latest from git).\n */\n async refreshRemote(name: string): Promise<RemoteState> {\n const federation = await this.ensureFederation();\n return federation.refreshRemote(name);\n }\n\n /**\n * Browse skills in a remote repository.\n *\n * This lists skills available in the remote without importing them.\n *\n * @example\n * ```typescript\n * const teamSkills = await bank.browse('team');\n * for (const skill of teamSkills) {\n * console.log(`${skill.id}: ${skill.name}`);\n * }\n * ```\n */\n async browse(remote: string, filter?: SkillFilter): Promise<Skill[]> {\n const federation = await this.ensureFederation();\n return federation.browse(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 const federation = await this.ensureFederation();\n return federation.browseSkill(remote, skillId);\n }\n\n /**\n * Import a skill from a remote repository.\n *\n * Import modes:\n * - **link** (default): Track upstream for updates. ID becomes `@remote/skillId`.\n * Use `checkUpstream()` and `pullUpstream()` to sync.\n * - **fork**: Independent copy with no upstream tracking.\n * Origin recorded in `derivedFrom`.\n *\n * @example\n * ```typescript\n * // Import with link (track updates)\n * await bank.import('team', 'auth-pattern');\n * // Now available as '@team/auth-pattern'\n *\n * // Import as fork (independent copy)\n * await bank.import('team', 'rate-limiter', {\n * mode: 'fork',\n * as: 'my-rate-limiter',\n * });\n * ```\n */\n async import(\n remote: string,\n skillId: string,\n options?: ImportOptions\n ): Promise<ImportResult> {\n const federation = await this.ensureFederation();\n return federation.import(remote, skillId, options);\n }\n\n /**\n * Share a local skill to a remote repository.\n *\n * Requires a remote with 'read-write' access.\n *\n * @example\n * ```typescript\n * await bank.share('my-pattern', 'team', {\n * message: 'Add useful pattern for error handling',\n * });\n * ```\n */\n async share(\n localId: string,\n remote: string,\n options?: ShareOptions\n ): Promise<ShareResult> {\n const federation = await this.ensureFederation();\n return federation.share(localId, remote, options);\n }\n\n /**\n * Check for upstream updates to linked skills.\n *\n * Returns a list of linked skills that have newer versions available\n * in their upstream repositories.\n *\n * @example\n * ```typescript\n * const updates = await bank.checkUpstream();\n * for (const update of updates) {\n * console.log(`${update.localId}: ${update.localVersion} → ${update.remoteVersion}`);\n * }\n * ```\n */\n async checkUpstream(): Promise<UpstreamUpdate[]> {\n const federation = await this.ensureFederation();\n return federation.checkUpstream();\n }\n\n /**\n * Pull upstream changes for a linked skill.\n *\n * @example\n * ```typescript\n * // Merge upstream changes\n * await bank.pullUpstream('@team/auth-pattern');\n *\n * // Overwrite local with upstream\n * await bank.pullUpstream('@team/auth-pattern', { strategy: 'overwrite' });\n * ```\n */\n async pullUpstream(\n localId: string,\n options?: PullUpstreamOptions\n ): Promise<PullUpstreamResult> {\n const federation = await this.ensureFederation();\n return federation.pullUpstream(localId, options);\n }\n\n /**\n * Unlink a skill from its upstream (convert link to fork).\n *\n * After unlinking, the skill becomes independent and will no longer\n * receive upstream updates. The original source is recorded in `derivedFrom`.\n *\n * @example\n * ```typescript\n * // Stop tracking upstream changes\n * await bank.unlink('@team/auth-pattern');\n * // Skill is now a fork, free to modify without upstream sync\n * ```\n */\n async unlink(localId: string): Promise<void> {\n const federation = await this.ensureFederation();\n return federation.unlink(localId);\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 /** Namespace breakdown (if namespace config is enabled) */\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 * 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 'problem',\n 'solution',\n 'verification',\n 'triggerConditions',\n 'examples',\n 'tags',\n 'notes',\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 problem: this.extractSection(body, 'Problem') || '',\n solution: this.extractSection(body, 'Solution') || '',\n verification: this.extractSection(body, 'Verification') || '',\n triggerConditions: [],\n examples: [],\n notes: this.extractSection(body, 'Notes'),\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 extractSection(content: string, heading: string): string | undefined {\n const regex = new RegExp(\n `## ${heading}\\\\n([\\\\s\\\\S]*?)(?=\\\\n## |$)`,\n 'i'\n );\n const match = content.match(regex);\n return match ? match[1].trim() : undefined;\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 '## Problem',\n '',\n skill.problem,\n '',\n '## Solution',\n '',\n skill.solution,\n '',\n '## Verification',\n '',\n skill.verification,\n ];\n\n if (skill.notes) {\n body.push('', '## Notes', '', skill.notes);\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 problem: skill.problem,\n solution: skill.solution,\n verification: skill.verification,\n triggerConditions: skill.triggerConditions,\n examples: skill.examples,\n tags: skill.tags,\n notes: skill.notes,\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 * 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// 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 examples: 'union',\n triggerConditions: 'union',\n },\n },\n };\n}\n","/**\n * MCP Tool Definitions for Loadout Management\n *\n * These tools allow agents to view and modify their skill loadouts.\n *\n * @packageDocumentation\n */\n\nimport type { ToolDefinition } from '../../serving/types.js';\n\n/**\n * List skills in the current loadout\n */\nexport const loadoutListTool: ToolDefinition = {\n name: 'loadout_list',\n description:\n 'List skills in your current loadout. Shows available skills (summaries), expanded skills (full content visible), and pending skill requests. Use this to see what skills you have access to.',\n inputSchema: {\n type: 'object',\n properties: {\n filter: {\n type: 'string',\n enum: ['all', 'expanded', 'available', 'pending'],\n description:\n 'Filter results: \"all\" (default) shows everything, \"expanded\" shows only skills with full content visible, \"available\" shows skills with summaries only, \"pending\" shows skills awaiting approval',\n },\n },\n },\n};\n\n/**\n * Search for skills to add to loadout\n */\nexport const loadoutSearchTool: ToolDefinition = {\n name: 'loadout_search',\n description:\n 'Search for skills that can be added to your loadout. Searches across all available skills by name, description, and tags. Use this to find relevant skills for your current task.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Search query - matches skill names, descriptions, problems, and tags',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of results to return (default: 5)',\n },\n },\n required: ['query'],\n },\n};\n\n/**\n * Request to add skills to loadout\n */\nexport const loadoutAddTool: ToolDefinition = {\n name: 'loadout_add',\n description:\n 'Request to add skills to your loadout. If approval is required, skills will be added to pending. Otherwise, they will be added immediately. Use skill IDs from loadout_search results.',\n inputSchema: {\n type: 'object',\n properties: {\n skill_ids: {\n type: 'array',\n items: { type: 'string' },\n description: 'Array of skill IDs to add to your loadout',\n },\n },\n required: ['skill_ids'],\n },\n};\n\n/**\n * Remove skills from loadout\n */\nexport const loadoutRemoveTool: ToolDefinition = {\n name: 'loadout_remove',\n description:\n 'Remove skills from your current loadout. Removes skills from both available and expanded states. Use this to declutter your loadout or remove irrelevant skills.',\n inputSchema: {\n type: 'object',\n properties: {\n skill_ids: {\n type: 'array',\n items: { type: 'string' },\n description: 'Array of skill IDs to remove from your loadout',\n },\n },\n required: ['skill_ids'],\n },\n};\n\n/**\n * Switch to a named profile\n */\nexport const loadoutProfileTool: ToolDefinition = {\n name: 'loadout_profile',\n description:\n 'Switch your loadout to a pre-configured profile. Profiles are curated sets of skills for common tasks like code-review, debugging, security, testing, etc. This replaces your current loadout.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description:\n 'Profile name. Common profiles: \"code-review\", \"implementation\", \"debugging\", \"security\", \"testing\", \"refactoring\", \"documentation\", \"devops\"',\n },\n },\n required: ['name'],\n },\n};\n\n/**\n * Set loadout from criteria\n */\nexport const loadoutSetTool: ToolDefinition = {\n name: 'loadout_set',\n description:\n 'Set your loadout based on criteria. Allows filtering by tags, task description, or other criteria. This may be restricted - if denied, use loadout_profile or loadout_add instead.',\n inputSchema: {\n type: 'object',\n properties: {\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Include skills matching any of these tags',\n },\n tags_all: {\n type: 'array',\n items: { type: 'string' },\n description: 'Include only skills matching ALL of these tags',\n },\n task_description: {\n type: 'string',\n description: 'Semantic match to task description',\n },\n max_skills: {\n type: 'number',\n description: 'Maximum number of skills to include',\n },\n },\n },\n};\n\n/**\n * All loadout management tools\n */\nexport const loadoutTools: ToolDefinition[] = [\n loadoutListTool,\n loadoutSearchTool,\n loadoutAddTool,\n loadoutRemoveTool,\n loadoutProfileTool,\n loadoutSetTool,\n];\n","/**\n * MCP Tool Definitions for Skill Operations\n *\n * These tools allow agents to expand, collapse, and use individual skills.\n *\n * @packageDocumentation\n */\n\nimport type { ToolDefinition } from '../../serving/types.js';\n\n/**\n * Expand a skill to see full content\n */\nexport const skillExpandTool: ToolDefinition = {\n name: 'skill_expand',\n description:\n 'Expand a skill to see its full content including problem description, solution steps, verification criteria, and examples. The skill must be in your current loadout. Returns the complete skill object.',\n inputSchema: {\n type: 'object',\n properties: {\n skill_id: {\n type: 'string',\n description: 'ID of the skill to expand (must be in your loadout)',\n },\n },\n required: ['skill_id'],\n },\n};\n\n/**\n * Collapse a skill back to summary\n */\nexport const skillCollapseTool: ToolDefinition = {\n name: 'skill_collapse',\n description:\n 'Collapse an expanded skill back to summary view. This frees up space in your expanded skill limit. Use this when you no longer need the full content of a skill.',\n inputSchema: {\n type: 'object',\n properties: {\n skill_id: {\n type: 'string',\n description: 'ID of the skill to collapse',\n },\n },\n required: ['skill_id'],\n },\n};\n\n/**\n * Use/invoke a skill\n */\nexport const skillUseTool: ToolDefinition = {\n name: 'skill_use',\n description:\n 'Mark a skill as being used for the current task. This auto-expands the skill if not already expanded, and may expand related skills that are often used together. Use this when you are actively applying a skill.',\n inputSchema: {\n type: 'object',\n properties: {\n skill_id: {\n type: 'string',\n description: 'ID of the skill being used',\n },\n },\n required: ['skill_id'],\n },\n};\n\n/**\n * Get details about a specific skill\n */\nexport const skillGetTool: ToolDefinition = {\n name: 'skill_get',\n description:\n 'Get details about a specific skill by ID. Returns the skill if it is in your loadout, or null if not found. Use this to check skill details before expanding.',\n inputSchema: {\n type: 'object',\n properties: {\n skill_id: {\n type: 'string',\n description: 'ID of the skill to retrieve',\n },\n },\n required: ['skill_id'],\n },\n};\n\n/**\n * All skill operation tools\n */\nexport const skillTools: ToolDefinition[] = [\n skillExpandTool,\n skillCollapseTool,\n skillUseTool,\n skillGetTool,\n];\n","/**\n * MCP Tool Definitions\n *\n * Exports all tool definitions for the skill-tree MCP server.\n *\n * @packageDocumentation\n */\n\nimport type { ToolDefinition } from '../../serving/types.js';\n\n// Loadout management tools\nexport {\n loadoutListTool,\n loadoutSearchTool,\n loadoutAddTool,\n loadoutRemoveTool,\n loadoutProfileTool,\n loadoutSetTool,\n loadoutTools,\n} from './loadout-tools.js';\n\n// Skill operation tools\nexport {\n skillExpandTool,\n skillCollapseTool,\n skillUseTool,\n skillGetTool,\n skillTools,\n} from './skill-tools.js';\n\n// Re-export ToolDefinition type\nexport type { ToolDefinition };\n\n/**\n * All available MCP tools\n */\nimport { loadoutTools } from './loadout-tools.js';\nimport { skillTools } from './skill-tools.js';\n\nexport const allTools: ToolDefinition[] = [...loadoutTools, ...skillTools];\n\n/**\n * Get a tool definition by name\n */\nexport function getToolDefinition(name: string): ToolDefinition | undefined {\n return allTools.find((tool) => tool.name === name);\n}\n\n/**\n * Get all tool names\n */\nexport function getToolNames(): string[] {\n return allTools.map((tool) => tool.name);\n}\n","/**\n * MCP Tool Handlers\n *\n * Maps MCP tool calls to SkillGraphServer methods.\n * Can be used with any MCP server implementation.\n *\n * @packageDocumentation\n */\n\nimport type { Skill } from '../types.js';\nimport type { SkillGraphServer } from '../serving/graph-server.js';\nimport type { LoadoutView, SkillSummary, LoadoutCriteria } from '../serving/types.js';\n\n/**\n * Result of a tool execution\n */\nexport interface ToolResult {\n /** Whether the tool executed successfully */\n success: boolean;\n /** Result data (if success) */\n data?: unknown;\n /** Error message (if !success) */\n error?: string;\n}\n\n/**\n * Tool handler function type\n */\nexport type ToolHandler = (args: Record<string, unknown>) => Promise<ToolResult>;\n\n/**\n * Creates tool handlers bound to a SkillGraphServer instance\n */\nexport function createToolHandlers(server: SkillGraphServer): Record<string, ToolHandler> {\n return {\n // =========================================================================\n // Loadout Tools\n // =========================================================================\n\n /**\n * List skills in current loadout\n */\n loadout_list: async (args): Promise<ToolResult> => {\n try {\n const filter = args.filter as string | undefined;\n const view = server.agentListLoadout();\n\n if (filter === 'expanded') {\n return {\n success: true,\n data: {\n ...view,\n available: view.available.filter((s) => s.expanded),\n },\n };\n } else if (filter === 'available') {\n return {\n success: true,\n data: {\n ...view,\n available: view.available.filter((s) => !s.expanded),\n },\n };\n } else if (filter === 'pending') {\n return {\n success: true,\n data: {\n available: [],\n pending: view.pending,\n profiles: view.profiles,\n },\n };\n }\n\n return { success: true, data: view };\n } catch (err) {\n return { success: false, error: String(err) };\n }\n },\n\n /**\n * Search for skills to add\n */\n loadout_search: async (args): Promise<ToolResult> => {\n try {\n const query = args.query as string;\n const limit = args.limit as number | undefined;\n\n if (!query) {\n return { success: false, error: 'query is required' };\n }\n\n const results = await server.agentSearchSkills(query, limit);\n return { success: true, data: results };\n } catch (err) {\n return { success: false, error: String(err) };\n }\n },\n\n /**\n * Request to add skills\n */\n loadout_add: async (args): Promise<ToolResult> => {\n try {\n const skillIds = args.skill_ids as string[];\n\n if (!skillIds || !Array.isArray(skillIds)) {\n return { success: false, error: 'skill_ids array is required' };\n }\n\n const result = await server.agentRequestSkills(skillIds);\n return { success: true, data: result };\n } catch (err) {\n return { success: false, error: String(err) };\n }\n },\n\n /**\n * Remove skills from loadout\n */\n loadout_remove: async (args): Promise<ToolResult> => {\n try {\n const skillIds = args.skill_ids as string[];\n\n if (!skillIds || !Array.isArray(skillIds)) {\n return { success: false, error: 'skill_ids array is required' };\n }\n\n const result = server.agentRemoveSkills(skillIds);\n return { success: true, data: result };\n } catch (err) {\n return { success: false, error: String(err) };\n }\n },\n\n /**\n * Switch to a profile\n */\n loadout_profile: async (args): Promise<ToolResult> => {\n try {\n const name = args.name as string;\n\n if (!name) {\n return { success: false, error: 'name is required' };\n }\n\n const state = await server.agentSwitchProfile(name);\n if (state === null) {\n return { success: false, error: 'Profile switching is not permitted' };\n }\n\n // Return the new loadout view\n const view = server.agentListLoadout();\n return { success: true, data: view };\n } catch (err) {\n return { success: false, error: String(err) };\n }\n },\n\n /**\n * Set loadout from criteria\n */\n loadout_set: async (args): Promise<ToolResult> => {\n try {\n const criteria: LoadoutCriteria = {};\n\n if (args.tags) criteria.tags = args.tags as string[];\n if (args.tags_all) criteria.tagsAll = args.tags_all as string[];\n if (args.task_description) criteria.taskDescription = args.task_description as string;\n if (args.max_skills) criteria.maxSkills = args.max_skills as number;\n\n const state = await server.agentSetLoadout(criteria);\n if (state === null) {\n return { success: false, error: 'Setting loadout is not permitted' };\n }\n\n const view = server.agentListLoadout();\n return { success: true, data: view };\n } catch (err) {\n return { success: false, error: String(err) };\n }\n },\n\n // =========================================================================\n // Skill Tools\n // =========================================================================\n\n /**\n * Expand a skill\n */\n skill_expand: async (args): Promise<ToolResult> => {\n try {\n const skillId = args.skill_id as string;\n\n if (!skillId) {\n return { success: false, error: 'skill_id is required' };\n }\n\n const skill = server.agentExpandSkill(skillId);\n if (skill === null) {\n return { success: false, error: `Skill not found in loadout: ${skillId}` };\n }\n\n return { success: true, data: formatSkillForOutput(skill) };\n } catch (err) {\n return { success: false, error: String(err) };\n }\n },\n\n /**\n * Collapse a skill\n */\n skill_collapse: async (args): Promise<ToolResult> => {\n try {\n const skillId = args.skill_id as string;\n\n if (!skillId) {\n return { success: false, error: 'skill_id is required' };\n }\n\n const success = server.agentCollapseSkill(skillId);\n return { success: true, data: { collapsed: success } };\n } catch (err) {\n return { success: false, error: String(err) };\n }\n },\n\n /**\n * Use/invoke a skill\n */\n skill_use: async (args): Promise<ToolResult> => {\n try {\n const skillId = args.skill_id as string;\n\n if (!skillId) {\n return { success: false, error: 'skill_id is required' };\n }\n\n // Record usage (this auto-expands if configured)\n server.recordUsage(skillId);\n\n // Get the skill content\n const state = server.getState();\n const skill = state.available.get(skillId);\n\n if (!skill) {\n return { success: false, error: `Skill not found in loadout: ${skillId}` };\n }\n\n return { success: true, data: formatSkillForOutput(skill) };\n } catch (err) {\n return { success: false, error: String(err) };\n }\n },\n\n /**\n * Get skill details\n */\n skill_get: async (args): Promise<ToolResult> => {\n try {\n const skillId = args.skill_id as string;\n\n if (!skillId) {\n return { success: false, error: 'skill_id is required' };\n }\n\n const state = server.getState();\n const skill = state.available.get(skillId);\n\n if (!skill) {\n return { success: true, data: null };\n }\n\n const isExpanded = state.expanded.has(skillId);\n if (isExpanded) {\n return { success: true, data: formatSkillForOutput(skill) };\n } else {\n // Return summary only\n return {\n success: true,\n data: {\n id: skill.id,\n name: skill.name,\n description: skill.description,\n tags: skill.tags,\n expanded: false,\n },\n };\n }\n } catch (err) {\n return { success: false, error: String(err) };\n }\n },\n };\n}\n\n/**\n * Execute a tool by name\n */\nexport async function executeToolCall(\n handlers: Record<string, ToolHandler>,\n toolName: string,\n args: Record<string, unknown>\n): Promise<ToolResult> {\n const handler = handlers[toolName];\n if (!handler) {\n return { success: false, error: `Unknown tool: ${toolName}` };\n }\n return handler(args);\n}\n\n/**\n * Format skill for output (removes internal fields)\n */\nfunction formatSkillForOutput(skill: Skill): Record<string, unknown> {\n return {\n id: skill.id,\n name: skill.name,\n version: skill.version,\n description: skill.description,\n problem: skill.problem,\n triggerConditions: skill.triggerConditions,\n solution: skill.solution,\n verification: skill.verification,\n examples: skill.examples,\n tags: skill.tags,\n notes: skill.notes,\n };\n}\n","/**\n * MCP Server Factory\n *\n * Creates an MCP server configuration for skill-tree.\n * Can be used with the @modelcontextprotocol/sdk package.\n *\n * @packageDocumentation\n */\n\nimport type { SkillGraphServer } from '../serving/graph-server.js';\nimport type { ToolDefinition, ServingEvent } from '../serving/types.js';\nimport { createToolHandlers, executeToolCall, type ToolHandler, type ToolResult } from './handlers.js';\nimport { allTools } from './tools/index.js';\n\n/**\n * Configuration for the MCP server\n */\nexport interface McpServerConfig {\n /** Name of the server */\n name?: string;\n /** Version of the server */\n version?: string;\n /** Enable dynamic tool registration for expanded skills */\n dynamicTools?: boolean;\n}\n\n/**\n * Default server configuration\n */\nconst DEFAULT_CONFIG: Required<McpServerConfig> = {\n name: 'skill-tree',\n version: '1.0.0',\n dynamicTools: true,\n};\n\n/**\n * MCP Server wrapper for SkillGraphServer\n *\n * Provides:\n * - Tool definitions for MCP clients\n * - Tool execution handlers\n * - Dynamic tool registration based on loadout state\n * - Event hooks for tools/list_changed notifications\n */\nexport class SkillTreeMcpServer {\n private config: Required<McpServerConfig>;\n private handlers: Record<string, ToolHandler>;\n private toolsChangedCallbacks: Set<() => void> = new Set();\n private unsubscribeEvents?: () => void;\n\n constructor(\n private graphServer: SkillGraphServer,\n config?: McpServerConfig\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.handlers = createToolHandlers(graphServer);\n\n // Subscribe to events for dynamic tool updates\n if (this.config.dynamicTools) {\n this.unsubscribeEvents = graphServer.on((event) => {\n this.handleGraphEvent(event);\n });\n }\n }\n\n /**\n * Get server info for MCP initialization\n */\n getServerInfo(): { name: string; version: string } {\n return {\n name: this.config.name,\n version: this.config.version,\n };\n }\n\n /**\n * Get all available tools (static + dynamic)\n */\n getTools(): ToolDefinition[] {\n const tools = [...allTools];\n\n // Add dynamic tools for expanded skills\n if (this.config.dynamicTools) {\n const state = this.graphServer.getState();\n for (const skillId of state.expanded) {\n const skill = state.available.get(skillId);\n if (skill) {\n tools.push(this.createDynamicSkillTool(skillId, skill.name, skill.description));\n }\n }\n }\n\n return tools;\n }\n\n /**\n * Execute a tool call\n */\n async executeTool(name: string, args: Record<string, unknown>): Promise<ToolResult> {\n // Check for dynamic skill tool\n if (name.startsWith('skill_') && !this.handlers[name]) {\n const skillId = name.replace('skill_', '');\n const state = this.graphServer.getState();\n\n if (state.expanded.has(skillId)) {\n // Treat as skill_use for the dynamic tool\n return executeToolCall(this.handlers, 'skill_use', { skill_id: skillId });\n }\n }\n\n return executeToolCall(this.handlers, name, args);\n }\n\n /**\n * Subscribe to tools/list_changed notifications\n */\n onToolsChanged(callback: () => void): () => void {\n this.toolsChangedCallbacks.add(callback);\n return () => this.toolsChangedCallbacks.delete(callback);\n }\n\n /**\n * Clean up resources\n */\n dispose(): void {\n if (this.unsubscribeEvents) {\n this.unsubscribeEvents();\n }\n this.toolsChangedCallbacks.clear();\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * Handle graph server events\n */\n private handleGraphEvent(event: ServingEvent): void {\n // Notify tools changed when skills are expanded/collapsed\n if (event.type === 'skill:expanded' || event.type === 'skill:collapsed') {\n this.notifyToolsChanged();\n }\n }\n\n /**\n * Notify all tools changed callbacks\n */\n private notifyToolsChanged(): void {\n for (const callback of this.toolsChangedCallbacks) {\n callback();\n }\n }\n\n /**\n * Create a dynamic tool definition for an expanded skill\n */\n private createDynamicSkillTool(\n skillId: string,\n skillName: string,\n skillDescription: string\n ): ToolDefinition {\n return {\n name: `skill_${skillId}`,\n description: `Use the \"${skillName}\" skill: ${skillDescription}`,\n inputSchema: {\n type: 'object',\n properties: {},\n },\n };\n }\n}\n\n/**\n * Create an MCP server instance\n */\nexport function createMcpServer(\n graphServer: SkillGraphServer,\n config?: McpServerConfig\n): SkillTreeMcpServer {\n return new SkillTreeMcpServer(graphServer, config);\n}\n","/**\n * skill-tree - A library for managing agent skill versions and evolution\n *\n * This library provides:\n * - Session adapters for parsing different agent trajectory formats\n * - Skill extraction (manual and automatic with quality gates)\n * - Versioned skill storage (OpenSkills-compatible)\n * - Lineage tracking and skill evolution\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 type SkillQuery,\n} from \"./skill-bank.js\";\n\n// Types\nexport type {\n // Core skill types\n Skill,\n SkillStatus,\n TriggerCondition,\n SkillExample,\n SkillMetrics,\n SkillSource,\n\n // Version types\n SkillVersion,\n SkillLineage,\n SkillFork,\n\n // Trajectory types\n Trajectory,\n Turn,\n ToolCall,\n ToolResult,\n TrajectoryMetadata,\n TrajectoryOutcome,\n\n // Extraction types\n ExtractionConfig,\n ExtractionResult,\n QualityGate,\n QualityGateResult,\n ManualExtractionRequest,\n\n // Storage types\n StorageAdapter,\n SkillFilter,\n StorageConfig,\n\n // Adapter types\n SessionAdapter,\n\n // LLM types\n LLMProvider,\n LLMOptions,\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} from \"./types.js\";\n\n// Adapters\nexport {\n BaseSessionAdapter,\n AdapterRegistry,\n adapterRegistry,\n ClaudeCodeAdapter,\n claudeCodeAdapter,\n OpenAIAdapter,\n openAIAdapter,\n AnthropicAdapter,\n anthropicAdapter,\n GenericAdapter,\n genericAdapter,\n createGenericAdapter,\n type GenericAdapterConfig,\n} from \"./adapters/index.js\";\n\n// Extraction\nexport {\n BaseExtractor,\n ManualExtractor,\n AutomaticExtractor,\n QualityGateEvaluator,\n DEFAULT_QUALITY_GATES,\n type ExtractOptions,\n} from \"./extraction/index.js\";\n\n// Storage\nexport {\n BaseStorageAdapter,\n MemoryStorageAdapter,\n FilesystemStorageAdapter,\n SQLiteStorageAdapter,\n migrateStorage,\n type FilesystemStorageConfig,\n type SQLiteStorageConfig,\n type MigrationOptions,\n type MigrationResult,\n type MigrationProgressItem,\n} from \"./storage/index.js\";\n\n// Federation / Discovery\nexport {\n discoverSkills,\n hasSkilltreeDir,\n type DiscoveredSkill,\n} from \"./federation/skilltree-config.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// Semantic Matching\nexport {\n SemanticMatcher,\n type MatcherConfig,\n type MatchResult,\n type MatchContext,\n type SkillEmbeddingField,\n type EmbeddingProvider,\n type EmbeddingProviderOptions,\n SimpleHashEmbedding,\n OpenAIEmbedding,\n VoyageEmbedding,\n cosineSimilarity,\n euclideanDistance,\n} from \"./matching/index.js\";\n\n// Batch Processing\nexport {\n BatchProcessor,\n type BatchConfig,\n type BatchProgress,\n type BatchResult,\n type SessionInput,\n type DeduplicationStrategy,\n} from \"./batch/index.js\";\n\n// Skill Composition\nexport {\n SkillComposer,\n DependencyGraph,\n type ComposerConfig,\n type CompositionResult,\n type CompositionConflict,\n type CompositionSuggestion,\n type GraphNode,\n type GraphEdge,\n type DependencyType,\n type CompoundSkill,\n type SkillComponent,\n type CompositionMode,\n type ExecutionOrder,\n} from \"./composer/index.js\";\n\nexport { isCompoundSkill } from \"./composer/types.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// Skill Validation\nexport {\n SkillValidator,\n createSkillValidator,\n type ValidationTestCase,\n type TestCaseResult,\n type SkillValidationResult,\n type ValidationRecommendation,\n type ValidationSchedule,\n type ValidatorConfig,\n type TestRunner,\n type CompatibilityCheckResult,\n type CompatibilityIssue,\n DEFAULT_VALIDATOR_CONFIG,\n} from \"./validation/index.js\";\n\n// Metrics and Analytics\nexport {\n MetricsTracker,\n createMetricsTracker,\n MemoryMetricsStorage,\n FileMetricsStorage,\n type UsageEvent,\n type FeedbackEvent,\n type SkillMetricsSnapshot,\n type UsageTrend,\n type SkillRanking,\n type UsageReport,\n type MetricsConfig,\n type MetricsStorage,\n DEFAULT_METRICS_CONFIG,\n} from \"./metrics/index.js\";\n\n// Hooks and Activation\nexport {\n // Types\n type HookEvent,\n type HookPriority,\n type BaseHookContext,\n type ExtractionHookContext,\n type QualityHookContext,\n type StorageHookContext,\n type SessionHookContext,\n type SkillHookContext,\n type HookContext,\n type HookResult,\n type HookHandler,\n type RegisteredHook,\n type ActivationTrigger,\n type ActivationConfig,\n type ActivationState,\n DEFAULT_ACTIVATION_CONFIG,\n\n // Registry\n HookRegistry,\n hookRegistry,\n type RegisterHookOptions,\n type HookExecutionResult,\n\n // Activation\n ActivationManager,\n createActivationManager,\n type ActivationCheckResult,\n type ActivationCallback,\n\n // Built-in hooks\n createLoggingHook,\n createExtractionValidationHook,\n createExtractionEnrichmentHook,\n createQualityLoggingHook,\n createQualityBypassHook,\n createBackupHook,\n createSaveValidationHook,\n createMetricsHook,\n combineHandlers,\n conditionalHook,\n} from \"./hooks/index.js\";\n\n// Serving\nexport {\n LoadoutCompiler,\n ViewRenderer,\n ProjectDetector,\n SkillGraphServer,\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 EvictionStrategy,\n type GraphServerConfig,\n type ServingEvent,\n type ServingEventHandler,\n type ViewRendererConfig,\n} from \"./serving/index.js\";\n\n// MCP Integration\nexport {\n // Adapter\n GitSyncAdapter,\n createGitSyncAdapter,\n type GitSyncAdapterOptions,\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// MCP Tools and Server\nexport {\n // Tool definitions\n loadoutListTool,\n loadoutSearchTool,\n loadoutAddTool,\n loadoutRemoveTool,\n loadoutProfileTool,\n loadoutSetTool,\n loadoutTools,\n skillExpandTool,\n skillCollapseTool,\n skillUseTool,\n skillGetTool,\n skillTools,\n allTools,\n getToolDefinition,\n getToolNames,\n type ToolDefinition,\n\n // Handlers\n createToolHandlers,\n executeToolCall,\n type ToolHandler,\n type ToolResult as McpToolResult,\n\n // Server\n SkillTreeMcpServer,\n createMcpServer,\n type McpServerConfig,\n} from \"./mcp/index.js\";\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 /** Storage type */\n type: 'sqlite' | 'filesystem' | 'memory';\n /** Path to storage (for sqlite and filesystem) */\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 * 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}\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};\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: SkillTreeConfig = {\n storage: {\n type: 'sqlite',\n path: '~/.skill-tree/skills.db',\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};\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_TYPE: 'storage.type',\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 type: sqlite\n path: ~/.skill-tree/skills.db\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`;\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 * list command - List all skills\n */\n\nimport { Command } from 'commander';\nimport type { SkillStatus } from '../../types.js';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { formatSkillLine, printError, printInfo } from '../utils/output.js';\nimport { getSkillPath } from '../utils/skillbank.js';\n\ninterface ListOptions extends GlobalOptions {\n status?: string;\n tag?: string;\n author?: string;\n}\n\nexport const listCommand = new Command('list')\n .description('List all skills')\n .option('-s, --status <status>', 'Filter by status (active, draft, deprecated, experimental)')\n .option('-t, --tag <tag>', 'Filter by tag')\n .option('-a, --author <author>', 'Filter by author')\n .action(async (options: ListOptions, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n\n // Build filter\n const filter: {\n status?: SkillStatus[];\n tags?: string[];\n author?: string;\n } = {};\n\n if (options.status) {\n filter.status = [options.status as SkillStatus];\n }\n if (options.tag) {\n filter.tags = [options.tag];\n }\n if (options.author) {\n filter.author = options.author;\n }\n\n const skills = await skillBank.listSkills(\n Object.keys(filter).length > 0 ? filter : undefined\n );\n\n if (globalOpts.json) {\n console.log(JSON.stringify(skills, null, 2));\n return;\n }\n\n if (skills.length === 0) {\n printInfo(`No skills found in ${getSkillPath(globalOpts)}`);\n return;\n }\n\n if (!globalOpts.quiet) {\n printInfo(`Skills in ${getSkillPath(globalOpts)}:\\n`);\n }\n\n for (const skill of skills) {\n console.log(formatSkillLine(skill));\n }\n\n if (!globalOpts.quiet) {\n console.log();\n printInfo(`${skills.length} skill(s)`);\n }\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * Path resolution for skill directories\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\n\n/**\n * Default skill directory search paths (in priority order)\n */\nconst DEFAULT_PATHS = [\n '.claude/skills', // Project local (Claude)\n '.agent/skills', // Project local (universal)\n '~/.claude/skills', // User global (Claude)\n '~/.agent/skills', // User global (universal)\n];\n\n/**\n * Expand ~ to home directory\n */\nfunction expandHome(p: string): string {\n if (p.startsWith('~/')) {\n return path.join(os.homedir(), p.slice(2));\n }\n return p;\n}\n\n/**\n * Check if a directory exists\n */\nfunction dirExists(p: string): boolean {\n try {\n return fs.statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the skill directory path\n *\n * Priority:\n * 1. Explicit --path flag\n * 2. SKILL_TREE_PATH environment variable\n * 3. First existing default path\n * 4. Create .claude/skills if nothing exists\n */\nexport function resolveSkillPath(explicitPath?: string): string {\n // 1. Explicit path takes priority\n if (explicitPath) {\n const resolved = expandHome(explicitPath);\n return path.resolve(resolved);\n }\n\n // 2. Environment variable\n const envPath = process.env.SKILL_TREE_PATH;\n if (envPath) {\n return path.resolve(expandHome(envPath));\n }\n\n // 3. Find first existing default path\n for (const defaultPath of DEFAULT_PATHS) {\n const resolved = path.resolve(expandHome(defaultPath));\n if (dirExists(resolved)) {\n return resolved;\n }\n }\n\n // 4. Default to .claude/skills (will be created if needed)\n return path.resolve('.claude/skills');\n}\n\n/**\n * Ensure a directory exists\n */\nexport function ensureDir(dir: string): void {\n if (!dirExists(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n}\n\n/**\n * Get all potential skill paths that exist\n */\nexport function findExistingSkillPaths(): string[] {\n const existing: string[] = [];\n\n for (const defaultPath of DEFAULT_PATHS) {\n const resolved = path.resolve(expandHome(defaultPath));\n if (dirExists(resolved)) {\n existing.push(resolved);\n }\n }\n\n return existing;\n}\n","/**\n * SkillBank initialization for CLI\n */\n\nimport { SkillBank } from '../../skill-bank.js';\nimport { resolveSkillPath, ensureDir } from './paths.js';\n\n/**\n * Global options passed to all commands\n */\nexport interface GlobalOptions {\n path?: string;\n json?: boolean;\n quiet?: boolean;\n}\n\n/**\n * Create and initialize a SkillBank from CLI options\n */\nexport async function createSkillBankFromOptions(options: GlobalOptions): Promise<SkillBank> {\n const skillPath = resolveSkillPath(options.path);\n\n // Ensure the directory exists\n ensureDir(skillPath);\n\n const skillBank = new SkillBank({\n storage: {\n type: 'filesystem',\n basePath: skillPath,\n openSkillsCompatible: true,\n },\n });\n\n await skillBank.initialize();\n\n return skillBank;\n}\n\n/**\n * Get the resolved skill path for display\n */\nexport function getSkillPath(options: GlobalOptions): string {\n return resolveSkillPath(options.path);\n}\n\n/**\n * Alias for createSkillBankFromOptions\n * Used by indexer commands for consistent naming\n */\nexport const getSkillBank = createSkillBankFromOptions;\n","/**\n * Output formatting utilities for CLI\n */\n\nimport chalk from 'chalk';\nimport type { Skill, SkillVersion, SkillBankStats } from '../../index.js';\n\n/**\n * Format a skill for list display (one line)\n */\nexport function formatSkillLine(skill: Skill): string {\n const status = formatStatus(skill.status);\n const version = chalk.dim(`v${skill.version}`);\n const id = chalk.bold(skill.id);\n const name = skill.name !== skill.id ? chalk.dim(` (${skill.name})`) : '';\n const tags = skill.tags.length > 0 ? chalk.dim(` [${skill.tags.join(', ')}]`) : '';\n\n return `${status} ${id}${name} ${version}${tags}`;\n}\n\n/**\n * Format status with color\n */\nexport function formatStatus(status: Skill['status']): string {\n switch (status) {\n case 'active':\n return chalk.green('●');\n case 'draft':\n return chalk.yellow('○');\n case 'deprecated':\n return chalk.red('✗');\n case 'experimental':\n return chalk.blue('◐');\n default:\n return chalk.gray('?');\n }\n}\n\n/**\n * Format full skill details\n */\nexport function formatSkillDetail(skill: Skill): string {\n const lines: string[] = [];\n\n // Header\n lines.push(chalk.bold(`${skill.name} v${skill.version}`));\n lines.push(chalk.dim('─'.repeat(50)));\n\n // Status & metadata\n lines.push(`${chalk.dim('Status:')} ${formatStatusLabel(skill.status)}`);\n lines.push(`${chalk.dim('Author:')} ${skill.author}`);\n if (skill.tags.length > 0) {\n lines.push(`${chalk.dim('Tags:')} ${skill.tags.join(', ')}`);\n }\n if (skill.parentVersion) {\n lines.push(`${chalk.dim('Parent:')} v${skill.parentVersion}`);\n }\n if (skill.derivedFrom && skill.derivedFrom.length > 0) {\n lines.push(`${chalk.dim('Derived:')} ${skill.derivedFrom.join(', ')}`);\n }\n\n // Metrics\n const { usageCount, successRate } = skill.metrics;\n if (usageCount > 0) {\n lines.push(`${chalk.dim('Usage:')} ${usageCount} times, ${Math.round(successRate * 100)}% success`);\n }\n\n lines.push('');\n\n // Description\n lines.push(chalk.dim('Description'));\n lines.push(chalk.dim('─'.repeat(50)));\n lines.push(skill.description);\n lines.push('');\n\n // Problem\n lines.push(chalk.dim('Problem'));\n lines.push(chalk.dim('─'.repeat(50)));\n lines.push(skill.problem);\n lines.push('');\n\n // Trigger conditions\n if (skill.triggerConditions.length > 0) {\n lines.push(chalk.dim('Trigger Conditions'));\n lines.push(chalk.dim('─'.repeat(50)));\n for (const trigger of skill.triggerConditions) {\n const desc = trigger.description ? ` - ${trigger.description}` : '';\n lines.push(` ${chalk.cyan(trigger.type)}: ${trigger.value}${chalk.dim(desc)}`);\n }\n lines.push('');\n }\n\n // Solution\n lines.push(chalk.dim('Solution'));\n lines.push(chalk.dim('─'.repeat(50)));\n lines.push(skill.solution);\n lines.push('');\n\n // Verification\n if (skill.verification) {\n lines.push(chalk.dim('Verification'));\n lines.push(chalk.dim('─'.repeat(50)));\n lines.push(skill.verification);\n lines.push('');\n }\n\n // Notes\n if (skill.notes) {\n lines.push(chalk.dim('Notes'));\n lines.push(chalk.dim('─'.repeat(50)));\n lines.push(skill.notes);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format status as full label\n */\nfunction formatStatusLabel(status: Skill['status']): string {\n switch (status) {\n case 'active':\n return chalk.green('active');\n case 'draft':\n return chalk.yellow('draft');\n case 'deprecated':\n return chalk.red('deprecated');\n case 'experimental':\n return chalk.blue('experimental');\n default:\n return chalk.gray(status);\n }\n}\n\n/**\n * Format version history\n */\nexport function formatVersionHistory(versions: SkillVersion[]): string {\n const lines: string[] = [];\n\n lines.push(chalk.bold('Version History'));\n lines.push(chalk.dim('─'.repeat(50)));\n\n for (const v of versions.reverse()) {\n const date = v.createdAt.toISOString().split('T')[0];\n const hash = chalk.dim(`#${v.contentHash.slice(0, 7)}`);\n const changelog = v.changelog ? ` - ${v.changelog}` : '';\n\n lines.push(` ${chalk.cyan(`v${v.version}`)} ${chalk.dim(date)} ${hash}${changelog}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format version diff\n */\nexport function formatDiff(\n versionA: string,\n versionB: string,\n changes: {\n modified: Array<{ field: string; oldValue: string; newValue: string }>;\n added: Array<{ type: string; value: string }>;\n removed: Array<{ type: string; value: string }>;\n }\n): string {\n const lines: string[] = [];\n\n lines.push(chalk.bold(`Diff: v${versionA} → v${versionB}`));\n lines.push(chalk.dim('─'.repeat(50)));\n\n if (changes.modified.length === 0 && changes.added.length === 0 && changes.removed.length === 0) {\n lines.push(chalk.dim('No changes'));\n return lines.join('\\n');\n }\n\n for (const mod of changes.modified) {\n lines.push(chalk.yellow(`~ ${mod.field}`));\n lines.push(chalk.red(` - ${truncate(mod.oldValue, 60)}`));\n lines.push(chalk.green(` + ${truncate(mod.newValue, 60)}`));\n }\n\n for (const add of changes.added) {\n lines.push(chalk.green(`+ ${add.type}: ${add.value}`));\n }\n\n for (const rem of changes.removed) {\n lines.push(chalk.red(`- ${rem.type}: ${rem.value}`));\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format statistics\n */\nexport function formatStats(stats: SkillBankStats): string {\n const lines: string[] = [];\n\n lines.push(chalk.bold('Skill Bank Statistics'));\n lines.push(chalk.dim('─'.repeat(50)));\n\n lines.push(`${chalk.dim('Total skills:')} ${stats.totalSkills}`);\n lines.push('');\n\n lines.push(chalk.dim('By Status:'));\n lines.push(` ${chalk.green('●')} Active: ${stats.byStatus.active}`);\n lines.push(` ${chalk.yellow('○')} Draft: ${stats.byStatus.draft}`);\n lines.push(` ${chalk.blue('◐')} Experimental: ${stats.byStatus.experimental}`);\n lines.push(` ${chalk.red('✗')} Deprecated: ${stats.byStatus.deprecated}`);\n lines.push('');\n\n if (Object.keys(stats.byTag).length > 0) {\n lines.push(chalk.dim('By Tag:'));\n const sortedTags = Object.entries(stats.byTag).sort((a, b) => b[1] - a[1]);\n for (const [tag, count] of sortedTags.slice(0, 10)) {\n lines.push(` ${tag}: ${count}`);\n }\n lines.push('');\n }\n\n if (stats.totalUsage > 0) {\n lines.push(chalk.dim('Usage:'));\n lines.push(` Total uses: ${stats.totalUsage}`);\n lines.push(` Avg success: ${Math.round(stats.avgSuccessRate * 100)}%`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Print error message\n */\nexport function printError(message: string): void {\n console.error(chalk.red(`Error: ${message}`));\n}\n\n/**\n * Print success message\n */\nexport function printSuccess(message: string): void {\n console.log(chalk.green(`✓ ${message}`));\n}\n\n/**\n * Print warning message\n */\nexport function printWarning(message: string): void {\n console.log(chalk.yellow(`⚠ ${message}`));\n}\n\n/**\n * Print info message\n */\nexport function printInfo(message: string): void {\n console.log(chalk.dim(message));\n}\n\n/**\n * Truncate text\n */\nfunction truncate(text: string, maxLength: number): string {\n const oneLine = text.replace(/\\n/g, ' ');\n if (oneLine.length <= maxLength) return oneLine;\n return oneLine.slice(0, maxLength - 3) + '...';\n}\n","/**\n * show command - Show skill details\n */\n\nimport { Command } from 'commander';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { formatSkillDetail, printError } from '../utils/output.js';\n\ninterface ShowOptions extends GlobalOptions {\n version?: string;\n}\n\nexport const showCommand = new Command('show')\n .description('Show skill details')\n .argument('<id>', 'Skill ID')\n .option('-v, --version <version>', 'Show specific version')\n .action(async (id: string, options: ShowOptions, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const skill = await skillBank.getSkill(id, options.version);\n\n if (!skill) {\n printError(`Skill not found: ${id}${options.version ? `@${options.version}` : ''}`);\n process.exit(1);\n }\n\n if (globalOpts.json) {\n console.log(JSON.stringify(skill, null, 2));\n return;\n }\n\n console.log(formatSkillDetail(skill));\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * search command - Search skills by text\n */\n\nimport { Command } from 'commander';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { formatSkillLine, printError, printInfo } from '../utils/output.js';\n\nexport const searchCommand = new Command('search')\n .description('Search skills by text')\n .argument('<query>', 'Search query')\n .action(async (query: string, options: unknown, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const skills = await skillBank.searchSkills(query);\n\n if (globalOpts.json) {\n console.log(JSON.stringify(skills, null, 2));\n return;\n }\n\n if (skills.length === 0) {\n printInfo(`No skills found matching \"${query}\"`);\n return;\n }\n\n if (!globalOpts.quiet) {\n printInfo(`Results for \"${query}\":\\n`);\n }\n\n for (const skill of skills) {\n console.log(formatSkillLine(skill));\n }\n\n if (!globalOpts.quiet) {\n console.log();\n printInfo(`${skills.length} result(s)`);\n }\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * stats command - Show skill bank statistics\n */\n\nimport { Command } from 'commander';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { formatStats, printError } from '../utils/output.js';\n\nexport const statsCommand = new Command('stats')\n .description('Show skill bank statistics')\n .action(async (options: unknown, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const stats = await skillBank.getStats();\n\n if (globalOpts.json) {\n console.log(JSON.stringify(stats, null, 2));\n return;\n }\n\n console.log(formatStats(stats));\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * versions command - Show version history\n */\n\nimport { Command } from 'commander';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { formatVersionHistory, printError, printInfo } from '../utils/output.js';\n\nexport const versionsCommand = new Command('versions')\n .description('Show version history for a skill')\n .argument('<id>', 'Skill ID')\n .action(async (id: string, options: unknown, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const versions = await skillBank.getVersionHistory(id);\n\n if (versions.length === 0) {\n printInfo(`No version history found for: ${id}`);\n return;\n }\n\n if (globalOpts.json) {\n console.log(JSON.stringify(versions, null, 2));\n return;\n }\n\n console.log(formatVersionHistory(versions));\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * diff command - Compare two versions\n */\n\nimport { Command } from 'commander';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { formatDiff, printError } from '../utils/output.js';\n\nexport const diffCommand = new Command('diff')\n .description('Compare two versions of a skill')\n .argument('<id>', 'Skill ID')\n .argument('<version-a>', 'First version')\n .argument('<version-b>', 'Second version')\n .action(async (id: string, versionA: string, versionB: string, options: unknown, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const diff = await skillBank.compareVersions(id, versionA, versionB);\n\n if (globalOpts.json) {\n console.log(JSON.stringify(diff, null, 2));\n return;\n }\n\n console.log(formatDiff(diff.versionA, diff.versionB, diff.changes));\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * rollback command - Rollback to a previous version\n */\n\nimport { Command } from 'commander';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { printError, printSuccess } from '../utils/output.js';\n\ninterface RollbackOptions extends GlobalOptions {\n to: string;\n}\n\nexport const rollbackCommand = new Command('rollback')\n .description('Rollback a skill to a previous version')\n .argument('<id>', 'Skill ID')\n .requiredOption('--to <version>', 'Version to rollback to')\n .action(async (id: string, options: RollbackOptions, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const skill = await skillBank.rollbackSkill(id, options.to);\n\n if (globalOpts.json) {\n console.log(JSON.stringify(skill, null, 2));\n return;\n }\n\n printSuccess(`Rolled back ${id} to v${options.to} (new version: v${skill.version})`);\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * fork command - Fork a skill to create a variant\n */\n\nimport { Command } from 'commander';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { printError, printSuccess } from '../utils/output.js';\n\ninterface ForkOptions extends GlobalOptions {\n newId: string;\n reason: string;\n name?: string;\n fromVersion?: string;\n}\n\nexport const forkCommand = new Command('fork')\n .description('Fork a skill to create a variant')\n .argument('<id>', 'Skill ID to fork from')\n .requiredOption('--new-id <id>', 'ID for the new forked skill')\n .requiredOption('--reason <reason>', 'Reason for forking')\n .option('--name <name>', 'Name for the forked skill')\n .option('--from-version <version>', 'Version to fork from (defaults to latest)')\n .action(async (id: string, options: ForkOptions, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const forked = await skillBank.forkSkill(id, {\n newId: options.newId,\n newName: options.name,\n reason: options.reason,\n fromVersion: options.fromVersion,\n });\n\n if (globalOpts.json) {\n console.log(JSON.stringify(forked, null, 2));\n return;\n }\n\n printSuccess(`Forked ${id} → ${forked.id} (v${forked.version})`);\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * deprecate command - Mark skill as deprecated\n */\n\nimport { Command } from 'commander';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { printError, printSuccess } from '../utils/output.js';\n\nexport const deprecateCommand = new Command('deprecate')\n .description('Mark a skill as deprecated')\n .argument('<id>', 'Skill ID')\n .action(async (id: string, options: unknown, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const skill = await skillBank.deprecateSkill(id);\n\n if (globalOpts.json) {\n console.log(JSON.stringify(skill, null, 2));\n return;\n }\n\n printSuccess(`Deprecated: ${id} (v${skill.version})`);\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * activate command - Mark skill as active\n */\n\nimport { Command } from 'commander';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { printError, printSuccess } from '../utils/output.js';\n\nexport const activateCommand = new Command('activate')\n .description('Mark a skill as active')\n .argument('<id>', 'Skill ID')\n .action(async (id: string, options: unknown, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const skill = await skillBank.getSkill(id);\n\n if (!skill) {\n printError(`Skill not found: ${id}`);\n process.exit(1);\n }\n\n skill.status = 'active';\n skill.updatedAt = new Date();\n await skillBank.saveSkill(skill);\n\n if (globalOpts.json) {\n console.log(JSON.stringify(skill, null, 2));\n return;\n }\n\n printSuccess(`Activated: ${id} (v${skill.version})`);\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * delete command - Delete a skill\n */\n\nimport { Command } from 'commander';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { printError, printSuccess, printWarning } from '../utils/output.js';\n\ninterface DeleteOptions extends GlobalOptions {\n force?: boolean;\n version?: string;\n}\n\nexport const deleteCommand = new Command('delete')\n .description('Delete a skill')\n .argument('<id>', 'Skill ID')\n .option('-f, --force', 'Skip confirmation')\n .option('-v, --version <version>', 'Delete specific version only')\n .action(async (id: string, options: DeleteOptions, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n\n // Check if skill exists\n const skill = await skillBank.getSkill(id, options.version);\n if (!skill) {\n printError(`Skill not found: ${id}${options.version ? `@${options.version}` : ''}`);\n process.exit(1);\n }\n\n if (!options.force) {\n printWarning(`This will permanently delete ${id}${options.version ? `@${options.version}` : ' and all versions'}`);\n printWarning('Use --force to confirm');\n process.exit(1);\n }\n\n const deleted = await skillBank.deleteSkill(id, options.version);\n\n if (!deleted) {\n printError(`Failed to delete: ${id}`);\n process.exit(1);\n }\n\n if (globalOpts.json) {\n console.log(JSON.stringify({ deleted: true, id, version: options.version }));\n return;\n }\n\n printSuccess(`Deleted: ${id}${options.version ? `@${options.version}` : ''}`);\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * export command - Export all skills to JSON\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { printError, printSuccess, printInfo } from '../utils/output.js';\n\ninterface ExportOptions extends GlobalOptions {\n output?: string;\n}\n\nexport const exportCommand = new Command('export')\n .description('Export all skills to JSON')\n .option('-o, --output <file>', 'Output file path (defaults to stdout)')\n .action(async (options: ExportOptions, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const skills = await skillBank.exportAll();\n\n const json = JSON.stringify(skills, null, 2);\n\n if (options.output) {\n fs.writeFileSync(options.output, json, 'utf-8');\n if (!globalOpts.quiet) {\n printSuccess(`Exported ${skills.length} skill(s) to ${options.output}`);\n }\n } else {\n console.log(json);\n }\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n","/**\n * import command - Import skills from JSON\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport type { Skill } from '../../types.js';\nimport { createSkillBankFromOptions, type GlobalOptions } from '../utils/skillbank.js';\nimport { printError, printSuccess, printWarning, printInfo } from '../utils/output.js';\nimport { parseIndexerExport, isLikelyIndexerFormat } from '../../import/index.js';\n\nexport const importCommand = new Command('import')\n .description('Import skills from JSON file')\n .argument('<file>', 'JSON file to import')\n .option('--from-indexer', 'Import from skill-indexer export format')\n .option('--auto-detect', 'Auto-detect format (default: true)', true)\n .action(async (file: string, options: { fromIndexer?: boolean; autoDetect?: boolean }, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n // Read and parse file\n if (!fs.existsSync(file)) {\n printError(`File not found: ${file}`);\n process.exit(1);\n }\n\n const content = fs.readFileSync(file, 'utf-8');\n let skills: Skill[];\n\n // Determine if this is an indexer export\n const isIndexerFormat = options.fromIndexer || (options.autoDetect !== false && isLikelyIndexerFormat(content));\n\n if (isIndexerFormat) {\n // Convert from indexer format\n if (!globalOpts.quiet) {\n printInfo('Detected skill-indexer format, converting...');\n }\n\n try {\n const { skills: converted, stats, exportMetadata } = parseIndexerExport(content);\n skills = converted;\n\n if (!globalOpts.quiet) {\n printInfo(`Converted ${stats.total} skills (${stats.withStructuredContent} with structured content)`);\n if (exportMetadata) {\n printInfo(`Original export from: ${exportMetadata.exportedAt}`);\n }\n }\n } catch (err) {\n printError(`Failed to parse indexer export: ${(err as Error).message}`);\n process.exit(1);\n }\n } else {\n // Standard skill-tree format\n try {\n const parsed = JSON.parse(content);\n skills = Array.isArray(parsed) ? parsed : [parsed];\n } catch {\n printError('Invalid JSON file');\n process.exit(1);\n }\n\n // Restore date objects for skill-tree format\n for (const skill of skills) {\n skill.createdAt = new Date(skill.createdAt);\n skill.updatedAt = new Date(skill.updatedAt);\n if (skill.metrics.lastUsed) {\n skill.metrics.lastUsed = new Date(skill.metrics.lastUsed);\n }\n if (skill.source?.importedAt) {\n skill.source.importedAt = new Date(skill.source.importedAt);\n }\n if (skill.externalSource?.scrapedAt) {\n skill.externalSource.scrapedAt = new Date(skill.externalSource.scrapedAt);\n }\n }\n }\n\n const skillBank = await createSkillBankFromOptions(globalOpts);\n const result = await skillBank.importSkills(skills);\n\n if (globalOpts.json) {\n console.log(JSON.stringify({\n ...result,\n format: isIndexerFormat ? 'indexer' : 'skill-tree',\n }, null, 2));\n return;\n }\n\n printSuccess(`Imported ${result.imported} skill(s)`);\n if (result.failed > 0) {\n printWarning(`Failed to import ${result.failed} skill(s)`);\n }\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\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, TriggerCondition, SkillExample } 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 * Parsed markdown sections from skill content\n */\ninterface MarkdownSections {\n problem?: string;\n solution?: string;\n verification?: string;\n examples?: SkillExample[];\n notes?: string;\n triggers?: string[];\n remainingContent: string;\n}\n\n/**\n * Default section patterns for markdown parsing\n */\nconst DEFAULT_SECTION_PATTERNS = {\n problem: [\n /^#+\\s*(?:problem|issue|what\\s+problem|the\\s+problem)/i,\n /^#+\\s*(?:why|motivation|background)/i,\n ],\n solution: [\n /^#+\\s*(?:solution|how\\s+to|implementation|approach)/i,\n /^#+\\s*(?:usage|instructions|steps)/i,\n ],\n verification: [\n /^#+\\s*(?:verification|verify|testing|test|validate)/i,\n /^#+\\s*(?:how\\s+to\\s+verify|checking)/i,\n ],\n examples: [\n /^#+\\s*(?:examples?|sample|demo)/i,\n /^#+\\s*(?:use\\s+cases?|scenarios?)/i,\n ],\n notes: [\n /^#+\\s*(?:notes?|caveats?|warnings?|tips?)/i,\n /^#+\\s*(?:additional|edge\\s+cases?|considerations?)/i,\n ],\n triggers: [\n /^#+\\s*(?:triggers?|when\\s+to\\s+use|conditions?)/i,\n /^#+\\s*(?:activation|applies\\s+when)/i,\n ],\n};\n\n/**\n * Parse markdown content into structured sections\n */\nfunction parseMarkdownSections(content: string): MarkdownSections {\n const lines = content.split('\\n');\n const sections: MarkdownSections = {\n remainingContent: '',\n };\n\n let currentSection: keyof typeof DEFAULT_SECTION_PATTERNS | 'remaining' = 'remaining';\n let currentContent: string[] = [];\n\n const flushSection = () => {\n const text = currentContent.join('\\n').trim();\n if (!text) return;\n\n switch (currentSection) {\n case 'problem':\n sections.problem = text;\n break;\n case 'solution':\n sections.solution = text;\n break;\n case 'verification':\n sections.verification = text;\n break;\n case 'examples':\n sections.examples = parseExamples(text);\n break;\n case 'notes':\n sections.notes = text;\n break;\n case 'triggers':\n sections.triggers = parseTriggerList(text);\n break;\n case 'remaining':\n sections.remainingContent += (sections.remainingContent ? '\\n\\n' : '') + text;\n break;\n }\n currentContent = [];\n };\n\n for (const line of lines) {\n let matchedSection: keyof typeof DEFAULT_SECTION_PATTERNS | null = null;\n\n for (const [section, sectionPatterns] of Object.entries(DEFAULT_SECTION_PATTERNS)) {\n for (const pattern of sectionPatterns) {\n if (pattern.test(line)) {\n matchedSection = section as keyof typeof DEFAULT_SECTION_PATTERNS;\n break;\n }\n }\n if (matchedSection) break;\n }\n\n if (matchedSection) {\n flushSection();\n currentSection = matchedSection;\n } else {\n currentContent.push(line);\n }\n }\n\n flushSection();\n return sections;\n}\n\n/**\n * Parse examples from a text block\n */\nfunction parseExamples(text: string): SkillExample[] {\n const examples: SkillExample[] = [];\n const exampleBlocks = text.split(/^###\\s+/m).filter(Boolean);\n\n for (const block of exampleBlocks) {\n const lines = block.split('\\n');\n const scenario = lines[0]?.trim() || 'Example';\n const content = lines.slice(1).join('\\n');\n\n const beforeMatch = content.match(/(?:before|input|given)[:\\s]*\\n?([\\s\\S]*?)(?=(?:after|output|then|result)|$)/i);\n const afterMatch = content.match(/(?:after|output|then|result)[:\\s]*\\n?([\\s\\S]*?)$/i);\n\n if (beforeMatch || afterMatch) {\n examples.push({\n scenario,\n before: beforeMatch?.[1]?.trim() || '',\n after: afterMatch?.[1]?.trim() || content.trim(),\n });\n } else {\n examples.push({\n scenario,\n before: '',\n after: content.trim(),\n });\n }\n }\n\n if (examples.length === 0 && text.trim()) {\n examples.push({\n scenario: 'Example usage',\n before: '',\n after: text.trim(),\n });\n }\n\n return examples;\n}\n\n/**\n * Parse a list of trigger conditions from text\n */\nfunction parseTriggerList(text: string): string[] {\n const triggers: string[] = [];\n const listItems = text.match(/^[\\s]*[-*•]\\s*(.+)$/gm) ||\n text.match(/^[\\s]*\\d+\\.\\s*(.+)$/gm);\n\n if (listItems) {\n for (const item of listItems) {\n const cleaned = item.replace(/^[\\s]*[-*•\\d.]+\\s*/, '').trim();\n if (cleaned) triggers.push(cleaned);\n }\n } else {\n triggers.push(...text.split('\\n').map(t => t.trim()).filter(Boolean));\n }\n\n return triggers;\n}\n\n/**\n * Infer trigger type from text\n */\nfunction inferTriggerType(text: string): TriggerCondition {\n const lower = text.toLowerCase();\n\n if (lower.includes('error') || lower.includes('exception') || lower.includes('fail')) {\n return { type: 'error', value: text, description: 'Triggered by error conditions' };\n }\n\n if (lower.includes('pattern') || lower.includes('regex') || lower.includes('match')) {\n return { type: 'pattern', value: text };\n }\n\n if (lower.includes('when') || lower.includes('context') || lower.includes('if ')) {\n return { type: 'context', value: text };\n }\n\n return { type: 'keyword', value: text };\n}\n\n/**\n * Extract relevant keywords from description\n */\nfunction extractKeywordsFromDescription(description: string): string[] {\n const keywords: string[] = [];\n const techPatterns = [\n /\\b(react|vue|angular|svelte|next\\.?js|nuxt)\\b/gi,\n /\\b(node\\.?js|deno|bun|python|rust|go|java|typescript|javascript)\\b/gi,\n /\\b(docker|kubernetes|k8s|aws|gcp|azure)\\b/gi,\n /\\b(git|github|gitlab|npm|yarn|pnpm)\\b/gi,\n /\\b(sql|postgres|mysql|mongodb|redis)\\b/gi,\n /\\b(api|rest|graphql|grpc)\\b/gi,\n /\\b(test|testing|jest|vitest|pytest)\\b/gi,\n ];\n\n for (const pattern of techPatterns) {\n const matches = description.match(pattern);\n if (matches) {\n keywords.push(...matches.map(m => m.toLowerCase()));\n }\n }\n\n return [...new Set(keywords)];\n}\n\n/**\n * Extract trigger conditions from skill\n */\nfunction extractTriggerConditions(skill: IndexerSkill, sections?: MarkdownSections): TriggerCondition[] {\n const conditions: TriggerCondition[] = [];\n\n if (sections?.triggers) {\n for (const trigger of sections.triggers) {\n conditions.push(inferTriggerType(trigger));\n }\n }\n\n const keywords = extractKeywordsFromDescription(skill.description);\n for (const keyword of keywords) {\n if (!conditions.some(c => c.value.toLowerCase() === keyword.toLowerCase())) {\n conditions.push({\n type: 'keyword',\n value: keyword,\n description: 'Keyword from description',\n });\n }\n }\n\n if (skill.tags) {\n for (const tag of skill.tags.slice(0, 5)) {\n if (!conditions.some(c => c.value.toLowerCase() === tag.toLowerCase())) {\n conditions.push({\n type: 'keyword',\n value: tag,\n description: 'Tag from classification',\n });\n }\n }\n }\n\n if (conditions.length === 0) {\n conditions.push({\n type: 'context',\n value: skill.description.substring(0, 100),\n description: 'Generated from skill description',\n });\n }\n\n return conditions;\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 // Parse structured sections from content\n const sections = parseMarkdownSections(indexerSkill.content);\n const hasStructuredContent = !!(\n sections.problem ||\n sections.solution ||\n sections.verification ||\n sections.examples?.length\n );\n\n if (!hasStructuredContent) {\n warnings.push('No structured content sections found, using raw content');\n }\n\n // Extract trigger conditions\n const triggerConditions = extractTriggerConditions(indexerSkill, sections);\n\n // Build examples array\n let examples: SkillExample[] = sections.examples || [];\n if (examples.length === 0) {\n examples = [{\n scenario: 'Usage example',\n before: '',\n after: indexerSkill.content.substring(0, 500),\n }];\n warnings.push('No examples found, created placeholder');\n }\n\n // Determine problem/solution/verification\n const problem = sections.problem || indexerSkill.description;\n const solution = sections.solution || indexerSkill.content;\n const verification = sections.verification || 'Verify the skill output meets expectations';\n\n if (!sections.problem) warnings.push('No problem section found, using description');\n if (!sections.solution) warnings.push('No solution section found, using full content');\n if (!sections.verification) warnings.push('No verification section found, using default');\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 // Build notes with classification info\n let notes = sections.notes || undefined;\n if (indexerSkill.classificationReasoning) {\n const classificationNote = `\\n\\n---\\nClassification: ${indexerSkill.primaryPath?.join(' > ') || 'uncategorized'}\\nReasoning: ${indexerSkill.classificationReasoning}`;\n notes = (notes || '') + classificationNote;\n }\n\n const skill: Skill = {\n id: indexerSkill.slug,\n name: indexerSkill.displayName || indexerSkill.name,\n version: indexerSkill.version,\n description: indexerSkill.description,\n problem,\n triggerConditions,\n solution,\n verification,\n examples,\n notes,\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","/**\n * Format detection for skill imports\n */\n\nimport type { IndexerSkill, IndexerExport } from './converter.js';\n\n/**\n * Detected format types\n */\nexport type ImportFormat = 'skill-tree' | 'indexer' | 'indexer-export' | 'unknown';\n\n/**\n * Detection result\n */\nexport interface FormatDetectionResult {\n format: ImportFormat;\n confidence: number;\n details?: string;\n}\n\n/**\n * Check if object looks like a skill-tree Skill\n */\nfunction isSkillTreeSkill(obj: unknown): boolean {\n if (typeof obj !== 'object' || obj === null) return false;\n const skill = obj as Record<string, unknown>;\n\n // Required skill-tree fields\n return (\n typeof skill.id === 'string' &&\n typeof skill.name === 'string' &&\n typeof skill.version === 'string' &&\n typeof skill.problem === 'string' &&\n typeof skill.solution === 'string' &&\n Array.isArray(skill.triggerConditions) &&\n typeof skill.metrics === 'object'\n );\n}\n\n/**\n * Check if object looks like an indexer skill\n */\nfunction isIndexerSkill(obj: unknown): boolean {\n if (typeof obj !== 'object' || obj === null) return false;\n const skill = obj as Record<string, unknown>;\n\n // Indexer-specific fields\n return (\n typeof skill.slug === 'string' &&\n typeof skill.sourceRepo === 'string' &&\n typeof skill.sourcePath === 'string' &&\n typeof skill.sourceUrl === 'string' &&\n typeof skill.content === 'string' &&\n typeof skill.scrapedAt === 'string' &&\n (skill.status === 'raw' || skill.status === 'indexed' || skill.status === 'failed')\n );\n}\n\n/**\n * Check if object is an indexer export wrapper\n */\nfunction isIndexerExport(obj: unknown): boolean {\n if (typeof obj !== 'object' || obj === null) return false;\n const exp = obj as Record<string, unknown>;\n\n return (\n typeof exp.exportedAt === 'string' &&\n Array.isArray(exp.skills)\n );\n}\n\n/**\n * Detect the format of parsed JSON content\n */\nexport function detectFormat(data: unknown): FormatDetectionResult {\n // Handle arrays\n if (Array.isArray(data)) {\n if (data.length === 0) {\n return { format: 'unknown', confidence: 0, details: 'Empty array' };\n }\n\n const first = data[0];\n\n // Check indexer format first (more specific)\n if (isIndexerSkill(first)) {\n return { format: 'indexer', confidence: 0.95, details: 'Array of indexer skills' };\n }\n\n // Check skill-tree format\n if (isSkillTreeSkill(first)) {\n return { format: 'skill-tree', confidence: 0.95, details: 'Array of skill-tree skills' };\n }\n\n return { format: 'unknown', confidence: 0.3, details: 'Array of unknown objects' };\n }\n\n // Handle objects\n if (typeof data === 'object' && data !== null) {\n // Check indexer export wrapper\n if (isIndexerExport(data)) {\n return { format: 'indexer-export', confidence: 0.98, details: 'Indexer export with metadata' };\n }\n\n // Single skill\n if (isIndexerSkill(data)) {\n return { format: 'indexer', confidence: 0.9, details: 'Single indexer skill' };\n }\n\n if (isSkillTreeSkill(data)) {\n return { format: 'skill-tree', confidence: 0.9, details: 'Single skill-tree skill' };\n }\n }\n\n return { format: 'unknown', confidence: 0, details: 'Unrecognized format' };\n}\n\n/**\n * Detect format from raw JSON string\n */\nexport function detectFormatFromString(content: string): FormatDetectionResult {\n try {\n const data = JSON.parse(content);\n return detectFormat(data);\n } catch {\n return { format: 'unknown', confidence: 0, details: 'Invalid JSON' };\n }\n}\n\n/**\n * Check if content is likely an indexer export (for CLI auto-detection)\n */\nexport function isLikelyIndexerFormat(content: string): boolean {\n const result = detectFormatFromString(content);\n return result.format === 'indexer' || result.format === 'indexer-export';\n}\n","/**\n * Indexer command group - skill discovery and classification\n */\n\nimport { Command } from 'commander';\nimport { scrapeCommand } from './scrape.js';\nimport { classifyCommand } from './classify.js';\nimport { taxonomyCommand } from './taxonomy.js';\nimport { relationshipsCommand } from './relationships.js';\nimport { indexerStatsCommand } from './stats.js';\nimport { syncCommand } from './sync.js';\n\nexport const indexerCommand = new Command('index')\n .description('Skill indexer - discover and classify skills from GitHub')\n .addCommand(scrapeCommand)\n .addCommand(classifyCommand)\n .addCommand(taxonomyCommand)\n .addCommand(relationshipsCommand)\n .addCommand(indexerStatsCommand)\n .addCommand(syncCommand);\n","/**\n * scrape command - Discover skills from GitHub sources\n */\n\nimport { Command } from 'commander';\nimport { spawn } from 'child_process';\nimport { printError, printInfo, printSuccess, printWarning } from '../../utils/output.js';\nimport type { GlobalOptions } from '../../utils/skillbank.js';\nimport { getSkillBank } from '../../utils/skillbank.js';\nimport { IndexerService, createIntegratedIndexer, type SkillSource } from '../../../services/indexer.js';\n\nexport const scrapeCommand = new Command('scrape')\n .description('Scrape skills from GitHub sources')\n .argument('[url]', 'Repository or awesome-list URL')\n .option('-d, --discover', 'Discover from default sources')\n .option('-f, --force', 'Force scrape even if no changes detected')\n .option('--standalone', 'Use standalone skillindexer CLI (fallback)')\n .option('--import', 'Auto-import scraped skills into skill-tree', true)\n .action(async (url: string | undefined, options: {\n discover?: boolean;\n force?: boolean;\n standalone?: boolean;\n import?: boolean;\n }, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n // If standalone mode or no URL and no discover flag, use subprocess\n if (options.standalone) {\n await runStandaloneMode(url, options, globalOpts);\n return;\n }\n\n // Try to use integrated IndexerService\n try {\n const skillBank = await getSkillBank(globalOpts);\n const indexer = createIntegratedIndexer(skillBank, {\n githubToken: process.env.GITHUB_TOKEN,\n anthropicApiKey: process.env.ANTHROPIC_API_KEY,\n });\n\n // Determine sources\n let sources: SkillSource[];\n if (url) {\n sources = [{\n type: url.includes('awesome') ? 'awesome-list' : 'repository',\n url,\n }];\n } else if (options.discover) {\n sources = indexer.getDefaultSources();\n } else {\n printError('Please provide a URL or use --discover to scrape from default sources');\n process.exit(1);\n }\n\n if (!globalOpts.quiet) {\n printInfo(`Scraping ${sources.length} source(s)...`);\n for (const source of sources) {\n printInfo(` - ${source.url} (${source.type})`);\n }\n printInfo('');\n }\n\n // Run the scrape\n const result = await indexer.scrape(sources, { force: options.force });\n\n // Output results\n if (globalOpts.json) {\n console.log(JSON.stringify(result, null, 2));\n } else if (!globalOpts.quiet) {\n printSuccess('Scrape completed');\n console.log(` Discovered: ${result.discovered}`);\n console.log(` Scraped: ${result.scraped}`);\n console.log(` Unchanged: ${result.unchanged}`);\n console.log(` Skipped: ${result.skipped}`);\n console.log(` Failed: ${result.failed}`);\n\n if (result.errors.length > 0) {\n printWarning('\\nErrors:');\n for (const error of result.errors) {\n console.log(` - ${error}`);\n }\n }\n }\n\n // Auto-import if requested\n if (options.import && result.scraped > 0) {\n if (!globalOpts.quiet) {\n printInfo('\\nImporting scraped skills into skill-tree...');\n }\n\n try {\n const importResult = await indexer.importFromIndexerDb({ status: 'indexed' });\n\n if (!globalOpts.quiet) {\n printSuccess(`Imported ${importResult.imported} skills`);\n if (importResult.failed > 0) {\n printWarning(`Failed to import ${importResult.failed} skills`);\n }\n }\n } catch (err) {\n printWarning(`Auto-import failed: ${(err as Error).message}`);\n printInfo('You can manually import with: skill-tree import');\n }\n }\n\n await indexer.close();\n } catch (err) {\n const errorMessage = (err as Error).message;\n\n // If the service isn't available, fall back to subprocess\n if (errorMessage.includes('Scraper not available') || errorMessage.includes('not found')) {\n printWarning('IndexerService not available, falling back to standalone CLI...');\n await runStandaloneMode(url, options, globalOpts);\n return;\n }\n\n printError(errorMessage);\n process.exit(1);\n }\n });\n\n/**\n * Run in standalone mode using the skillindexer CLI subprocess\n */\nasync function runStandaloneMode(\n url: string | undefined,\n options: { discover?: boolean; force?: boolean },\n globalOpts: GlobalOptions\n): Promise<void> {\n if (!globalOpts.quiet) {\n printInfo('Using standalone skillindexer CLI...');\n printInfo('');\n }\n\n const args = ['scrape'];\n if (url) args.push(url);\n if (options.discover) args.push('--discover');\n if (options.force) args.push('--force');\n\n try {\n await runSkillIndexer(args, globalOpts.quiet ?? false);\n } catch (err) {\n printError((err as Error).message);\n printWarning('');\n printWarning('If skillindexer is not installed, you can:');\n printWarning(' 1. cd scraper && npm install && npm run build');\n printWarning(' 2. npm link (in scraper directory)');\n printWarning('');\n printWarning('Or use the export/import workflow:');\n printWarning(' skillindexer scrape --discover');\n printWarning(' skillindexer export-skilltree -o skills.json');\n printWarning(' skill-tree import skills.json');\n process.exit(1);\n }\n}\n\n/**\n * Run the skillindexer CLI as a subprocess\n */\nasync function runSkillIndexer(args: string[], quiet: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const proc = spawn('skillindexer', args, {\n stdio: quiet ? 'pipe' : 'inherit',\n shell: true,\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to run skillindexer: ${err.message}`));\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`skillindexer exited with code ${code}`));\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 { Skill, SkillRelationship, SkillTaxonomy, StorageAdapter } 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, targetId: string, type: string,\n confidence: number, 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 typeof s.addRelationship === 'function' && typeof s.getTaxonomyTree === 'function';\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}\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: config.anthropicApiKey || this.globalConfig.indexer.anthropic_key,\n batchSize: config.batchSize || this.globalConfig.indexer.batch_size,\n minConfidence: 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 };\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 // Try to find scraper modules in various locations\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 ? path.resolve(this.serviceConfig.cacheDir, '../scraper/dist') : 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('Scraper modules not found. Run `cd scraper && npm run build` first.');\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(/* webpackIgnore: true */ databasePath);\n\n // Initialize database connection\n if (this.databaseModule.createDatabase) {\n const dbPath = 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(sources: SkillSource[], options?: { force?: boolean }): 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(`Failed to save skill ${skill.slug}: ${(err as Error).message}`);\n }\n }\n } catch (err) {\n result.failed++;\n result.errors.push(`Failed to scrape ${source.url}: ${(err as Error).message}`);\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?: { skillId?: string; all?: boolean }): 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(`Failed to classify ${skill.slug}: ${(err as Error).message}`);\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?: { skillId?: string; useAi?: boolean }): 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(`Relationship detection failed: ${(err as Error).message}`);\n }\n\n return result;\n }\n\n // Fallback to scraper module\n if (!this.db) {\n throw new Error(\n 'Neither SkillBank nor scraper database available.'\n );\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(`Relationship detection failed: ${(err as Error).message}`);\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 = `${skill.name} ${skill.description} ${skill.problem || ''} ${skill.solution || ''} ${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 = ['requires', 'depends on', 'uses', 'needs', 'builds on'];\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 = ['extends', 'improves', 'enhances', 'builds upon'];\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 = ['alternative to', 'instead of', 'replacement for'];\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) => this.convertToTaxonomyNode(child)),\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(skills: 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 const nodeMap = new Map<string, TaxonomyNode>();\n\n for (const skill of skills) {\n const taxonomy = skill.taxonomy || (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(s =>\n s.status === 'active' && (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 }\n ): Promise<{\n scraped: ScrapeResult;\n indexed: IndexResult;\n relationships: RelationshipResult;\n skillsAdded: string[];\n }> {\n if (!this.skillBank) {\n throw new Error('SkillBank required for scrapeAndIndex. Use integrated mode.');\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 = { indexed: 0, skipped: 0, failed: 0, errors: [] };\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 = this.db.getAllSkills?.() || [];\n for (const skill of skills) {\n if (skill.status !== 'indexed' && !options?.force) continue;\n\n try {\n const converted = convertIndexerSkill(skill as IndexerSkill);\n await this.skillBank.addSkill(converted.skill);\n skillsAdded.push(converted.skill.id);\n } catch (err) {\n indexed.errors.push(`Failed to import ${skill.slug}: ${(err as Error).message}`);\n }\n }\n }\n\n // Step 4: Detect relationships if requested\n let relationships: RelationshipResult = { detected: 0, skipped: 0, errors: [] };\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.addSkill(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 { type: 'awesome-list', url: 'https://github.com/VoltAgent/awesome-agent-skills' },\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 * classify command - Classify skills using AI\n */\n\nimport { Command } from 'commander';\nimport { spawn } from 'child_process';\nimport { printError, printInfo, printSuccess, printWarning } from '../../utils/output.js';\nimport type { GlobalOptions } from '../../utils/skillbank.js';\nimport { getSkillBank } from '../../utils/skillbank.js';\nimport { createIntegratedIndexer } from '../../../services/indexer.js';\n\nexport const classifyCommand = new Command('classify')\n .description('Classify unindexed skills using AI')\n .option('-s, --skill <id>', 'Classify specific skill by ID')\n .option('--all', 'Re-classify all skills (including already indexed)')\n .option('--standalone', 'Use standalone skillindexer CLI (fallback)')\n .action(async (options: { skill?: string; all?: boolean; standalone?: boolean }, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n // Check for API key\n if (!process.env.ANTHROPIC_API_KEY) {\n printError('ANTHROPIC_API_KEY environment variable is required');\n process.exit(1);\n }\n\n // If standalone mode, use subprocess\n if (options.standalone) {\n await runStandaloneMode(options, globalOpts);\n return;\n }\n\n // Try to use integrated IndexerService\n try {\n const skillBank = await getSkillBank(globalOpts);\n const indexer = createIntegratedIndexer(skillBank, {\n anthropicApiKey: process.env.ANTHROPIC_API_KEY,\n });\n\n if (!globalOpts.quiet) {\n if (options.skill) {\n printInfo(`Classifying skill: ${options.skill}`);\n } else if (options.all) {\n printInfo('Re-classifying all skills...');\n } else {\n printInfo('Classifying unindexed skills...');\n }\n printInfo('');\n }\n\n // Run classification\n const result = await indexer.classify({\n skillId: options.skill,\n all: options.all,\n });\n\n // Output results\n if (globalOpts.json) {\n console.log(JSON.stringify(result, null, 2));\n } else if (!globalOpts.quiet) {\n printSuccess('Classification completed');\n console.log(` Indexed: ${result.indexed}`);\n console.log(` Skipped: ${result.skipped}`);\n console.log(` Failed: ${result.failed}`);\n\n if (result.errors.length > 0) {\n printWarning('\\nErrors:');\n for (const error of result.errors) {\n console.log(` - ${error}`);\n }\n }\n }\n\n await indexer.close();\n } catch (err) {\n const errorMessage = (err as Error).message;\n\n // If the service isn't available, fall back to subprocess\n if (errorMessage.includes('not available') || errorMessage.includes('not found')) {\n printWarning('IndexerService not available, falling back to standalone CLI...');\n await runStandaloneMode(options, globalOpts);\n return;\n }\n\n printError(errorMessage);\n process.exit(1);\n }\n });\n\n/**\n * Run in standalone mode using the skillindexer CLI subprocess\n */\nasync function runStandaloneMode(\n options: { skill?: string; all?: boolean },\n globalOpts: GlobalOptions\n): Promise<void> {\n if (!globalOpts.quiet) {\n printInfo('Using standalone skillindexer CLI...');\n printInfo('');\n }\n\n const args = ['index'];\n if (options.skill) args.push('--skill', options.skill);\n if (options.all) args.push('--all');\n\n try {\n await runSkillIndexer(args, globalOpts.quiet ?? false);\n } catch (err) {\n printError((err as Error).message);\n printWarning('');\n printWarning('Make sure skillindexer is installed and ANTHROPIC_API_KEY is set.');\n process.exit(1);\n }\n}\n\nasync function runSkillIndexer(args: string[], quiet: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const proc = spawn('skillindexer', args, {\n stdio: quiet ? 'pipe' : 'inherit',\n shell: true,\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to run skillindexer: ${err.message}`));\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`skillindexer exited with code ${code}`));\n }\n });\n });\n}\n","/**\n * taxonomy command - Browse the skill taxonomy tree\n */\n\nimport { Command } from 'commander';\nimport { spawn } from 'child_process';\nimport { printError, printInfo, printWarning } from '../../utils/output.js';\nimport type { GlobalOptions } from '../../utils/skillbank.js';\nimport { getSkillBank } from '../../utils/skillbank.js';\nimport { createIntegratedIndexer, type TaxonomyNode } from '../../../services/indexer.js';\n\nexport const taxonomyCommand = new Command('taxonomy')\n .description('Browse the taxonomy tree')\n .argument('[path]', 'Subtree path (e.g., \"Development/Python\")')\n .option('-i, --interactive', 'Interactive browsing mode')\n .option('--standalone', 'Use standalone skillindexer CLI (fallback)')\n .action(async (pathArg: string | undefined, options: { interactive?: boolean; standalone?: boolean }, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n // Interactive mode requires standalone CLI\n if (options.interactive || options.standalone) {\n await runStandaloneMode(pathArg, options, globalOpts);\n return;\n }\n\n // Try to use integrated IndexerService\n try {\n const skillBank = await getSkillBank(globalOpts);\n const indexer = createIntegratedIndexer(skillBank);\n\n // Parse path argument\n const rootPath = pathArg ? pathArg.split('/').filter(Boolean) : undefined;\n\n // Get taxonomy tree\n const tree = await indexer.getTaxonomyTree(rootPath);\n\n // Output results\n if (globalOpts.json) {\n console.log(JSON.stringify(tree, null, 2));\n } else {\n printTaxonomyTree(tree, 0);\n }\n\n await indexer.close();\n } catch (err) {\n const errorMessage = (err as Error).message;\n\n // If the service isn't available, fall back to subprocess\n if (errorMessage.includes('not available') || errorMessage.includes('not found')) {\n printWarning('IndexerService not available, falling back to standalone CLI...');\n await runStandaloneMode(pathArg, options, globalOpts);\n return;\n }\n\n printError(errorMessage);\n process.exit(1);\n }\n });\n\n/**\n * Print taxonomy tree recursively\n */\nfunction printTaxonomyTree(node: TaxonomyNode, indent: number): void {\n const prefix = ' '.repeat(indent);\n const countStr = node.skillCount > 0 ? ` (${node.skillCount})` : '';\n\n if (indent === 0) {\n console.log(`${node.name}${countStr}`);\n } else {\n console.log(`${prefix}├─ ${node.name}${countStr}`);\n }\n\n for (const child of node.children) {\n printTaxonomyTree(child, indent + 1);\n }\n}\n\n/**\n * Run in standalone mode using the skillindexer CLI subprocess\n */\nasync function runStandaloneMode(\n pathArg: string | undefined,\n options: { interactive?: boolean },\n globalOpts: GlobalOptions\n): Promise<void> {\n if (!globalOpts.quiet) {\n printInfo('Using standalone skillindexer CLI...');\n printInfo('');\n }\n\n const args = ['tree'];\n if (pathArg) args.push(pathArg);\n if (options.interactive) args.push('--interactive');\n\n try {\n await runSkillIndexer(args, globalOpts.quiet ?? false);\n } catch (err) {\n printError((err as Error).message);\n printWarning('');\n printWarning('Make sure skillindexer is installed and has indexed skills.');\n printWarning('Run: skill-tree index scrape --discover && skill-tree index classify');\n process.exit(1);\n }\n}\n\nasync function runSkillIndexer(args: string[], quiet: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const proc = spawn('skillindexer', args, {\n stdio: quiet ? 'pipe' : 'inherit',\n shell: true,\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to run skillindexer: ${err.message}`));\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`skillindexer exited with code ${code}`));\n }\n });\n });\n}\n","/**\n * relationships command - Detect relationships between skills\n */\n\nimport { Command } from 'commander';\nimport { spawn } from 'child_process';\nimport { printError, printInfo, printSuccess, printWarning } from '../../utils/output.js';\nimport type { GlobalOptions } from '../../utils/skillbank.js';\nimport { getSkillBank } from '../../utils/skillbank.js';\nimport { createIntegratedIndexer } from '../../../services/indexer.js';\n\nexport const relationshipsCommand = new Command('relationships')\n .description('Detect relationships between indexed skills')\n .option('-s, --skill <id>', 'Detect relationships for specific skill')\n .option('--use-ai', 'Use AI for relationship reasoning (slower, more accurate)')\n .option('--clear', 'Clear existing relationships before detection')\n .option('--standalone', 'Use standalone skillindexer CLI (fallback)')\n .action(async (options: {\n skill?: string;\n useAi?: boolean;\n clear?: boolean;\n standalone?: boolean;\n }, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n // If standalone mode or AI mode (which requires scraper), use subprocess\n if (options.standalone || options.useAi) {\n await runStandaloneMode(options, globalOpts);\n return;\n }\n\n // Try to use integrated IndexerService\n try {\n const skillBank = await getSkillBank(globalOpts);\n const indexer = createIntegratedIndexer(skillBank);\n\n if (!globalOpts.quiet) {\n if (options.skill) {\n printInfo(`Detecting relationships for skill: ${options.skill}`);\n } else {\n printInfo('Detecting relationships between all skills...');\n }\n printInfo('');\n }\n\n // Run relationship detection\n const result = await indexer.detectRelationships({\n skillId: options.skill,\n useAi: options.useAi,\n });\n\n // Output results\n if (globalOpts.json) {\n console.log(JSON.stringify(result, null, 2));\n } else if (!globalOpts.quiet) {\n printSuccess('Relationship detection completed');\n console.log(` Detected: ${result.detected}`);\n console.log(` Skipped: ${result.skipped}`);\n\n if (result.errors.length > 0) {\n printWarning('\\nErrors:');\n for (const error of result.errors) {\n console.log(` - ${error}`);\n }\n }\n }\n\n await indexer.close();\n } catch (err) {\n const errorMessage = (err as Error).message;\n\n // If the service isn't available, fall back to subprocess\n if (errorMessage.includes('not available') || errorMessage.includes('not found')) {\n printWarning('IndexerService not available, falling back to standalone CLI...');\n await runStandaloneMode(options, globalOpts);\n return;\n }\n\n printError(errorMessage);\n process.exit(1);\n }\n });\n\n/**\n * Run in standalone mode using the skillindexer CLI subprocess\n */\nasync function runStandaloneMode(\n options: { skill?: string; useAi?: boolean; clear?: boolean },\n globalOpts: GlobalOptions\n): Promise<void> {\n if (!globalOpts.quiet) {\n printInfo('Using standalone skillindexer CLI...');\n printInfo('');\n }\n\n const args = ['detect-relationships'];\n if (options.skill) args.push('--skill', options.skill);\n if (options.useAi) args.push('--use-ai');\n if (options.clear) args.push('--clear');\n\n try {\n await runSkillIndexer(args, globalOpts.quiet ?? false);\n } catch (err) {\n printError((err as Error).message);\n printWarning('');\n printWarning('Make sure skillindexer is installed and has indexed skills.');\n process.exit(1);\n }\n}\n\nasync function runSkillIndexer(args: string[], quiet: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const proc = spawn('skillindexer', args, {\n stdio: quiet ? 'pipe' : 'inherit',\n shell: true,\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to run skillindexer: ${err.message}`));\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`skillindexer exited with code ${code}`));\n }\n });\n });\n}\n","/**\n * stats command - Show indexer statistics\n */\n\nimport { Command } from 'commander';\nimport { spawn } from 'child_process';\nimport { printError, printInfo, printWarning } from '../../utils/output.js';\nimport type { GlobalOptions } from '../../utils/skillbank.js';\nimport { getSkillBank } from '../../utils/skillbank.js';\nimport { createIntegratedIndexer } from '../../../services/indexer.js';\n\nexport const indexerStatsCommand = new Command('stats')\n .description('Show indexer database statistics')\n .option('--standalone', 'Use standalone skillindexer CLI (fallback)')\n .action(async (options: { standalone?: boolean }, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n // If standalone mode, use subprocess\n if (options.standalone) {\n await runStandaloneMode(globalOpts);\n return;\n }\n\n // Try to use integrated IndexerService\n try {\n const skillBank = await getSkillBank(globalOpts);\n const indexer = createIntegratedIndexer(skillBank);\n\n // Get stats\n const stats = await indexer.getStats();\n\n // Output results\n if (globalOpts.json) {\n console.log(JSON.stringify(stats, null, 2));\n } else {\n console.log('Skill-Tree Statistics');\n console.log('=' .repeat(40));\n console.log('');\n console.log('Skills:');\n console.log(` Total: ${stats.totalSkills}`);\n console.log(` Indexed: ${stats.indexedSkills}`);\n console.log(` Draft: ${stats.rawSkills}`);\n console.log(` Deprecated: ${stats.failedSkills}`);\n console.log('');\n console.log('Taxonomy:');\n console.log(` Nodes: ${stats.taxonomyNodes}`);\n console.log('');\n console.log('Relationships:');\n console.log(` Total: ${stats.relationships}`);\n console.log('');\n console.log('Sources:');\n console.log(` Unique: ${stats.sources}`);\n }\n\n await indexer.close();\n } catch (err) {\n const errorMessage = (err as Error).message;\n\n // If the service isn't available, fall back to subprocess\n if (errorMessage.includes('not available') || errorMessage.includes('not found')) {\n printWarning('IndexerService not available, falling back to standalone CLI...');\n await runStandaloneMode(globalOpts);\n return;\n }\n\n printError(errorMessage);\n process.exit(1);\n }\n });\n\n/**\n * Run in standalone mode using the skillindexer CLI subprocess\n */\nasync function runStandaloneMode(globalOpts: GlobalOptions): Promise<void> {\n if (!globalOpts.quiet) {\n printInfo('Using standalone skillindexer CLI...');\n printInfo('');\n }\n\n try {\n await runSkillIndexer(['stats'], globalOpts.quiet ?? false);\n } catch (err) {\n printError((err as Error).message);\n printWarning('');\n printWarning('Make sure skillindexer is installed.');\n process.exit(1);\n }\n}\n\nasync function runSkillIndexer(args: string[], quiet: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const proc = spawn('skillindexer', args, {\n stdio: quiet ? 'pipe' : 'inherit',\n shell: true,\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to run skillindexer: ${err.message}`));\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`skillindexer exited with code ${code}`));\n }\n });\n });\n}\n","/**\n * sync command - Bidirectional sync for imported skills\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { spawn } from 'child_process';\nimport { getSkillBank, type GlobalOptions } from '../../utils/skillbank.js';\nimport { printError, printInfo, printSuccess, printWarning } from '../../utils/output.js';\nimport { parseIndexerExport } from '../../../import/index.js';\nimport { createSyncService, type ConflictResolution } from '../../../services/sync.js';\n\nexport const syncCommand = new Command('sync')\n .description('Sync imported skills with remote sources')\n .option('--status', 'Show sync status for all imported skills')\n .option('--pull', 'Pull remote changes for skills that need updates')\n .option('--dry-run', 'Preview changes without making them')\n .option('--force', 'Force sync even for conflicting skills')\n .option('--resolve <strategy>', 'Conflict resolution: local, remote, manual', 'manual')\n .option('--skill <id>', 'Sync specific skill only')\n .option('--import', 'Import from indexer export (legacy mode)')\n .option('--export-path <path>', 'Path to indexer export file (for --import)')\n .option('--indexed-only', 'Only sync indexed skills (for --import)')\n .action(async (options: {\n status?: boolean;\n pull?: boolean;\n dryRun?: boolean;\n force?: boolean;\n resolve?: string;\n skill?: string;\n import?: boolean;\n exportPath?: string;\n indexedOnly?: boolean;\n }, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n\n try {\n // Legacy import mode\n if (options.import) {\n await runLegacyImport(options, globalOpts);\n return;\n }\n\n const skillBank = await getSkillBank(globalOpts);\n const syncService = createSyncService(skillBank, {\n githubToken: process.env.GITHUB_TOKEN,\n conflictResolution: options.resolve as ConflictResolution,\n });\n\n await syncService.initialize();\n\n // Show status\n if (options.status) {\n if (!globalOpts.quiet) {\n printInfo('Checking sync status...');\n }\n\n const results = await syncService.checkForUpdates();\n const summary = await syncService.getStatusSummary();\n\n if (globalOpts.json) {\n console.log(JSON.stringify({ results, summary }, null, 2));\n return;\n }\n\n console.log('');\n console.log('Sync Status Summary');\n console.log('='.repeat(40));\n console.log(` Total imported skills: ${summary.total}`);\n console.log(` Synced: ${summary.synced}`);\n console.log(` Local modified: ${summary.localModified}`);\n console.log(` Remote modified: ${summary.remoteModified}`);\n console.log(` Conflicts: ${summary.conflicts}`);\n console.log(` Never synced: ${summary.neverSynced}`);\n\n if (summary.lastCheck) {\n console.log(` Last check: ${summary.lastCheck.toISOString()}`);\n }\n\n // Show details for non-synced skills\n const needsAction = results.filter(r => r.status !== 'synced');\n if (needsAction.length > 0) {\n console.log('');\n console.log('Skills needing attention:');\n for (const result of needsAction) {\n const icon = result.status === 'conflict' ? '⚠️' :\n result.status === 'remote-modified' ? '↓' :\n result.status === 'local-modified' ? '↑' : '?';\n console.log(` ${icon} ${result.skillName} (${result.skillId})`);\n console.log(` Status: ${result.status}`);\n console.log(` Local version: ${result.localVersion}`);\n if (result.remoteVersion) {\n console.log(` Remote version: ${result.remoteVersion}`);\n }\n }\n }\n\n return;\n }\n\n // Pull remote changes\n if (options.pull) {\n if (!globalOpts.quiet) {\n if (options.dryRun) {\n printInfo('Checking for remote changes (dry run)...');\n } else {\n printInfo('Pulling remote changes...');\n }\n }\n\n const pullResult = await syncService.pullRemoteChanges({\n skillIds: options.skill ? [options.skill] : undefined,\n conflictResolution: options.force ? 'remote' : options.resolve as ConflictResolution,\n dryRun: options.dryRun,\n });\n\n if (globalOpts.json) {\n console.log(JSON.stringify(pullResult, null, 2));\n return;\n }\n\n if (options.dryRun) {\n console.log('');\n console.log('Would pull the following updates:');\n console.log(` Skills to update: ${pullResult.pulled}`);\n console.log(` Skipped: ${pullResult.skipped}`);\n console.log(` Conflicts: ${pullResult.conflicts}`);\n } else {\n printSuccess('Sync completed');\n console.log(` Pulled: ${pullResult.pulled}`);\n console.log(` Skipped: ${pullResult.skipped}`);\n console.log(` Conflicts: ${pullResult.conflicts}`);\n\n if (pullResult.updates.length > 0) {\n console.log('');\n console.log('Updated skills:');\n for (const update of pullResult.updates) {\n console.log(` - ${update.skillId}: ${update.previousVersion} -> ${update.newVersion}`);\n }\n }\n }\n\n if (pullResult.errors.length > 0) {\n printWarning('\\nErrors:');\n for (const error of pullResult.errors) {\n console.log(` - ${error}`);\n }\n }\n\n return;\n }\n\n // Default: show help\n printInfo('Usage:');\n console.log(' skill-tree index sync --status Show sync status');\n console.log(' skill-tree index sync --pull Pull remote changes');\n console.log(' skill-tree index sync --import Import from indexer export');\n console.log('');\n console.log('Options:');\n console.log(' --dry-run Preview changes');\n console.log(' --force Force sync for conflicts');\n console.log(' --resolve <strategy> Conflict resolution: local, remote, manual');\n console.log(' --skill <id> Sync specific skill');\n } catch (err) {\n printError((err as Error).message);\n process.exit(1);\n }\n });\n\n/**\n * Legacy import mode using skillindexer export\n */\nasync function runLegacyImport(\n options: { exportPath?: string; indexedOnly?: boolean; dryRun?: boolean },\n globalOpts: GlobalOptions\n): Promise<void> {\n let exportPath = options.exportPath;\n\n // If no export path provided, generate one\n if (!exportPath) {\n if (!globalOpts.quiet) {\n printInfo('Exporting skills from indexer...');\n }\n\n exportPath = path.join(os.tmpdir(), `skill-tree-sync-${Date.now()}.json`);\n\n const args = ['export-skilltree', '-o', exportPath, '-f', 'json'];\n if (options.indexedOnly) args.push('--indexed-only');\n\n await runSkillIndexer(args, true);\n\n if (!fs.existsSync(exportPath)) {\n printError('Failed to export skills from indexer');\n process.exit(1);\n }\n }\n\n // Read and parse the export\n if (!globalOpts.quiet) {\n printInfo(`Reading export from ${exportPath}...`);\n }\n\n const content = fs.readFileSync(exportPath, 'utf-8');\n const { skills, stats } = parseIndexerExport(content);\n\n if (!globalOpts.quiet) {\n printInfo(`Found ${stats.total} skills (${stats.withStructuredContent} with structured content)`);\n }\n\n if (options.dryRun) {\n console.log('');\n console.log('Would import the following skills:');\n for (const skill of skills.slice(0, 20)) {\n console.log(` - ${skill.id} (${skill.name})`);\n }\n if (skills.length > 20) {\n console.log(` ... and ${skills.length - 20} more`);\n }\n return;\n }\n\n // Import into SkillBank\n const skillBank = await getSkillBank(globalOpts);\n const result = await skillBank.importSkills(skills);\n\n // Clean up temp file\n if (!options.exportPath && exportPath) {\n try {\n fs.unlinkSync(exportPath);\n } catch {\n // Ignore cleanup errors\n }\n }\n\n if (globalOpts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n printSuccess(`Synced ${result.imported} skills into SkillBank`);\n if (result.failed > 0) {\n printWarning(`Failed to sync ${result.failed} skills`);\n }\n}\n\nasync function runSkillIndexer(args: string[], quiet: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const proc = spawn('skillindexer', args, {\n stdio: quiet ? 'pipe' : 'inherit',\n shell: true,\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to run skillindexer: ${err.message}`));\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`skillindexer exited with code ${code}`));\n }\n });\n });\n}\n","/**\n * Sync Service - Bidirectional synchronization for imported skills\n *\n * Keeps skills in sync with their remote sources (GitHub repos, etc.)\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { type Skill, type ExternalSource, hasSyncSupport } from '../types.js';\nimport type { SkillBank } from '../skill-bank.js';\nimport { loadConfig, SkillTreeConfig } from '../config/index.js';\n\n/**\n * Sync state for a skill\n */\nexport interface SkillSyncState {\n skillId: string;\n sourceUrl: string;\n sourceEtag?: string;\n lastSynced: Date;\n localVersion: string;\n remoteVersion?: string;\n status: 'synced' | 'local-modified' | 'remote-modified' | 'conflict';\n}\n\n/**\n * Sync check result for a single skill\n */\nexport interface SyncCheckResult {\n skillId: string;\n skillName: string;\n status: SkillSyncState['status'];\n localVersion: string;\n remoteVersion?: string;\n lastSynced?: Date;\n hasRemoteChanges: boolean;\n hasLocalChanges: boolean;\n}\n\n/**\n * Sync pull result\n */\nexport interface SyncPullResult {\n pulled: number;\n skipped: number;\n conflicts: number;\n errors: string[];\n updates: Array<{\n skillId: string;\n previousVersion: string;\n newVersion: string;\n }>;\n}\n\n/**\n * Sync status summary\n */\nexport interface SyncStatusSummary {\n total: number;\n synced: number;\n localModified: number;\n remoteModified: number;\n conflicts: number;\n neverSynced: number;\n lastCheck?: Date;\n}\n\n/**\n * Conflict resolution strategy\n */\nexport type ConflictResolution = 'local' | 'remote' | 'manual';\n\n/**\n * Sync service configuration\n */\nexport interface SyncServiceConfig {\n /** GitHub API token for fetching updates */\n githubToken?: string;\n /** Auto-sync interval in hours (0 = disabled) */\n autoSyncInterval?: number;\n /** Default conflict resolution */\n conflictResolution?: ConflictResolution;\n}\n\n/**\n * SyncService - Manages bidirectional synchronization of imported skills\n */\nexport class SyncService {\n private skillBank: SkillBank;\n private config: SyncServiceConfig;\n private globalConfig: SkillTreeConfig;\n private syncStates: Map<string, SkillSyncState> = new Map();\n private lastCheck?: Date;\n\n constructor(skillBank: SkillBank, config: SyncServiceConfig = {}) {\n this.skillBank = skillBank;\n this.globalConfig = loadConfig();\n this.config = {\n githubToken: config.githubToken || this.globalConfig.indexer.github_token,\n autoSyncInterval: config.autoSyncInterval || 0,\n conflictResolution: config.conflictResolution || this.globalConfig.sync.conflict_resolution as ConflictResolution,\n };\n }\n\n /**\n * Initialize sync service\n * Loads sync state from storage if available\n */\n async initialize(): Promise<void> {\n // Try to load sync states from storage\n // Note: Storage may have extended sync state support beyond the base interface\n const storage = this.skillBank.getStorage();\n if (storage?.getSyncStates) {\n try {\n const states = await storage.getSyncStates();\n for (const state of states) {\n const record = state as Record<string, unknown>;\n if (record.skillId && record.lastSynced) {\n const skillId = record.skillId as string;\n this.syncStates.set(skillId, {\n skillId,\n sourceUrl: (record.sourceUrl as string) || '',\n sourceEtag: record.sourceEtag as string | undefined,\n lastSynced: new Date(record.lastSynced as string | number | Date),\n localVersion: (record.localVersion as string) || '0.0.0',\n remoteVersion: record.remoteVersion as string | undefined,\n status: (record.status as SkillSyncState['status']) || 'synced',\n });\n }\n }\n } catch {\n // Sync states not available in storage\n }\n }\n }\n\n /**\n * Get sync state for a skill\n */\n getSyncState(skillId: string): SkillSyncState | undefined {\n return this.syncStates.get(skillId);\n }\n\n /**\n * Set sync state for a skill\n */\n async setSyncState(skillId: string, state: SkillSyncState): Promise<void> {\n this.syncStates.set(skillId, state);\n\n // Persist to storage if available\n const storage = this.skillBank.getStorage();\n if (storage?.saveSyncState) {\n try {\n await storage.saveSyncState({\n remote: state.sourceUrl,\n syncedAt: state.lastSynced,\n commitHash: state.sourceEtag,\n });\n } catch {\n // Sync state persistence not available\n }\n }\n }\n\n /**\n * Check for updates on all imported skills\n */\n async checkForUpdates(): Promise<SyncCheckResult[]> {\n const results: SyncCheckResult[] = [];\n const skills = await this.skillBank.listSkills();\n\n for (const skill of skills) {\n // Only check imported skills with external sources\n if (!skill.externalSource?.url) continue;\n\n const result = await this.checkSkillForUpdates(skill);\n results.push(result);\n }\n\n this.lastCheck = new Date();\n return results;\n }\n\n /**\n * Check a single skill for updates\n */\n async checkSkillForUpdates(skill: Skill): Promise<SyncCheckResult> {\n const syncState = this.syncStates.get(skill.id);\n\n // If no external source, can't sync\n if (!skill.externalSource?.url) {\n return {\n skillId: skill.id,\n skillName: skill.name,\n status: 'synced',\n localVersion: skill.version,\n hasRemoteChanges: false,\n hasLocalChanges: false,\n };\n }\n\n // Check for local modifications\n const hasLocalChanges = syncState\n ? skill.version !== syncState.localVersion\n : false;\n\n // Check for remote changes (if we have a GitHub URL)\n let hasRemoteChanges = false;\n let remoteVersion: string | undefined;\n\n if (skill.externalSource.url.includes('github.com')) {\n try {\n const remoteInfo = await this.fetchRemoteInfo(skill.externalSource.url);\n hasRemoteChanges = remoteInfo.etag !== syncState?.sourceEtag;\n remoteVersion = remoteInfo.version;\n } catch {\n // Failed to check remote, assume no changes\n }\n }\n\n // Determine status\n let status: SkillSyncState['status'];\n if (hasLocalChanges && hasRemoteChanges) {\n status = 'conflict';\n } else if (hasLocalChanges) {\n status = 'local-modified';\n } else if (hasRemoteChanges) {\n status = 'remote-modified';\n } else {\n status = 'synced';\n }\n\n return {\n skillId: skill.id,\n skillName: skill.name,\n status,\n localVersion: skill.version,\n remoteVersion,\n lastSynced: syncState?.lastSynced,\n hasRemoteChanges,\n hasLocalChanges,\n };\n }\n\n /**\n * Fetch remote info from GitHub\n */\n private async fetchRemoteInfo(url: string): Promise<{ etag?: string; version?: string; content?: string }> {\n // Parse GitHub URL\n const match = url.match(/github\\.com\\/([^/]+)\\/([^/]+)\\/blob\\/([^/]+)\\/(.+)/);\n if (!match) {\n throw new Error('Invalid GitHub URL');\n }\n\n const [, owner, repo, branch, filePath] = match;\n\n // Fetch file info from GitHub API\n const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${filePath}?ref=${branch}`;\n\n const headers: Record<string, string> = {\n 'Accept': 'application/vnd.github.v3+json',\n 'User-Agent': 'skill-tree-sync',\n };\n\n if (this.config.githubToken) {\n headers['Authorization'] = `Bearer ${this.config.githubToken}`;\n }\n\n const response = await fetch(apiUrl, { headers });\n\n if (!response.ok) {\n throw new Error(`GitHub API error: ${response.status}`);\n }\n\n const data = await response.json();\n const etag = response.headers.get('etag') || data.sha;\n\n // Try to extract version from content\n let version: string | undefined;\n if (data.content) {\n const content = Buffer.from(data.content, 'base64').toString('utf-8');\n const versionMatch = content.match(/version:\\s*['\"]?(\\d+\\.\\d+\\.\\d+)['\"]?/i);\n if (versionMatch) {\n version = versionMatch[1];\n }\n }\n\n return { etag, version, content: data.content };\n }\n\n /**\n * Pull remote changes for all skills that need updates\n */\n async pullRemoteChanges(options?: {\n skillIds?: string[];\n conflictResolution?: ConflictResolution;\n dryRun?: boolean;\n }): Promise<SyncPullResult> {\n const result: SyncPullResult = {\n pulled: 0,\n skipped: 0,\n conflicts: 0,\n errors: [],\n updates: [],\n };\n\n // Get skills to check\n let skills = await this.skillBank.listSkills();\n if (options?.skillIds) {\n skills = skills.filter(s => options.skillIds!.includes(s.id));\n }\n\n for (const skill of skills) {\n if (!skill.externalSource?.url) {\n result.skipped++;\n continue;\n }\n\n try {\n const checkResult = await this.checkSkillForUpdates(skill);\n\n if (checkResult.status === 'synced') {\n result.skipped++;\n continue;\n }\n\n if (checkResult.status === 'conflict') {\n const resolution = options?.conflictResolution || this.config.conflictResolution;\n if (resolution === 'manual') {\n result.conflicts++;\n continue;\n } else if (resolution === 'local') {\n result.skipped++;\n continue;\n }\n // If 'remote', proceed to pull\n }\n\n if (checkResult.status === 'local-modified') {\n result.skipped++;\n continue;\n }\n\n // Pull remote changes\n if (!options?.dryRun) {\n const updated = await this.pullSkillUpdate(skill);\n if (updated) {\n result.pulled++;\n result.updates.push({\n skillId: skill.id,\n previousVersion: skill.version,\n newVersion: updated.version,\n });\n }\n } else {\n result.pulled++;\n }\n } catch (err) {\n result.errors.push(`Failed to sync ${skill.id}: ${(err as Error).message}`);\n }\n }\n\n return result;\n }\n\n /**\n * Pull update for a single skill\n */\n private async pullSkillUpdate(skill: Skill): Promise<Skill | null> {\n if (!skill.externalSource?.url) return null;\n\n try {\n const remoteInfo = await this.fetchRemoteInfo(skill.externalSource.url);\n\n if (!remoteInfo.content) return null;\n\n // Decode and parse content\n const content = Buffer.from(remoteInfo.content, 'base64').toString('utf-8');\n\n // Update skill with remote content\n // Note: This is a simplified version - full implementation would\n // re-parse the skill file and merge changes\n const updatedSkill: Skill = {\n ...skill,\n version: remoteInfo.version || skill.version,\n updatedAt: new Date(),\n externalSource: {\n ...skill.externalSource,\n etag: remoteInfo.etag,\n },\n };\n\n await this.skillBank.saveSkill(updatedSkill);\n\n // Update sync state\n await this.setSyncState(skill.id, {\n skillId: skill.id,\n sourceUrl: skill.externalSource.url,\n sourceEtag: remoteInfo.etag,\n lastSynced: new Date(),\n localVersion: updatedSkill.version,\n remoteVersion: remoteInfo.version,\n status: 'synced',\n });\n\n return updatedSkill;\n } catch {\n return null;\n }\n }\n\n /**\n * Mark a skill as synced (after manual resolution)\n */\n async markAsSynced(skillId: string): Promise<void> {\n const skill = await this.skillBank.getSkill(skillId);\n if (!skill || !skill.externalSource?.url) return;\n\n await this.setSyncState(skillId, {\n skillId,\n sourceUrl: skill.externalSource.url,\n sourceEtag: skill.externalSource.etag,\n lastSynced: new Date(),\n localVersion: skill.version,\n status: 'synced',\n });\n }\n\n /**\n * Get sync status summary\n */\n async getStatusSummary(): Promise<SyncStatusSummary> {\n const skills = await this.skillBank.listSkills();\n const summary: SyncStatusSummary = {\n total: 0,\n synced: 0,\n localModified: 0,\n remoteModified: 0,\n conflicts: 0,\n neverSynced: 0,\n lastCheck: this.lastCheck,\n };\n\n for (const skill of skills) {\n if (!skill.externalSource?.url) continue;\n\n summary.total++;\n const state = this.syncStates.get(skill.id);\n\n if (!state) {\n summary.neverSynced++;\n } else {\n switch (state.status) {\n case 'synced':\n summary.synced++;\n break;\n case 'local-modified':\n summary.localModified++;\n break;\n case 'remote-modified':\n summary.remoteModified++;\n break;\n case 'conflict':\n summary.conflicts++;\n break;\n }\n }\n }\n\n return summary;\n }\n\n /**\n * Detect conflicts between local and remote versions\n */\n async detectConflicts(): Promise<Array<{\n skill: Skill;\n localChanges: string[];\n remoteChanges: string[];\n }>> {\n const conflicts: Array<{\n skill: Skill;\n localChanges: string[];\n remoteChanges: string[];\n }> = [];\n\n const skills = await this.skillBank.listSkills();\n\n for (const skill of skills) {\n const state = this.syncStates.get(skill.id);\n if (state?.status === 'conflict' && skill.externalSource?.url) {\n // Simplified conflict detection\n // Full implementation would do diff analysis\n conflicts.push({\n skill,\n localChanges: [`Version changed: ${state.localVersion} -> ${skill.version}`],\n remoteChanges: state.remoteVersion\n ? [`Remote version: ${state.remoteVersion}`]\n : ['Remote content changed'],\n });\n }\n }\n\n return conflicts;\n }\n\n /**\n * Register a skill as imported (sets initial sync state)\n */\n async registerImportedSkill(skill: Skill): Promise<void> {\n if (!skill.externalSource?.url) return;\n\n await this.setSyncState(skill.id, {\n skillId: skill.id,\n sourceUrl: skill.externalSource.url,\n sourceEtag: skill.externalSource.etag,\n lastSynced: new Date(),\n localVersion: skill.version,\n status: 'synced',\n });\n }\n}\n\n/**\n * Create a sync service instance\n */\nexport function createSyncService(\n skillBank: SkillBank,\n config?: SyncServiceConfig\n): SyncService {\n return new SyncService(skillBank, config);\n}\n","/**\n * Config Command\n * View and manage skill-tree configuration\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport {\n loadConfig,\n getConfigPath,\n getConfigDir,\n ConfigLoader,\n expandPath,\n DEFAULT_CONFIG,\n} from '../../config/index.js';\n\nexport const configCommand = new Command('config')\n .description('View and manage configuration');\n\n/**\n * Show current configuration\n */\nconfigCommand\n .command('show')\n .description('Show current configuration')\n .option('--path <path>', 'Path to specific config value (e.g., storage.type)')\n .action((options) => {\n const globalOpts = configCommand.parent?.opts() || {};\n const configPath = globalOpts.config as string | undefined;\n const loader = new ConfigLoader(configPath);\n const config = loader.load();\n\n if (options.path) {\n const value = loader.get(options.path);\n if (value === undefined) {\n console.error(`Config path not found: ${options.path}`);\n process.exit(1);\n }\n if (globalOpts.json) {\n console.log(JSON.stringify(value, null, 2));\n } else {\n console.log(value);\n }\n } else {\n if (globalOpts.json) {\n console.log(JSON.stringify(config, null, 2));\n } else {\n console.log('Current Configuration:');\n console.log('='.repeat(40));\n console.log(`Config file: ${expandPath(configPath || getConfigPath())}`);\n console.log('');\n printConfig(config, 0);\n }\n }\n });\n\n/**\n * Initialize configuration file\n */\nconfigCommand\n .command('init')\n .description('Create default configuration file')\n .option('-f, --force', 'Overwrite existing config file')\n .action((options) => {\n const globalOpts = configCommand.parent?.opts() || {};\n const configPath = expandPath((globalOpts.config as string) || getConfigPath());\n\n if (fs.existsSync(configPath) && !options.force) {\n console.error(`Config file already exists: ${configPath}`);\n console.error('Use --force to overwrite');\n process.exit(1);\n }\n\n const loader = new ConfigLoader(configPath);\n loader.createDefaultConfigFile();\n\n if (!(globalOpts.quiet ?? false)) {\n console.log(`Created config file: ${configPath}`);\n }\n });\n\n/**\n * Show config file path\n */\nconfigCommand\n .command('path')\n .description('Show configuration file path')\n .action(() => {\n const globalOpts = configCommand.parent?.opts() || {};\n const configPath = (globalOpts.config as string) || getConfigPath();\n console.log(expandPath(configPath));\n });\n\n/**\n * Edit configuration file\n */\nconfigCommand\n .command('edit')\n .description('Open configuration file in editor')\n .action(() => {\n const globalOpts = configCommand.parent?.opts() || {};\n const configPath = expandPath((globalOpts.config as string) || getConfigPath());\n\n // Ensure config exists\n if (!fs.existsSync(configPath)) {\n const loader = new ConfigLoader(configPath);\n loader.createDefaultConfigFile();\n }\n\n const editor = process.env.EDITOR || process.env.VISUAL || 'nano';\n\n // Import child_process dynamically to avoid issues\n import('child_process')\n .then(({ spawn }) => {\n const child = spawn(editor, [configPath], {\n stdio: 'inherit',\n shell: true,\n });\n\n child.on('exit', (code) => {\n process.exit(code || 0);\n });\n })\n .catch((error) => {\n console.error('Failed to open editor:', error.message);\n process.exit(1);\n });\n });\n\n/**\n * Show defaults\n */\nconfigCommand\n .command('defaults')\n .description('Show default configuration values')\n .action(() => {\n const globalOpts = configCommand.parent?.opts() || {};\n\n if (globalOpts.json) {\n console.log(JSON.stringify(DEFAULT_CONFIG, null, 2));\n } else {\n console.log('Default Configuration:');\n console.log('='.repeat(40));\n printConfig(DEFAULT_CONFIG, 0);\n }\n });\n\n/**\n * Validate configuration\n */\nconfigCommand\n .command('validate')\n .description('Validate configuration file')\n .action(() => {\n const globalOpts = configCommand.parent?.opts() || {};\n const configPath = expandPath((globalOpts.config as string) || getConfigPath());\n\n if (!fs.existsSync(configPath)) {\n console.error(`Config file not found: ${configPath}`);\n process.exit(1);\n }\n\n try {\n const loader = new ConfigLoader(configPath);\n const config = loader.load();\n\n // Check required fields\n const errors: string[] = [];\n\n if (!config.storage.type) {\n errors.push('storage.type is required');\n }\n if (!config.storage.path) {\n errors.push('storage.path is required');\n }\n if (!['sqlite', 'filesystem', 'memory'].includes(config.storage.type)) {\n errors.push(`storage.type must be one of: sqlite, filesystem, memory`);\n }\n\n if (config.indexer.min_confidence < 0 || config.indexer.min_confidence > 1) {\n errors.push('indexer.min_confidence must be between 0 and 1');\n }\n if (config.indexer.batch_size < 1) {\n errors.push('indexer.batch_size must be at least 1');\n }\n\n if (config.matching.similarity_threshold < 0 || config.matching.similarity_threshold > 1) {\n errors.push('matching.similarity_threshold must be between 0 and 1');\n }\n\n if (errors.length > 0) {\n console.error('Configuration errors:');\n for (const error of errors) {\n console.error(` - ${error}`);\n }\n process.exit(1);\n }\n\n if (!(globalOpts.quiet ?? false)) {\n console.log('Configuration is valid');\n }\n } catch (error) {\n console.error('Failed to parse config file:', (error as Error).message);\n process.exit(1);\n }\n });\n\n/**\n * Print config object with indentation\n */\nfunction printConfig(obj: unknown, indent: number): void {\n const prefix = ' '.repeat(indent);\n\n if (typeof obj !== 'object' || obj === null) {\n console.log(`${prefix}${obj}`);\n return;\n }\n\n if (Array.isArray(obj)) {\n if (obj.length === 0) {\n console.log(`${prefix}[]`);\n } else {\n for (const item of obj) {\n console.log(`${prefix}- ${item}`);\n }\n }\n return;\n }\n\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n console.log(`${prefix}${key}:`);\n printConfig(value, indent + 1);\n } else if (Array.isArray(value)) {\n console.log(`${prefix}${key}:`);\n printConfig(value, indent + 1);\n } else {\n const displayValue = value === undefined ? '(not set)' : value;\n console.log(`${prefix}${key}: ${displayValue}`);\n }\n }\n}\n","/**\n * sync command - Multi-agent skill synchronization\n */\n\nimport { Command } from 'commander';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport type { GlobalOptions } from '../utils/skillbank.js';\nimport { printError, printInfo, printSuccess, printWarning } from '../utils/output.js';\nimport { getSkillPath } from '../utils/skillbank.js';\nimport {\n GitSyncAdapter,\n createDefaultSyncConfig,\n type SyncConfig,\n type SkillConflict,\n} from '../../sync/index.js';\n\n// Path to sync config file\nfunction getSyncConfigPath(basePath: string): string {\n return path.join(basePath, '.skillbank', 'sync-config.json');\n}\n\n// Load sync config\nasync function loadSyncConfig(basePath: string): Promise<SyncConfig | null> {\n const configPath = getSyncConfigPath(basePath);\n try {\n const content = await fs.promises.readFile(configPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n// Save sync config\nasync function saveSyncConfig(basePath: string, config: SyncConfig): Promise<void> {\n const configPath = getSyncConfigPath(basePath);\n await fs.promises.mkdir(path.dirname(configPath), { recursive: true });\n await fs.promises.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');\n}\n\n// Create the sync adapter\nasync function createSyncAdapter(\n basePath: string,\n globalOpts: GlobalOptions\n): Promise<GitSyncAdapter | null> {\n const config = await loadSyncConfig(basePath);\n\n if (!config) {\n printError('Sync not configured. Run \"skill-tree sync init\" first.');\n return null;\n }\n\n const adapter = new GitSyncAdapter({\n repoPath: basePath,\n config,\n });\n\n await adapter.initialize();\n return adapter;\n}\n\n// ===========================================================================\n// Main sync command\n// ===========================================================================\n\nexport const syncCommand = new Command('sync')\n .description('Multi-agent skill synchronization')\n .addCommand(initCommand())\n .addCommand(statusCommand())\n .addCommand(pullCommand())\n .addCommand(pushCommand())\n .addCommand(conflictsCommand())\n .addCommand(resolveCommand());\n\n// ===========================================================================\n// sync init\n// ===========================================================================\n\nfunction initCommand(): Command {\n return new Command('init')\n .description('Initialize sync configuration')\n .requiredOption('-r, --remote <url>', 'Remote repository URL')\n .requiredOption('-a, --agent <id>', 'Agent ID (slug format)')\n .option('-b, --branch <branch>', 'Branch to sync with', 'main')\n .option('-n, --name <name>', 'Agent name (human-readable)')\n .option('-e, --env <environment>', 'Environment (production, staging, etc.)')\n .action(async (options, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n const basePath = getSkillPath(globalOpts);\n\n try {\n // Check if already configured\n const existing = await loadSyncConfig(basePath);\n if (existing) {\n printWarning('Sync already configured. Overwriting...');\n }\n\n // Create config\n const config = createDefaultSyncConfig(options.remote, options.agent, {\n branch: options.branch,\n agentName: options.name,\n environment: options.env,\n });\n\n // Verify it's a git repo\n const gitDir = path.join(basePath, '.git');\n if (!fs.existsSync(gitDir)) {\n printError(`Not a git repository: ${basePath}`);\n printInfo('Initialize a git repository first with: git init');\n process.exit(1);\n }\n\n // Save config\n await saveSyncConfig(basePath, config);\n\n printSuccess('Sync configured successfully!');\n console.log();\n printInfo(`Remote: ${options.remote}`);\n printInfo(`Branch: ${options.branch}`);\n printInfo(`Agent ID: ${options.agent}`);\n if (options.name) {\n printInfo(`Agent Name: ${options.name}`);\n }\n if (options.env) {\n printInfo(`Environment: ${options.env}`);\n }\n console.log();\n printInfo('Run \"skill-tree sync pull\" to fetch skills from remote.');\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n}\n\n// ===========================================================================\n// sync status\n// ===========================================================================\n\nfunction statusCommand(): Command {\n return new Command('status')\n .description('Show sync status')\n .action(async (_options, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n const basePath = getSkillPath(globalOpts);\n\n try {\n const adapter = await createSyncAdapter(basePath, globalOpts);\n if (!adapter) return;\n\n const status = await adapter.status();\n\n if (globalOpts.json) {\n console.log(JSON.stringify(status, null, 2));\n return;\n }\n\n console.log();\n printInfo(`Branch: ${status.branch}`);\n printInfo(`Remote: ${status.remoteUrl}`);\n console.log();\n\n if (!status.connected) {\n printWarning('Not connected to remote');\n } else {\n if (status.localAhead > 0) {\n printWarning(`Your branch is ahead by ${status.localAhead} commit(s)`);\n }\n if (status.remoteBehind > 0) {\n printWarning(`Your branch is behind by ${status.remoteBehind} commit(s)`);\n }\n if (status.localAhead === 0 && status.remoteBehind === 0) {\n printSuccess('Up to date with remote');\n }\n }\n\n if (status.modifiedSkills.length > 0) {\n console.log();\n printInfo(`Modified skills (${status.modifiedSkills.length}):`);\n for (const skillId of status.modifiedSkills) {\n console.log(` - ${skillId}`);\n }\n }\n\n if (status.pendingConflicts > 0) {\n console.log();\n printWarning(`Pending conflicts: ${status.pendingConflicts}`);\n printInfo('Run \"skill-tree sync conflicts\" to see details');\n }\n\n if (status.lastSync) {\n console.log();\n printInfo(`Last sync: ${status.lastSync.toLocaleString()}`);\n }\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n}\n\n// ===========================================================================\n// sync pull\n// ===========================================================================\n\nfunction pullCommand(): Command {\n return new Command('pull')\n .description('Pull skills from remote')\n .option('-s, --skills <ids>', 'Specific skill IDs (comma-separated)')\n .option('-f, --force', 'Force overwrite local changes')\n .option('-d, --dry-run', 'Preview changes without applying')\n .action(async (options, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n const basePath = getSkillPath(globalOpts);\n\n try {\n const adapter = await createSyncAdapter(basePath, globalOpts);\n if (!adapter) return;\n\n const skillIds = options.skills?.split(',').map((s: string) => s.trim());\n\n if (options.dryRun) {\n printInfo('Dry run - no changes will be applied');\n console.log();\n }\n\n const result = await adapter.pull({\n skillIds,\n force: options.force,\n dryRun: options.dryRun,\n });\n\n if (globalOpts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n // Report results\n if (result.pulled.length === 0 && result.conflicts.length === 0) {\n printSuccess('Already up to date');\n return;\n }\n\n if (result.pulled.length > 0) {\n console.log();\n printSuccess(`Pulled ${result.pulled.length} skill(s):`);\n for (const change of result.pulled) {\n const icon =\n change.changeType === 'added'\n ? '+'\n : change.changeType === 'deleted'\n ? '-'\n : '~';\n console.log(` ${icon} ${change.skillId}`);\n }\n }\n\n if (result.autoMerged.length > 0) {\n console.log();\n printInfo(`Auto-merged ${result.autoMerged.length} skill(s):`);\n for (const merge of result.autoMerged) {\n console.log(` ~ ${merge.skillId}`);\n }\n }\n\n if (result.conflicts.length > 0) {\n console.log();\n printWarning(`Conflicts (${result.conflicts.length}):`);\n for (const conflict of result.conflicts) {\n console.log(` ! ${conflict.skillId}`);\n for (const field of conflict.conflictingFields) {\n console.log(` - ${field}`);\n }\n }\n console.log();\n printInfo('Run \"skill-tree sync conflicts\" to resolve');\n }\n\n if (result.errors.length > 0) {\n console.log();\n printError(`Errors (${result.errors.length}):`);\n for (const err of result.errors) {\n console.log(` - ${err.skillId || 'general'}: ${err.message}`);\n }\n }\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n}\n\n// ===========================================================================\n// sync push\n// ===========================================================================\n\nfunction pushCommand(): Command {\n return new Command('push')\n .description('Push skills to remote')\n .option('-s, --skills <ids>', 'Specific skill IDs (comma-separated)')\n .option('-m, --message <msg>', 'Custom commit message')\n .option('-f, --force', 'Force push (overwrites remote)')\n .action(async (options, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n const basePath = getSkillPath(globalOpts);\n\n try {\n const adapter = await createSyncAdapter(basePath, globalOpts);\n if (!adapter) return;\n\n const skillIds = options.skills?.split(',').map((s: string) => s.trim());\n\n if (options.force) {\n printWarning('Force push enabled - this may overwrite remote changes!');\n }\n\n const result = await adapter.push({\n skillIds,\n message: options.message,\n force: options.force,\n });\n\n if (globalOpts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n // Report results\n if (result.pushed.length === 0 && result.errors.length === 0) {\n printInfo('Nothing to push');\n return;\n }\n\n if (result.pushed.length > 0) {\n console.log();\n printSuccess(`Pushed ${result.pushed.length} skill(s):`);\n for (const change of result.pushed) {\n const icon = change.changeType === 'added' ? '+' : '~';\n console.log(` ${icon} ${change.skillId}`);\n }\n }\n\n if (result.errors.length > 0) {\n console.log();\n if (result.errors.some((e) => e.type === 'conflict')) {\n printWarning('Push rejected - remote has changes');\n printInfo('Run \"skill-tree sync pull\" first, then try again');\n } else {\n printError(`Errors (${result.errors.length}):`);\n for (const err of result.errors) {\n console.log(` - ${err.skillId || 'general'}: ${err.message}`);\n }\n }\n }\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n}\n\n// ===========================================================================\n// sync conflicts\n// ===========================================================================\n\nfunction conflictsCommand(): Command {\n return new Command('conflicts')\n .description('List pending conflicts')\n .option('-v, --verbose', 'Show detailed conflict information')\n .action(async (options, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n const basePath = getSkillPath(globalOpts);\n\n try {\n const adapter = await createSyncAdapter(basePath, globalOpts);\n if (!adapter) return;\n\n const conflicts = await adapter.listConflicts();\n\n if (globalOpts.json) {\n console.log(JSON.stringify(conflicts, null, 2));\n return;\n }\n\n if (conflicts.length === 0) {\n printSuccess('No pending conflicts');\n return;\n }\n\n console.log();\n printWarning(`${conflicts.length} conflict(s) pending resolution:`);\n console.log();\n\n for (const conflict of conflicts) {\n console.log(` ${conflict.skillId}`);\n console.log(` Detected: ${conflict.detectedAt.toLocaleString()}`);\n console.log(` Local version: ${conflict.localVersion.version}`);\n console.log(` Remote version: ${conflict.remoteVersion.version}`);\n console.log(` Conflicting fields:`);\n for (const field of conflict.conflictingFields) {\n console.log(` - ${field}`);\n }\n\n if (options.verbose && conflict.fieldConflicts.length > 0) {\n console.log(` Details:`);\n for (const fc of conflict.fieldConflicts) {\n console.log(` ${fc.field}: ${fc.reason}`);\n }\n }\n\n if (conflict.suggestedResolution) {\n console.log(\n ` Suggested resolution available (confidence: ${Math.round(conflict.confidence * 100)}%)`\n );\n }\n\n console.log();\n }\n\n printInfo('To resolve a conflict:');\n console.log(' skill-tree sync resolve <skill-id> --accept-local');\n console.log(' skill-tree sync resolve <skill-id> --accept-remote');\n console.log(' skill-tree sync resolve <skill-id> --accept-merged');\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n}\n\n// ===========================================================================\n// sync resolve\n// ===========================================================================\n\nfunction resolveCommand(): Command {\n return new Command('resolve')\n .description('Resolve a conflict')\n .argument('<skill-id>', 'Skill ID to resolve')\n .option('-l, --accept-local', 'Accept local version')\n .option('-r, --accept-remote', 'Accept remote version')\n .option('-m, --accept-merged', 'Accept auto-merged suggestion')\n .action(async (skillId: string, options, command: Command) => {\n const globalOpts = command.optsWithGlobals() as GlobalOptions;\n const basePath = getSkillPath(globalOpts);\n\n try {\n const adapter = await createSyncAdapter(basePath, globalOpts);\n if (!adapter) return;\n\n // Determine resolution strategy\n let strategy: 'accept-local' | 'accept-remote' | 'accept-merged';\n\n if (options.acceptLocal) {\n strategy = 'accept-local';\n } else if (options.acceptRemote) {\n strategy = 'accept-remote';\n } else if (options.acceptMerged) {\n strategy = 'accept-merged';\n } else {\n printError('Specify a resolution strategy:');\n console.log(' --accept-local Keep your local version');\n console.log(' --accept-remote Accept the remote version');\n console.log(' --accept-merged Accept the auto-merged suggestion');\n process.exit(1);\n return;\n }\n\n await adapter.resolveConflict(skillId, { strategy });\n\n printSuccess(`Resolved conflict for ${skillId} using ${strategy}`);\n printInfo('The resolved version has been staged. Run \"skill-tree sync push\" when ready.');\n } catch (error) {\n printError((error as Error).message);\n process.exit(1);\n }\n });\n}\n","/**\n * mcp command - Start MCP server over stdio\n *\n * Bridges the SkillTreeMcpServer to a JSON-RPC 2.0 stdio transport,\n * allowing Claude and other MCP clients to interact with skill-tree.\n */\n\nimport { Command } from 'commander';\nimport * as readline from 'node:readline';\nimport { FilesystemStorageAdapter } from '../../storage/filesystem.js';\nimport { SkillGraphServer } from '../../serving/graph-server.js';\nimport { SkillTreeMcpServer } from '../../mcp/server.js';\nimport type { GlobalOptions } from '../utils/skillbank.js';\nimport { resolveSkillPath, ensureDir } from '../utils/paths.js';\n\ninterface McpOptions extends GlobalOptions {\n agentCanSetLoadout?: boolean;\n maxExpanded?: string;\n}\n\nexport const mcpCommand = new Command('mcp')\n .description('Start MCP server over stdio (JSON-RPC 2.0)')\n .option('--agent-can-set-loadout', 'Allow agent to set loadout via criteria', false)\n .option('--max-expanded <n>', 'Maximum number of expanded skills', '5')\n .action(async (options: McpOptions, command: Command) => {\n const globalOpts = command.optsWithGlobals() as McpOptions;\n const skillPath = resolveSkillPath(globalOpts.path);\n\n ensureDir(skillPath);\n\n // Initialize storage\n const storage = new FilesystemStorageAdapter({ basePath: skillPath });\n await storage.initialize();\n\n // Initialize graph server\n const graphServer = new SkillGraphServer(storage, {\n agentCanModify: true,\n agentCanSetLoadout: globalOpts.agentCanSetLoadout ?? false,\n agentCanSwitchProfile: true,\n requireApproval: false,\n autoExpandOnUse: true,\n autoExpandRelated: false,\n maxExpanded: parseInt(globalOpts.maxExpanded || '5', 10),\n });\n await graphServer.initialize();\n\n // Initialize MCP server\n const mcpServer = new SkillTreeMcpServer(graphServer, {\n dynamicTools: false,\n });\n\n // JSON-RPC 2.0 stdio transport\n const rl = readline.createInterface({ input: process.stdin, terminal: false });\n let buffer = '';\n\n rl.on('line', async (line: string) => {\n buffer += line;\n\n let msg: { id?: number; method: string; params?: Record<string, unknown> };\n try {\n msg = JSON.parse(buffer);\n buffer = '';\n } catch {\n return;\n }\n\n const { id, method, params } = msg;\n\n try {\n let result: unknown;\n\n switch (method) {\n case 'initialize':\n result = {\n protocolVersion: '2024-11-05',\n capabilities: { tools: {} },\n serverInfo: mcpServer.getServerInfo(),\n };\n break;\n\n case 'notifications/initialized':\n return;\n\n case 'tools/list':\n result = {\n tools: mcpServer.getTools().map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n };\n break;\n\n case 'tools/call': {\n const { name, arguments: args } = params as {\n name: string;\n arguments?: Record<string, unknown>;\n };\n const toolResult = await mcpServer.executeTool(name, args || {});\n\n result = {\n content: [\n {\n type: 'text',\n text: JSON.stringify(toolResult, null, 2),\n },\n ],\n isError: !toolResult.success,\n };\n break;\n }\n\n case 'ping':\n result = {};\n break;\n\n default:\n respond(id, null, { code: -32601, message: `Method not found: ${method}` });\n return;\n }\n\n respond(id, result);\n } catch (err) {\n respond(id, null, { code: -32603, message: String(err) });\n }\n });\n\n function respond(\n id: number | undefined,\n result: unknown,\n error?: { code: number; message: string }\n ): void {\n if (id === undefined) return;\n const response: Record<string, unknown> = { jsonrpc: '2.0', id };\n if (error) {\n response.error = error;\n } else {\n response.result = result;\n }\n process.stdout.write(JSON.stringify(response) + '\\n');\n }\n\n process.on('SIGTERM', () => {\n mcpServer.dispose();\n process.exit(0);\n });\n });\n"],"mappings":"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","names":["import_commander","config","config","DEFAULT_CONFIG","config","DEFAULT_CONFIG","config","config","path","config","config","fs","path","fs","path","DEFAULT_CONFIG","config","config","config","DEFAULT_CONFIG","config","path","config","config","config","fs","path","config","import_crypto","config","hookRegistry","config","fs","path","fs","path","DEFAULT_CONFIG","config","DEFAULT_CONFIG","fs","path","path","config","DEFAULT_CONFIG","fs","path","os","chalk","import_commander","import_commander","import_commander","import_commander","import_commander","import_commander","import_commander","import_commander","import_commander","import_commander","import_commander","fs","import_commander","fs","import_commander","import_commander","import_child_process","path","fs","config","resolve","import_commander","import_child_process","runStandaloneMode","runSkillIndexer","resolve","import_commander","import_child_process","runStandaloneMode","runSkillIndexer","resolve","import_commander","import_child_process","runStandaloneMode","runSkillIndexer","resolve","import_commander","import_child_process","runStandaloneMode","runSkillIndexer","resolve","import_commander","fs","path","os","import_child_process","config","runSkillIndexer","resolve","import_commander","fs","config","spawn","DEFAULT_CONFIG","import_commander","path","fs","config","syncCommand","import_commander","syncCommand"]}