/** * Skill Hot Reloader * * Watches skill directories for file changes and hot-reloads skills * without requiring server restart. Uses debouncing to prevent * rapid reload storms. */ import { EventEmitter } from 'events'; import type { Logger } from '../observability/logger.js'; import type { SkillLoader } from './skill-loader.js'; import type { SkillsConfig, SkillManagerEvents } from './types.js'; /** * Watches skill directories and hot-reloads on changes. * Supports multiple watched directories with debounced reload. */ export declare class SkillHotReloader extends EventEmitter { private watchers; private loader; private config; private logger; private debounceTimers; private debounceMs; private isRunning; constructor(loader: SkillLoader, config: SkillsConfig, logger: Logger); /** * Start watching all configured skill directories. * Creates watchers for each search path. */ start(): void; /** * Stop watching all directories. * Cleans up watchers and pending timers. */ stop(): void; /** * Watch a specific directory for changes. * Creates recursive watcher if directory exists. * * @param dirPath - Directory path to watch */ watchDirectory(dirPath: string): void; /** * Ensure directory exists, creating it if necessary. */ private ensureDirectoryExists; /** * Create a file watcher for a directory. */ private createWatcher; /** * Handle file change event from watcher. * Debounces rapid changes and filters to skill files. */ private handleFileChange; /** * Schedule a debounced reload for a file. * Cancels any pending reload for the same file. * * @param filePath - File path to reload */ private scheduleReload; /** * Reload a skill file. * Handles file creation, modification, and deletion. */ private reloadFile; /** * Check if a file exists. */ private fileExists; /** * Find skill name by source path. */ private findSkillByPath; /** * Check if filename matches skill file patterns. */ private isSkillFile; /** * Expand ~ in paths to home directory. */ private expandPath; /** * Get list of currently watched directories. */ getWatchedPaths(): string[]; /** * Emit a reload event. */ private emitReloadEvent; /** * Set debounce delay (for testing). */ setDebounceMs(ms: number): void; /** * Check if hot reloader is running. */ get running(): boolean; } export interface SkillHotReloader { on(event: K, listener: (payload: SkillManagerEvents[K]) => void): this; emit(event: K, payload: SkillManagerEvents[K]): boolean; } //# sourceMappingURL=hot-reloader.d.ts.map