@laphilosophia/steady-watch 2.0.1 → 2.0.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.
package/bin/steady-watch CHANGED
@@ -1,3 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import './index.js';
3
+ const path = require('path');
4
+ const distPath = path.join(path.dirname(process.argv[1]), '..', 'dist', 'index.js');
5
+ require(distPath);
package/dist/index.d.mts CHANGED
@@ -65,7 +65,7 @@ interface CliOptions {
65
65
  theme?: string;
66
66
  }
67
67
  interface CliArgs {
68
- pattern: string;
68
+ pattern?: string;
69
69
  }
70
70
 
71
71
  type ChalkStyle = (s: string) => string;
package/dist/index.d.ts CHANGED
@@ -65,7 +65,7 @@ interface CliOptions {
65
65
  theme?: string;
66
66
  }
67
67
  interface CliArgs {
68
- pattern: string;
68
+ pattern?: string;
69
69
  }
70
70
 
71
71
  type ChalkStyle = (s: string) => string;
package/dist/index.js CHANGED
@@ -412,8 +412,9 @@ function loadConfig(configPath) {
412
412
  ".steady-watchrc",
413
413
  ".steady-watchrc.json",
414
414
  "steady-watch.config.json"
415
- ].filter(Boolean);
415
+ ];
416
416
  for (const cfgPath of searchPaths) {
417
+ if (!cfgPath) continue;
417
418
  try {
418
419
  const fullPath = import_path2.default.resolve(cfgPath);
419
420
  if (import_fs2.default.existsSync(fullPath)) {
@@ -465,7 +466,7 @@ function mergeOptions(cliArgs, cliOpts, config) {
465
466
  };
466
467
  }
467
468
  function parseCliArgs() {
468
- import_commander.program.name("steady-watch").description("Intelligent file watcher with debouncing and content hashing.").argument("<files>", 'Glob pattern to watch (e.g., "src/**/*.ts")').requiredOption("-c, --cmd <command>", "Command(s) to execute on change (supports quotes)").option("-d, --delay <ms>", "Debounce delay in milliseconds", "300").option("-v, --verbose", "Show hash calculations", false).option("-q, --quiet", "Minimize output", false).option("--ignore <patterns>", "Additional ignore patterns (comma-separated)").option("--ext <extensions>", "Filter by file extensions (e.g., .ts,.tsx)").option("--config <path>", "Path to config file").option("--kill-timeout <ms>", "Force kill process after timeout", "0").option("--retry <count>", "Retry failed command (0 = disabled)", "0").option("--hash <algorithm>", "Hash algorithm (md5, sha1, sha256)", "md5").option("--no-hash", "Use mtime only instead of content hash (fastest)").option("--clear", "Clear screen on each trigger").option("--json", "Output in JSON format").option("--theme <theme>", "Color theme (default, minimal, none)", "default").version("2.0.0").parse();
469
+ import_commander.program.name("steady-watch").description("Intelligent file watcher with debouncing and content hashing.").argument("[files]", 'Glob pattern to watch (e.g., "src/**/*.ts")').option("-c, --cmd <command>", "Command(s) to execute on change (supports quotes)").option("-d, --delay <ms>", "Debounce delay in milliseconds", "300").option("-v, --verbose", "Show hash calculations", false).option("-q, --quiet", "Minimize output", false).option("--ignore <patterns>", "Additional ignore patterns (comma-separated)").option("--ext <extensions>", "Filter by file extensions (e.g., .ts,.tsx)").option("--config <path>", "Path to config file").option("--kill-timeout <ms>", "Force kill process after timeout", "0").option("--retry <count>", "Retry failed command (0 = disabled)", "0").option("--hash <algorithm>", "Hash algorithm (md5, sha1, sha256)", "md5").option("--no-hash", "Use mtime only instead of content hash (fastest)").option("--clear", "Clear screen on each trigger").option("--json", "Output in JSON format").option("--theme <theme>", "Color theme (default, minimal, none)", "default").version("2.0.0").parse();
469
470
  const cliOpts = import_commander.program.opts();
470
471
  const cliArgs = { pattern: import_commander.program.args[0] || "" };
471
472
  return { args: cliArgs, opts: cliOpts };
@@ -505,7 +506,8 @@ Received ${signal}, shutting down...`);
505
506
  process.exit(1);
506
507
  });
507
508
  }
508
- if (require.main === module) {
509
+ var isMain = require.main === module || process.argv[1]?.includes("index.js") || process.argv[1]?.includes("steady-watch");
510
+ if (isMain) {
509
511
  runCli();
510
512
  }
511
513
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/watcher.ts","../src/cli.ts"],"sourcesContent":["export * from './types.js';\nexport * from './theme.js';\nexport { SteadyWatcher, steadyWatch } from './watcher.js';\n\nimport { SteadyWatcher, steadyWatch } from './watcher.js';\nimport { parseCliArgs, loadConfig, mergeOptions } from './cli.js';\n\nexport function runCli(): void {\n const { args, opts } = parseCliArgs();\n const config = loadConfig(opts.config);\n \n if (opts.config && config.cmd) {\n opts.cmd = config.cmd as string;\n }\n\n const options = mergeOptions(args, opts, config);\n \n if (!options.cmd) {\n console.error('Error: Command is required. Use -c option or config file.');\n process.exit(1);\n }\n\n const watcher = new SteadyWatcher(options);\n\n watcher.on('error', (err) => {\n console.error(`Error: ${err.message}`);\n process.exit(1);\n });\n\n watcher.start().catch((err) => {\n console.error(`Failed to start: ${err.message}`);\n process.exit(1);\n });\n\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n await watcher.close();\n process.exit(0);\n };\n\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('uncaughtException', (err) => {\n console.error('Uncaught exception:', err);\n process.exit(1);\n });\n}\n\nif (require.main === module) {\n runCli();\n}\n","import chalk from 'chalk';\nimport { ThemeName } from './types.js';\n\nexport type ChalkStyle = (s: string) => string;\n\nexport interface Theme {\n blue: ChalkStyle;\n green: ChalkStyle;\n yellow: ChalkStyle;\n red: ChalkStyle;\n cyan: ChalkStyle;\n gray: ChalkStyle;\n dim: ChalkStyle;\n bold: ChalkStyle;\n}\n\nexport const themes: Record<ThemeName, Theme> = {\n default: {\n blue: chalk.blue,\n green: chalk.green,\n yellow: chalk.yellow,\n red: chalk.red,\n cyan: chalk.cyan,\n gray: chalk.gray,\n dim: chalk.dim,\n bold: chalk.bold\n },\n minimal: {\n blue: (s: string) => s,\n green: (s: string) => s,\n yellow: (s: string) => s,\n red: (s: string) => s,\n cyan: (s: string) => s,\n gray: (s: string) => s,\n dim: (s: string) => s,\n bold: (s: string) => s\n },\n none: {\n blue: () => '',\n green: () => '',\n yellow: () => '',\n red: () => '',\n cyan: () => '',\n gray: () => '',\n dim: () => '',\n bold: (s: string) => s\n }\n};\n\nexport function getTheme(name: ThemeName): Theme {\n return themes[name] || themes.default;\n}\n","import { ChildProcess, spawn } from 'child_process';\nimport chokidar, { FSWatcher } from 'chokidar';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { EventEmitter } from 'events';\nimport { \n SteadyWatchOptions, \n NormalizedOptions, \n ValidationResult,\n HashAlgorithm,\n ThemeName,\n SteadyWatchEvents\n} from './types.js';\nimport { getTheme, Theme } from './theme.js';\n\nexport class SteadyWatcher extends EventEmitter {\n private options: NormalizedOptions;\n private watcher: FSWatcher | null = null;\n private fileHashes = new Map<string, string>();\n private timeout: NodeJS.Timeout | null = null;\n private isRunning = false;\n private activeProcess: ChildProcess | null = null;\n private killTimer: NodeJS.Timeout | null = null;\n private retryCount = 0;\n private disposed = false;\n private t: Theme;\n\n private static readonly DEFAULT_IGNORE = [/node_modules/, /\\.git/, /dist/, /build/];\n private static readonly VALID_HASH_ALGORITHMS: HashAlgorithm[] = ['md5', 'sha1', 'sha256'];\n private static readonly VALID_THEMES: ThemeName[] = ['default', 'minimal', 'none'];\n\n constructor(options: SteadyWatchOptions) {\n super();\n this.options = this.normalizeOptions(options);\n this.t = getTheme(this.options.theme);\n }\n\n private normalizeOptions(options: SteadyWatchOptions): NormalizedOptions {\n const hash = SteadyWatcher.VALID_HASH_ALGORITHMS.includes(options.hash as HashAlgorithm)\n ? options.hash as HashAlgorithm\n : 'md5';\n \n const theme = SteadyWatcher.VALID_THEMES.includes(options.theme as ThemeName)\n ? options.theme as ThemeName\n : 'default';\n\n const mergedIgnore = [\n ...SteadyWatcher.DEFAULT_IGNORE,\n ...this.normalizeIgnorePatterns(options.ignore || [])\n ];\n\n return {\n pattern: options.pattern,\n cmd: options.cmd,\n delay: Math.max(0, options.delay ?? 300),\n verbose: options.verbose ?? false,\n quiet: options.quiet ?? false,\n ignore: mergedIgnore,\n ext: options.ext || [],\n killTimeout: Math.max(0, options.killTimeout ?? 0),\n retry: Math.max(0, options.retry ?? 0),\n hash,\n mtimeOnly: options.mtimeOnly ?? false,\n clearScreen: options.clearScreen ?? false,\n json: options.json ?? false,\n theme\n };\n }\n\n private normalizeIgnorePatterns(patterns: (string | RegExp)[]): RegExp[] {\n return patterns.map(p => {\n if (p instanceof RegExp) return p;\n try {\n return new RegExp(p);\n } catch {\n return new RegExp(`^${p.replace(/\\*/g, '.*')}$`);\n }\n });\n }\n\n public validate(): ValidationResult {\n const errors: string[] = [];\n\n if (!this.options.pattern) {\n errors.push('Pattern is required');\n }\n\n if (!this.options.cmd) {\n errors.push('Command is required');\n }\n\n if (this.options.delay < 0) {\n errors.push('Delay must be a non-negative number');\n }\n\n if (this.options.killTimeout < 0) {\n errors.push('Kill timeout must be a non-negative number');\n }\n\n if (this.options.retry < 0) {\n errors.push('Retry must be a non-negative number');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n private getEffectivePattern(): string {\n if (this.options.ext.length === 0) {\n return this.options.pattern;\n }\n\n const extGlob = this.options.ext\n .map(e => e.startsWith('.') ? `*${e}` : `*.${e}`)\n .join(',');\n \n const pattern = this.options.pattern;\n return pattern.includes('{')\n ? pattern.replace(/\\}$/, `,${extGlob}}`)\n : `${pattern.replace(/\\/$/, '')}/{${extGlob}}`;\n }\n\n private getHash(filePath: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n \n if (this.options.mtimeOnly) {\n const stats = fs.statSync(filePath);\n return `mtime:${stats.mtimeMs}`;\n }\n \n const content = fs.readFileSync(filePath);\n return crypto.createHash(this.options.hash).update(content).digest('hex');\n } catch {\n return null;\n }\n }\n\n private log(...args: unknown[]): void {\n if (!this.options.quiet && !this.disposed) console.log(...args);\n }\n\n private logVerbose(...args: unknown[]): void {\n if (this.options.verbose && !this.options.quiet && !this.disposed) {\n console.log(...args);\n }\n }\n\n private logJson(type: string, data: Record<string, unknown>): void {\n if (this.options.json && !this.disposed) {\n console.log(JSON.stringify({ timestamp: new Date().toISOString(), type, ...data }));\n }\n }\n\n private timestamp(): string {\n return this.t.gray(`[${new Date().toLocaleTimeString()}]`);\n }\n\n private parseCommand(cmdString: string): { cmd: string; args: string[] } {\n const tokens: string[] = [];\n let current = '';\n let inQuote = false;\n let quoteChar = '';\n let escaped = false;\n\n for (let i = 0; i < cmdString.length; i++) {\n const char = cmdString[i];\n const prevChar = i > 0 ? cmdString[i - 1] : '';\n\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === '\\\\' && !inQuote) {\n escaped = true;\n continue;\n }\n\n if ((char === '\"' || char === \"'\") && !inQuote) {\n inQuote = true;\n quoteChar = char;\n } else if (char === quoteChar && inQuote) {\n inQuote = false;\n quoteChar = '';\n } else if (char === ' ' && !inQuote) {\n if (current) {\n tokens.push(current);\n current = '';\n }\n } else {\n current += char;\n }\n }\n\n if (current) {\n tokens.push(current);\n }\n\n return { cmd: tokens[0] || '', args: tokens.slice(1) };\n }\n\n private runCommand(): void {\n if (this.disposed) return;\n\n if (this.isRunning) {\n this.logVerbose(this.t.yellow('⚠️ Previous command still running, skipping...'));\n this.emit('skip', 'previous command still running');\n return;\n }\n\n if (this.options.clearScreen) {\n console.clear();\n }\n\n this.isRunning = true;\n const retryInfo = this.retryCount > 0 ? ` (Retry ${this.retryCount}/${this.options.retry})` : '';\n this.log(`${this.timestamp()} ${this.t.cyan('🚀 Triggering:')} ${this.t.bold(this.options.cmd)}${retryInfo}`);\n this.logJson('trigger', { command: this.options.cmd, retry: this.retryCount });\n this.emit('trigger', this.options.cmd);\n\n const { cmd, args } = this.parseCommand(this.options.cmd);\n const startTime = Date.now();\n\n this.activeProcess = spawn(cmd, args, {\n stdio: 'inherit',\n shell: true,\n env: { ...process.env }\n });\n\n if (this.options.killTimeout > 0) {\n this.killTimer = setTimeout(() => {\n if (this.activeProcess && !this.disposed) {\n this.log(this.t.yellow(`⚠️ Process timeout (${this.options.killTimeout}ms), force killing...`));\n this.activeProcess.kill('SIGKILL');\n }\n }, this.options.killTimeout);\n }\n\n this.activeProcess.on('error', (err) => {\n this.log(this.t.red(`Process error: ${err.message}`));\n this.emit('error', err);\n });\n\n this.activeProcess.on('close', (code, signal) => {\n if (this.disposed) return;\n\n this.isRunning = false;\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n this.activeProcess = null;\n const duration = ((Date.now() - startTime) / 1000).toFixed(2);\n\n if (code === 0) {\n this.log(`${this.timestamp()} ${this.t.green('✔ Done')} in ${duration}s`);\n this.logJson('done', { duration: parseFloat(duration) });\n this.emit('done', parseFloat(duration));\n this.retryCount = 0;\n } else {\n const exitMessage = signal ? ` (Signal: ${signal})` : ` (Exit code: ${code})`;\n this.log(`${this.timestamp()} ${this.t.red('✘ Failed')}${exitMessage}`);\n this.logJson('failed', { exitCode: code, signal });\n this.emit('fail', code, signal ?? undefined);\n \n if (this.options.retry > 0 && this.retryCount < this.options.retry) {\n this.retryCount++;\n this.log(this.t.yellow(`🔄 Retrying in 1s... (${this.retryCount}/${this.options.retry})`));\n setTimeout(() => this.runCommand(), 1000);\n return;\n }\n this.retryCount = 0;\n }\n this.log(this.t.dim('─'.repeat(40)));\n });\n }\n\n private handleFileChange(filePath: string): void {\n if (this.disposed) return;\n\n const currentHash = this.getHash(filePath);\n const lastHash = this.fileHashes.get(filePath);\n\n if (currentHash === lastHash) {\n this.logVerbose(this.t.gray(`Skipping ghost change: ${path.basename(filePath)}`));\n this.emit('skip', 'content unchanged', filePath);\n return;\n }\n\n if (currentHash) {\n this.fileHashes.set(filePath, currentHash);\n }\n\n this.emit('change', filePath);\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(() => {\n if (!this.disposed) {\n this.log(`${this.timestamp()} ${this.t.yellow('⚡ Change detected:')} ${path.basename(filePath)}`);\n this.logJson('change', { file: path.basename(filePath) });\n this.runCommand();\n }\n }, this.options.delay);\n }\n\n public async start(): Promise<void> {\n const validation = this.validate();\n if (!validation.valid) {\n const errorMsg = validation.errors.join(', ');\n this.log(this.t.red(`Validation error: ${errorMsg}`));\n this.emit('error', new Error(errorMsg));\n throw new Error(errorMsg);\n }\n\n const effectivePattern = this.getEffectivePattern();\n\n this.log(this.t.bold(`\\n🔭 Steady Watch Initialized`));\n this.log(` ${this.t.dim('Pattern:')} ${effectivePattern}`);\n this.log(` ${this.t.dim('Command:')} ${this.options.cmd}`);\n this.log(` ${this.t.dim('Delay:')} ${this.options.delay}ms`);\n if (this.options.quiet) this.log(` ${this.t.dim('Mode:')} quiet`);\n if (this.options.killTimeout > 0) this.log(` ${this.t.dim('Kill:')} ${this.options.killTimeout}ms`);\n if (this.options.retry > 0) this.log(` ${this.t.dim('Retry:')} ${this.options.retry}x`);\n if (this.options.mtimeOnly) this.log(` ${this.t.dim('Hash:')} mtime-only (fastest)`);\n else this.log(` ${this.t.dim('Hash:')} ${this.options.hash}`);\n this.log('');\n\n this.watcher = chokidar.watch(effectivePattern, {\n ignored: this.options.ignore,\n ignoreInitial: false,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100\n }\n });\n\n this.watcher.on('ready', () => {\n this.log(this.t.green('👁️ Watcher ready. Monitoring for changes...'));\n this.logVerbose(this.t.dim(` Tracking ${this.fileHashes.size} file(s)`));\n this.emit('ready');\n });\n\n this.watcher.on('error', (error) => {\n this.log(this.t.red(`Watcher error: ${error.message}`));\n this.emit('error', error);\n });\n\n this.watcher.on('add', (filePath) => {\n if (this.disposed) return;\n const hash = this.getHash(filePath);\n if (hash) this.fileHashes.set(filePath, hash);\n this.logVerbose(this.t.dim(`Indexed: ${path.basename(filePath)}`));\n });\n\n this.watcher.on('change', (filePath) => this.handleFileChange(filePath));\n\n this.watcher.on('unlink', (filePath) => {\n if (this.disposed) return;\n this.fileHashes.delete(filePath);\n this.logVerbose(this.t.dim(`Removed: ${path.basename(filePath)}`));\n });\n }\n\n public async close(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n\n this.log(this.t.yellow('\\n🛑 Shutting down...'));\n this.logJson('shutdown', {});\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n\n if (this.activeProcess) {\n this.activeProcess.kill('SIGTERM');\n this.activeProcess = null;\n }\n\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n\n this.removeAllListeners();\n }\n\n public getTrackedFiles(): string[] {\n return Array.from(this.fileHashes.keys());\n }\n\n public isCurrentlyRunning(): boolean {\n return this.isRunning;\n }\n\n public isDisposed(): boolean {\n return this.disposed;\n }\n}\n\nexport function steadyWatch(options: SteadyWatchOptions): SteadyWatcher {\n return new SteadyWatcher(options);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { program } from 'commander';\nimport { CliOptions, CliArgs, SteadyWatchOptions, HashAlgorithm, ThemeName } from './types.js';\n\nexport function loadConfig(configPath?: string): Record<string, unknown> {\n const searchPaths = [\n configPath,\n '.steady-watchrc',\n '.steady-watchrc.json',\n 'steady-watch.config.json'\n ].filter(Boolean) as string[];\n\n for (const cfgPath of searchPaths) {\n try {\n const fullPath = path.resolve(cfgPath);\n if (fs.existsSync(fullPath)) {\n return JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n }\n } catch {\n continue;\n }\n }\n\n return {};\n}\n\nexport function parseIgnorePatterns(patternString?: string): (string | RegExp)[] {\n if (!patternString) return [];\n return patternString.split(',').map(p => p.trim()).filter(Boolean);\n}\n\nexport function parseExtFilter(extString?: string): string[] {\n if (!extString) return [];\n return extString.split(',').map(e => e.trim()).filter(Boolean);\n}\n\nexport function parseBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return false;\n}\n\nexport function parseNumber(value: unknown, defaultValue: number): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n return defaultValue;\n}\n\nexport function mergeOptions(\n cliArgs: CliArgs,\n cliOpts: CliOptions,\n config: Record<string, unknown>\n): SteadyWatchOptions {\n return {\n pattern: cliArgs.pattern || (config.pattern as string) || '',\n cmd: cliOpts.cmd || (config.cmd as string) || '', \n delay: parseNumber(cliOpts.delay ?? config.delay, 300),\n verbose: parseBoolean(cliOpts.verbose ?? config.verbose),\n quiet: parseBoolean(cliOpts.quiet ?? config.quiet),\n ignore: [...parseIgnorePatterns(cliOpts.ignore), ...(config.ignore as string[] || [])],\n ext: cliOpts.ext ? parseExtFilter(cliOpts.ext) : (config.ext as string[] || []),\n killTimeout: parseNumber(cliOpts.killTimeout ?? config.killTimeout, 0),\n retry: parseNumber(cliOpts.retry ?? config.retry, 0),\n hash: (cliOpts.hash as HashAlgorithm) || (config.hash as HashAlgorithm) || 'md5',\n mtimeOnly: cliOpts.noHash ?? (config.mtimeOnly as boolean) ?? false,\n clearScreen: parseBoolean(cliOpts.clear ?? config.clearScreen),\n json: parseBoolean(cliOpts.json ?? config.json),\n theme: (cliOpts.theme as ThemeName) || (config.theme as ThemeName) || 'default'\n };\n}\n\nexport function parseCliArgs(): { args: CliArgs; opts: CliOptions } {\n program\n .name('steady-watch')\n .description('Intelligent file watcher with debouncing and content hashing.')\n .argument('<files>', 'Glob pattern to watch (e.g., \"src/**/*.ts\")')\n .requiredOption('-c, --cmd <command>', 'Command(s) to execute on change (supports quotes)')\n .option('-d, --delay <ms>', 'Debounce delay in milliseconds', '300')\n .option('-v, --verbose', 'Show hash calculations', false)\n .option('-q, --quiet', 'Minimize output', false)\n .option('--ignore <patterns>', 'Additional ignore patterns (comma-separated)')\n .option('--ext <extensions>', 'Filter by file extensions (e.g., .ts,.tsx)')\n .option('--config <path>', 'Path to config file')\n .option('--kill-timeout <ms>', 'Force kill process after timeout', '0')\n .option('--retry <count>', 'Retry failed command (0 = disabled)', '0')\n .option('--hash <algorithm>', 'Hash algorithm (md5, sha1, sha256)', 'md5')\n .option('--no-hash', 'Use mtime only instead of content hash (fastest)')\n .option('--clear', 'Clear screen on each trigger')\n .option('--json', 'Output in JSON format')\n .option('--theme <theme>', 'Color theme (default, minimal, none)', 'default')\n .version('2.0.0')\n .parse();\n\n const cliOpts = program.opts() as CliOptions;\n const cliArgs: CliArgs = { pattern: program.args[0] || '' };\n\n return { args: cliArgs, opts: cliOpts };\n}\n"],"mappings":"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","names":["chalk","fs","crypto","path","chokidar","import_fs","import_path","path","fs"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/watcher.ts","../src/cli.ts"],"sourcesContent":["export * from './types.js';\nexport * from './theme.js';\nexport { SteadyWatcher, steadyWatch } from './watcher.js';\n\nimport { SteadyWatcher, steadyWatch } from './watcher.js';\nimport { parseCliArgs, loadConfig, mergeOptions } from './cli.js';\n\nexport function runCli(): void {\n const { args, opts } = parseCliArgs();\n const config = loadConfig(opts.config);\n \n if (opts.config && config.cmd) {\n opts.cmd = config.cmd as string;\n }\n\n const options = mergeOptions(args, opts, config);\n \n if (!options.cmd) {\n console.error('Error: Command is required. Use -c option or config file.');\n process.exit(1);\n }\n\n const watcher = new SteadyWatcher(options);\n\n watcher.on('error', (err) => {\n console.error(`Error: ${err.message}`);\n process.exit(1);\n });\n\n watcher.start().catch((err) => {\n console.error(`Failed to start: ${err.message}`);\n process.exit(1);\n });\n\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n await watcher.close();\n process.exit(0);\n };\n\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('uncaughtException', (err) => {\n console.error('Uncaught exception:', err);\n process.exit(1);\n });\n}\n\nconst isMain = require.main === module || process.argv[1]?.includes('index.js') || process.argv[1]?.includes('steady-watch');\n\nif (isMain) {\n runCli();\n}\n","import chalk from 'chalk';\nimport { ThemeName } from './types.js';\n\nexport type ChalkStyle = (s: string) => string;\n\nexport interface Theme {\n blue: ChalkStyle;\n green: ChalkStyle;\n yellow: ChalkStyle;\n red: ChalkStyle;\n cyan: ChalkStyle;\n gray: ChalkStyle;\n dim: ChalkStyle;\n bold: ChalkStyle;\n}\n\nexport const themes: Record<ThemeName, Theme> = {\n default: {\n blue: chalk.blue,\n green: chalk.green,\n yellow: chalk.yellow,\n red: chalk.red,\n cyan: chalk.cyan,\n gray: chalk.gray,\n dim: chalk.dim,\n bold: chalk.bold\n },\n minimal: {\n blue: (s: string) => s,\n green: (s: string) => s,\n yellow: (s: string) => s,\n red: (s: string) => s,\n cyan: (s: string) => s,\n gray: (s: string) => s,\n dim: (s: string) => s,\n bold: (s: string) => s\n },\n none: {\n blue: () => '',\n green: () => '',\n yellow: () => '',\n red: () => '',\n cyan: () => '',\n gray: () => '',\n dim: () => '',\n bold: (s: string) => s\n }\n};\n\nexport function getTheme(name: ThemeName): Theme {\n return themes[name] || themes.default;\n}\n","import { ChildProcess, spawn } from 'child_process';\nimport chokidar, { FSWatcher } from 'chokidar';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { EventEmitter } from 'events';\nimport { \n SteadyWatchOptions, \n NormalizedOptions, \n ValidationResult,\n HashAlgorithm,\n ThemeName,\n SteadyWatchEvents\n} from './types.js';\nimport { getTheme, Theme } from './theme.js';\n\nexport class SteadyWatcher extends EventEmitter {\n private options: NormalizedOptions;\n private watcher: FSWatcher | null = null;\n private fileHashes = new Map<string, string>();\n private timeout: NodeJS.Timeout | null = null;\n private isRunning = false;\n private activeProcess: ChildProcess | null = null;\n private killTimer: NodeJS.Timeout | null = null;\n private retryCount = 0;\n private disposed = false;\n private t: Theme;\n\n private static readonly DEFAULT_IGNORE = [/node_modules/, /\\.git/, /dist/, /build/];\n private static readonly VALID_HASH_ALGORITHMS: HashAlgorithm[] = ['md5', 'sha1', 'sha256'];\n private static readonly VALID_THEMES: ThemeName[] = ['default', 'minimal', 'none'];\n\n constructor(options: SteadyWatchOptions) {\n super();\n this.options = this.normalizeOptions(options);\n this.t = getTheme(this.options.theme);\n }\n\n private normalizeOptions(options: SteadyWatchOptions): NormalizedOptions {\n const hash = SteadyWatcher.VALID_HASH_ALGORITHMS.includes(options.hash as HashAlgorithm)\n ? options.hash as HashAlgorithm\n : 'md5';\n \n const theme = SteadyWatcher.VALID_THEMES.includes(options.theme as ThemeName)\n ? options.theme as ThemeName\n : 'default';\n\n const mergedIgnore = [\n ...SteadyWatcher.DEFAULT_IGNORE,\n ...this.normalizeIgnorePatterns(options.ignore || [])\n ];\n\n return {\n pattern: options.pattern,\n cmd: options.cmd,\n delay: Math.max(0, options.delay ?? 300),\n verbose: options.verbose ?? false,\n quiet: options.quiet ?? false,\n ignore: mergedIgnore,\n ext: options.ext || [],\n killTimeout: Math.max(0, options.killTimeout ?? 0),\n retry: Math.max(0, options.retry ?? 0),\n hash,\n mtimeOnly: options.mtimeOnly ?? false,\n clearScreen: options.clearScreen ?? false,\n json: options.json ?? false,\n theme\n };\n }\n\n private normalizeIgnorePatterns(patterns: (string | RegExp)[]): RegExp[] {\n return patterns.map(p => {\n if (p instanceof RegExp) return p;\n try {\n return new RegExp(p);\n } catch {\n return new RegExp(`^${p.replace(/\\*/g, '.*')}$`);\n }\n });\n }\n\n public validate(): ValidationResult {\n const errors: string[] = [];\n\n if (!this.options.pattern) {\n errors.push('Pattern is required');\n }\n\n if (!this.options.cmd) {\n errors.push('Command is required');\n }\n\n if (this.options.delay < 0) {\n errors.push('Delay must be a non-negative number');\n }\n\n if (this.options.killTimeout < 0) {\n errors.push('Kill timeout must be a non-negative number');\n }\n\n if (this.options.retry < 0) {\n errors.push('Retry must be a non-negative number');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n private getEffectivePattern(): string {\n if (this.options.ext.length === 0) {\n return this.options.pattern;\n }\n\n const extGlob = this.options.ext\n .map(e => e.startsWith('.') ? `*${e}` : `*.${e}`)\n .join(',');\n \n const pattern = this.options.pattern;\n return pattern.includes('{')\n ? pattern.replace(/\\}$/, `,${extGlob}}`)\n : `${pattern.replace(/\\/$/, '')}/{${extGlob}}`;\n }\n\n private getHash(filePath: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n \n if (this.options.mtimeOnly) {\n const stats = fs.statSync(filePath);\n return `mtime:${stats.mtimeMs}`;\n }\n \n const content = fs.readFileSync(filePath);\n return crypto.createHash(this.options.hash).update(content).digest('hex');\n } catch {\n return null;\n }\n }\n\n private log(...args: unknown[]): void {\n if (!this.options.quiet && !this.disposed) console.log(...args);\n }\n\n private logVerbose(...args: unknown[]): void {\n if (this.options.verbose && !this.options.quiet && !this.disposed) {\n console.log(...args);\n }\n }\n\n private logJson(type: string, data: Record<string, unknown>): void {\n if (this.options.json && !this.disposed) {\n console.log(JSON.stringify({ timestamp: new Date().toISOString(), type, ...data }));\n }\n }\n\n private timestamp(): string {\n return this.t.gray(`[${new Date().toLocaleTimeString()}]`);\n }\n\n private parseCommand(cmdString: string): { cmd: string; args: string[] } {\n const tokens: string[] = [];\n let current = '';\n let inQuote = false;\n let quoteChar = '';\n let escaped = false;\n\n for (let i = 0; i < cmdString.length; i++) {\n const char = cmdString[i];\n const prevChar = i > 0 ? cmdString[i - 1] : '';\n\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === '\\\\' && !inQuote) {\n escaped = true;\n continue;\n }\n\n if ((char === '\"' || char === \"'\") && !inQuote) {\n inQuote = true;\n quoteChar = char;\n } else if (char === quoteChar && inQuote) {\n inQuote = false;\n quoteChar = '';\n } else if (char === ' ' && !inQuote) {\n if (current) {\n tokens.push(current);\n current = '';\n }\n } else {\n current += char;\n }\n }\n\n if (current) {\n tokens.push(current);\n }\n\n return { cmd: tokens[0] || '', args: tokens.slice(1) };\n }\n\n private runCommand(): void {\n if (this.disposed) return;\n\n if (this.isRunning) {\n this.logVerbose(this.t.yellow('⚠️ Previous command still running, skipping...'));\n this.emit('skip', 'previous command still running');\n return;\n }\n\n if (this.options.clearScreen) {\n console.clear();\n }\n\n this.isRunning = true;\n const retryInfo = this.retryCount > 0 ? ` (Retry ${this.retryCount}/${this.options.retry})` : '';\n this.log(`${this.timestamp()} ${this.t.cyan('🚀 Triggering:')} ${this.t.bold(this.options.cmd)}${retryInfo}`);\n this.logJson('trigger', { command: this.options.cmd, retry: this.retryCount });\n this.emit('trigger', this.options.cmd);\n\n const { cmd, args } = this.parseCommand(this.options.cmd);\n const startTime = Date.now();\n\n this.activeProcess = spawn(cmd, args, {\n stdio: 'inherit',\n shell: true,\n env: { ...process.env }\n });\n\n if (this.options.killTimeout > 0) {\n this.killTimer = setTimeout(() => {\n if (this.activeProcess && !this.disposed) {\n this.log(this.t.yellow(`⚠️ Process timeout (${this.options.killTimeout}ms), force killing...`));\n this.activeProcess.kill('SIGKILL');\n }\n }, this.options.killTimeout);\n }\n\n this.activeProcess.on('error', (err) => {\n this.log(this.t.red(`Process error: ${err.message}`));\n this.emit('error', err);\n });\n\n this.activeProcess.on('close', (code, signal) => {\n if (this.disposed) return;\n\n this.isRunning = false;\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n this.activeProcess = null;\n const duration = ((Date.now() - startTime) / 1000).toFixed(2);\n\n if (code === 0) {\n this.log(`${this.timestamp()} ${this.t.green('✔ Done')} in ${duration}s`);\n this.logJson('done', { duration: parseFloat(duration) });\n this.emit('done', parseFloat(duration));\n this.retryCount = 0;\n } else {\n const exitMessage = signal ? ` (Signal: ${signal})` : ` (Exit code: ${code})`;\n this.log(`${this.timestamp()} ${this.t.red('✘ Failed')}${exitMessage}`);\n this.logJson('failed', { exitCode: code, signal });\n this.emit('fail', code, signal ?? undefined);\n \n if (this.options.retry > 0 && this.retryCount < this.options.retry) {\n this.retryCount++;\n this.log(this.t.yellow(`🔄 Retrying in 1s... (${this.retryCount}/${this.options.retry})`));\n setTimeout(() => this.runCommand(), 1000);\n return;\n }\n this.retryCount = 0;\n }\n this.log(this.t.dim('─'.repeat(40)));\n });\n }\n\n private handleFileChange(filePath: string): void {\n if (this.disposed) return;\n\n const currentHash = this.getHash(filePath);\n const lastHash = this.fileHashes.get(filePath);\n\n if (currentHash === lastHash) {\n this.logVerbose(this.t.gray(`Skipping ghost change: ${path.basename(filePath)}`));\n this.emit('skip', 'content unchanged', filePath);\n return;\n }\n\n if (currentHash) {\n this.fileHashes.set(filePath, currentHash);\n }\n\n this.emit('change', filePath);\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(() => {\n if (!this.disposed) {\n this.log(`${this.timestamp()} ${this.t.yellow('⚡ Change detected:')} ${path.basename(filePath)}`);\n this.logJson('change', { file: path.basename(filePath) });\n this.runCommand();\n }\n }, this.options.delay);\n }\n\n public async start(): Promise<void> {\n const validation = this.validate();\n if (!validation.valid) {\n const errorMsg = validation.errors.join(', ');\n this.log(this.t.red(`Validation error: ${errorMsg}`));\n this.emit('error', new Error(errorMsg));\n throw new Error(errorMsg);\n }\n\n const effectivePattern = this.getEffectivePattern();\n\n this.log(this.t.bold(`\\n🔭 Steady Watch Initialized`));\n this.log(` ${this.t.dim('Pattern:')} ${effectivePattern}`);\n this.log(` ${this.t.dim('Command:')} ${this.options.cmd}`);\n this.log(` ${this.t.dim('Delay:')} ${this.options.delay}ms`);\n if (this.options.quiet) this.log(` ${this.t.dim('Mode:')} quiet`);\n if (this.options.killTimeout > 0) this.log(` ${this.t.dim('Kill:')} ${this.options.killTimeout}ms`);\n if (this.options.retry > 0) this.log(` ${this.t.dim('Retry:')} ${this.options.retry}x`);\n if (this.options.mtimeOnly) this.log(` ${this.t.dim('Hash:')} mtime-only (fastest)`);\n else this.log(` ${this.t.dim('Hash:')} ${this.options.hash}`);\n this.log('');\n\n this.watcher = chokidar.watch(effectivePattern, {\n ignored: this.options.ignore,\n ignoreInitial: false,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100\n }\n });\n\n this.watcher.on('ready', () => {\n this.log(this.t.green('👁️ Watcher ready. Monitoring for changes...'));\n this.logVerbose(this.t.dim(` Tracking ${this.fileHashes.size} file(s)`));\n this.emit('ready');\n });\n\n this.watcher.on('error', (error) => {\n this.log(this.t.red(`Watcher error: ${error.message}`));\n this.emit('error', error);\n });\n\n this.watcher.on('add', (filePath) => {\n if (this.disposed) return;\n const hash = this.getHash(filePath);\n if (hash) this.fileHashes.set(filePath, hash);\n this.logVerbose(this.t.dim(`Indexed: ${path.basename(filePath)}`));\n });\n\n this.watcher.on('change', (filePath) => this.handleFileChange(filePath));\n\n this.watcher.on('unlink', (filePath) => {\n if (this.disposed) return;\n this.fileHashes.delete(filePath);\n this.logVerbose(this.t.dim(`Removed: ${path.basename(filePath)}`));\n });\n }\n\n public async close(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n\n this.log(this.t.yellow('\\n🛑 Shutting down...'));\n this.logJson('shutdown', {});\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n\n if (this.activeProcess) {\n this.activeProcess.kill('SIGTERM');\n this.activeProcess = null;\n }\n\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n\n this.removeAllListeners();\n }\n\n public getTrackedFiles(): string[] {\n return Array.from(this.fileHashes.keys());\n }\n\n public isCurrentlyRunning(): boolean {\n return this.isRunning;\n }\n\n public isDisposed(): boolean {\n return this.disposed;\n }\n}\n\nexport function steadyWatch(options: SteadyWatchOptions): SteadyWatcher {\n return new SteadyWatcher(options);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { program } from 'commander';\nimport { CliOptions, CliArgs, SteadyWatchOptions, HashAlgorithm, ThemeName } from './types.js';\n\nexport function loadConfig(configPath?: string): Record<string, unknown> {\n const searchPaths = [\n configPath,\n '.steady-watchrc',\n '.steady-watchrc.json',\n 'steady-watch.config.json'\n ];\n\n for (const cfgPath of searchPaths) {\n if (!cfgPath) continue;\n try {\n const fullPath = path.resolve(cfgPath);\n if (fs.existsSync(fullPath)) {\n return JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n }\n } catch {\n continue;\n }\n }\n\n return {};\n}\n\nexport function parseIgnorePatterns(patternString?: string): (string | RegExp)[] {\n if (!patternString) return [];\n return patternString.split(',').map(p => p.trim()).filter(Boolean);\n}\n\nexport function parseExtFilter(extString?: string): string[] {\n if (!extString) return [];\n return extString.split(',').map(e => e.trim()).filter(Boolean);\n}\n\nexport function parseBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return false;\n}\n\nexport function parseNumber(value: unknown, defaultValue: number): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n return defaultValue;\n}\n\nexport function mergeOptions(\n cliArgs: CliArgs,\n cliOpts: CliOptions,\n config: Record<string, unknown>\n): SteadyWatchOptions {\n return {\n pattern: cliArgs.pattern || (config.pattern as string) || '',\n cmd: cliOpts.cmd || (config.cmd as string) || '', \n delay: parseNumber(cliOpts.delay ?? config.delay, 300),\n verbose: parseBoolean(cliOpts.verbose ?? config.verbose),\n quiet: parseBoolean(cliOpts.quiet ?? config.quiet),\n ignore: [...parseIgnorePatterns(cliOpts.ignore), ...(config.ignore as string[] || [])],\n ext: cliOpts.ext ? parseExtFilter(cliOpts.ext) : (config.ext as string[] || []),\n killTimeout: parseNumber(cliOpts.killTimeout ?? config.killTimeout, 0),\n retry: parseNumber(cliOpts.retry ?? config.retry, 0),\n hash: (cliOpts.hash as HashAlgorithm) || (config.hash as HashAlgorithm) || 'md5',\n mtimeOnly: cliOpts.noHash ?? (config.mtimeOnly as boolean) ?? false,\n clearScreen: parseBoolean(cliOpts.clear ?? config.clearScreen),\n json: parseBoolean(cliOpts.json ?? config.json),\n theme: (cliOpts.theme as ThemeName) || (config.theme as ThemeName) || 'default'\n };\n}\n\nexport function parseCliArgs(): { args: CliArgs; opts: CliOptions } {\n program\n .name('steady-watch')\n .description('Intelligent file watcher with debouncing and content hashing.')\n .argument('[files]', 'Glob pattern to watch (e.g., \"src/**/*.ts\")')\n .option('-c, --cmd <command>', 'Command(s) to execute on change (supports quotes)')\n .option('-d, --delay <ms>', 'Debounce delay in milliseconds', '300')\n .option('-v, --verbose', 'Show hash calculations', false)\n .option('-q, --quiet', 'Minimize output', false)\n .option('--ignore <patterns>', 'Additional ignore patterns (comma-separated)')\n .option('--ext <extensions>', 'Filter by file extensions (e.g., .ts,.tsx)')\n .option('--config <path>', 'Path to config file')\n .option('--kill-timeout <ms>', 'Force kill process after timeout', '0')\n .option('--retry <count>', 'Retry failed command (0 = disabled)', '0')\n .option('--hash <algorithm>', 'Hash algorithm (md5, sha1, sha256)', 'md5')\n .option('--no-hash', 'Use mtime only instead of content hash (fastest)')\n .option('--clear', 'Clear screen on each trigger')\n .option('--json', 'Output in JSON format')\n .option('--theme <theme>', 'Color theme (default, minimal, none)', 'default')\n .version('2.0.0')\n .parse();\n\n const cliOpts = program.opts() as CliOptions;\n const cliArgs: CliArgs = { pattern: program.args[0] || '' };\n\n return { args: cliArgs, opts: cliOpts };\n}\n"],"mappings":"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","names":["chalk","fs","crypto","path","chokidar","import_fs","import_path","path","fs"]}
package/dist/index.mjs CHANGED
@@ -379,8 +379,9 @@ function loadConfig(configPath) {
379
379
  ".steady-watchrc",
380
380
  ".steady-watchrc.json",
381
381
  "steady-watch.config.json"
382
- ].filter(Boolean);
382
+ ];
383
383
  for (const cfgPath of searchPaths) {
384
+ if (!cfgPath) continue;
384
385
  try {
385
386
  const fullPath = path2.resolve(cfgPath);
386
387
  if (fs2.existsSync(fullPath)) {
@@ -432,7 +433,7 @@ function mergeOptions(cliArgs, cliOpts, config) {
432
433
  };
433
434
  }
434
435
  function parseCliArgs() {
435
- program.name("steady-watch").description("Intelligent file watcher with debouncing and content hashing.").argument("<files>", 'Glob pattern to watch (e.g., "src/**/*.ts")').requiredOption("-c, --cmd <command>", "Command(s) to execute on change (supports quotes)").option("-d, --delay <ms>", "Debounce delay in milliseconds", "300").option("-v, --verbose", "Show hash calculations", false).option("-q, --quiet", "Minimize output", false).option("--ignore <patterns>", "Additional ignore patterns (comma-separated)").option("--ext <extensions>", "Filter by file extensions (e.g., .ts,.tsx)").option("--config <path>", "Path to config file").option("--kill-timeout <ms>", "Force kill process after timeout", "0").option("--retry <count>", "Retry failed command (0 = disabled)", "0").option("--hash <algorithm>", "Hash algorithm (md5, sha1, sha256)", "md5").option("--no-hash", "Use mtime only instead of content hash (fastest)").option("--clear", "Clear screen on each trigger").option("--json", "Output in JSON format").option("--theme <theme>", "Color theme (default, minimal, none)", "default").version("2.0.0").parse();
436
+ program.name("steady-watch").description("Intelligent file watcher with debouncing and content hashing.").argument("[files]", 'Glob pattern to watch (e.g., "src/**/*.ts")').option("-c, --cmd <command>", "Command(s) to execute on change (supports quotes)").option("-d, --delay <ms>", "Debounce delay in milliseconds", "300").option("-v, --verbose", "Show hash calculations", false).option("-q, --quiet", "Minimize output", false).option("--ignore <patterns>", "Additional ignore patterns (comma-separated)").option("--ext <extensions>", "Filter by file extensions (e.g., .ts,.tsx)").option("--config <path>", "Path to config file").option("--kill-timeout <ms>", "Force kill process after timeout", "0").option("--retry <count>", "Retry failed command (0 = disabled)", "0").option("--hash <algorithm>", "Hash algorithm (md5, sha1, sha256)", "md5").option("--no-hash", "Use mtime only instead of content hash (fastest)").option("--clear", "Clear screen on each trigger").option("--json", "Output in JSON format").option("--theme <theme>", "Color theme (default, minimal, none)", "default").version("2.0.0").parse();
436
437
  const cliOpts = program.opts();
437
438
  const cliArgs = { pattern: program.args[0] || "" };
438
439
  return { args: cliArgs, opts: cliOpts };
@@ -472,7 +473,8 @@ Received ${signal}, shutting down...`);
472
473
  process.exit(1);
473
474
  });
474
475
  }
475
- if (__require.main === module) {
476
+ var isMain = __require.main === module || process.argv[1]?.includes("index.js") || process.argv[1]?.includes("steady-watch");
477
+ if (isMain) {
476
478
  runCli();
477
479
  }
478
480
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/theme.ts","../src/watcher.ts","../src/cli.ts","../src/index.ts"],"sourcesContent":["import chalk from 'chalk';\nimport { ThemeName } from './types.js';\n\nexport type ChalkStyle = (s: string) => string;\n\nexport interface Theme {\n blue: ChalkStyle;\n green: ChalkStyle;\n yellow: ChalkStyle;\n red: ChalkStyle;\n cyan: ChalkStyle;\n gray: ChalkStyle;\n dim: ChalkStyle;\n bold: ChalkStyle;\n}\n\nexport const themes: Record<ThemeName, Theme> = {\n default: {\n blue: chalk.blue,\n green: chalk.green,\n yellow: chalk.yellow,\n red: chalk.red,\n cyan: chalk.cyan,\n gray: chalk.gray,\n dim: chalk.dim,\n bold: chalk.bold\n },\n minimal: {\n blue: (s: string) => s,\n green: (s: string) => s,\n yellow: (s: string) => s,\n red: (s: string) => s,\n cyan: (s: string) => s,\n gray: (s: string) => s,\n dim: (s: string) => s,\n bold: (s: string) => s\n },\n none: {\n blue: () => '',\n green: () => '',\n yellow: () => '',\n red: () => '',\n cyan: () => '',\n gray: () => '',\n dim: () => '',\n bold: (s: string) => s\n }\n};\n\nexport function getTheme(name: ThemeName): Theme {\n return themes[name] || themes.default;\n}\n","import { ChildProcess, spawn } from 'child_process';\nimport chokidar, { FSWatcher } from 'chokidar';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { EventEmitter } from 'events';\nimport { \n SteadyWatchOptions, \n NormalizedOptions, \n ValidationResult,\n HashAlgorithm,\n ThemeName,\n SteadyWatchEvents\n} from './types.js';\nimport { getTheme, Theme } from './theme.js';\n\nexport class SteadyWatcher extends EventEmitter {\n private options: NormalizedOptions;\n private watcher: FSWatcher | null = null;\n private fileHashes = new Map<string, string>();\n private timeout: NodeJS.Timeout | null = null;\n private isRunning = false;\n private activeProcess: ChildProcess | null = null;\n private killTimer: NodeJS.Timeout | null = null;\n private retryCount = 0;\n private disposed = false;\n private t: Theme;\n\n private static readonly DEFAULT_IGNORE = [/node_modules/, /\\.git/, /dist/, /build/];\n private static readonly VALID_HASH_ALGORITHMS: HashAlgorithm[] = ['md5', 'sha1', 'sha256'];\n private static readonly VALID_THEMES: ThemeName[] = ['default', 'minimal', 'none'];\n\n constructor(options: SteadyWatchOptions) {\n super();\n this.options = this.normalizeOptions(options);\n this.t = getTheme(this.options.theme);\n }\n\n private normalizeOptions(options: SteadyWatchOptions): NormalizedOptions {\n const hash = SteadyWatcher.VALID_HASH_ALGORITHMS.includes(options.hash as HashAlgorithm)\n ? options.hash as HashAlgorithm\n : 'md5';\n \n const theme = SteadyWatcher.VALID_THEMES.includes(options.theme as ThemeName)\n ? options.theme as ThemeName\n : 'default';\n\n const mergedIgnore = [\n ...SteadyWatcher.DEFAULT_IGNORE,\n ...this.normalizeIgnorePatterns(options.ignore || [])\n ];\n\n return {\n pattern: options.pattern,\n cmd: options.cmd,\n delay: Math.max(0, options.delay ?? 300),\n verbose: options.verbose ?? false,\n quiet: options.quiet ?? false,\n ignore: mergedIgnore,\n ext: options.ext || [],\n killTimeout: Math.max(0, options.killTimeout ?? 0),\n retry: Math.max(0, options.retry ?? 0),\n hash,\n mtimeOnly: options.mtimeOnly ?? false,\n clearScreen: options.clearScreen ?? false,\n json: options.json ?? false,\n theme\n };\n }\n\n private normalizeIgnorePatterns(patterns: (string | RegExp)[]): RegExp[] {\n return patterns.map(p => {\n if (p instanceof RegExp) return p;\n try {\n return new RegExp(p);\n } catch {\n return new RegExp(`^${p.replace(/\\*/g, '.*')}$`);\n }\n });\n }\n\n public validate(): ValidationResult {\n const errors: string[] = [];\n\n if (!this.options.pattern) {\n errors.push('Pattern is required');\n }\n\n if (!this.options.cmd) {\n errors.push('Command is required');\n }\n\n if (this.options.delay < 0) {\n errors.push('Delay must be a non-negative number');\n }\n\n if (this.options.killTimeout < 0) {\n errors.push('Kill timeout must be a non-negative number');\n }\n\n if (this.options.retry < 0) {\n errors.push('Retry must be a non-negative number');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n private getEffectivePattern(): string {\n if (this.options.ext.length === 0) {\n return this.options.pattern;\n }\n\n const extGlob = this.options.ext\n .map(e => e.startsWith('.') ? `*${e}` : `*.${e}`)\n .join(',');\n \n const pattern = this.options.pattern;\n return pattern.includes('{')\n ? pattern.replace(/\\}$/, `,${extGlob}}`)\n : `${pattern.replace(/\\/$/, '')}/{${extGlob}}`;\n }\n\n private getHash(filePath: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n \n if (this.options.mtimeOnly) {\n const stats = fs.statSync(filePath);\n return `mtime:${stats.mtimeMs}`;\n }\n \n const content = fs.readFileSync(filePath);\n return crypto.createHash(this.options.hash).update(content).digest('hex');\n } catch {\n return null;\n }\n }\n\n private log(...args: unknown[]): void {\n if (!this.options.quiet && !this.disposed) console.log(...args);\n }\n\n private logVerbose(...args: unknown[]): void {\n if (this.options.verbose && !this.options.quiet && !this.disposed) {\n console.log(...args);\n }\n }\n\n private logJson(type: string, data: Record<string, unknown>): void {\n if (this.options.json && !this.disposed) {\n console.log(JSON.stringify({ timestamp: new Date().toISOString(), type, ...data }));\n }\n }\n\n private timestamp(): string {\n return this.t.gray(`[${new Date().toLocaleTimeString()}]`);\n }\n\n private parseCommand(cmdString: string): { cmd: string; args: string[] } {\n const tokens: string[] = [];\n let current = '';\n let inQuote = false;\n let quoteChar = '';\n let escaped = false;\n\n for (let i = 0; i < cmdString.length; i++) {\n const char = cmdString[i];\n const prevChar = i > 0 ? cmdString[i - 1] : '';\n\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === '\\\\' && !inQuote) {\n escaped = true;\n continue;\n }\n\n if ((char === '\"' || char === \"'\") && !inQuote) {\n inQuote = true;\n quoteChar = char;\n } else if (char === quoteChar && inQuote) {\n inQuote = false;\n quoteChar = '';\n } else if (char === ' ' && !inQuote) {\n if (current) {\n tokens.push(current);\n current = '';\n }\n } else {\n current += char;\n }\n }\n\n if (current) {\n tokens.push(current);\n }\n\n return { cmd: tokens[0] || '', args: tokens.slice(1) };\n }\n\n private runCommand(): void {\n if (this.disposed) return;\n\n if (this.isRunning) {\n this.logVerbose(this.t.yellow('⚠️ Previous command still running, skipping...'));\n this.emit('skip', 'previous command still running');\n return;\n }\n\n if (this.options.clearScreen) {\n console.clear();\n }\n\n this.isRunning = true;\n const retryInfo = this.retryCount > 0 ? ` (Retry ${this.retryCount}/${this.options.retry})` : '';\n this.log(`${this.timestamp()} ${this.t.cyan('🚀 Triggering:')} ${this.t.bold(this.options.cmd)}${retryInfo}`);\n this.logJson('trigger', { command: this.options.cmd, retry: this.retryCount });\n this.emit('trigger', this.options.cmd);\n\n const { cmd, args } = this.parseCommand(this.options.cmd);\n const startTime = Date.now();\n\n this.activeProcess = spawn(cmd, args, {\n stdio: 'inherit',\n shell: true,\n env: { ...process.env }\n });\n\n if (this.options.killTimeout > 0) {\n this.killTimer = setTimeout(() => {\n if (this.activeProcess && !this.disposed) {\n this.log(this.t.yellow(`⚠️ Process timeout (${this.options.killTimeout}ms), force killing...`));\n this.activeProcess.kill('SIGKILL');\n }\n }, this.options.killTimeout);\n }\n\n this.activeProcess.on('error', (err) => {\n this.log(this.t.red(`Process error: ${err.message}`));\n this.emit('error', err);\n });\n\n this.activeProcess.on('close', (code, signal) => {\n if (this.disposed) return;\n\n this.isRunning = false;\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n this.activeProcess = null;\n const duration = ((Date.now() - startTime) / 1000).toFixed(2);\n\n if (code === 0) {\n this.log(`${this.timestamp()} ${this.t.green('✔ Done')} in ${duration}s`);\n this.logJson('done', { duration: parseFloat(duration) });\n this.emit('done', parseFloat(duration));\n this.retryCount = 0;\n } else {\n const exitMessage = signal ? ` (Signal: ${signal})` : ` (Exit code: ${code})`;\n this.log(`${this.timestamp()} ${this.t.red('✘ Failed')}${exitMessage}`);\n this.logJson('failed', { exitCode: code, signal });\n this.emit('fail', code, signal ?? undefined);\n \n if (this.options.retry > 0 && this.retryCount < this.options.retry) {\n this.retryCount++;\n this.log(this.t.yellow(`🔄 Retrying in 1s... (${this.retryCount}/${this.options.retry})`));\n setTimeout(() => this.runCommand(), 1000);\n return;\n }\n this.retryCount = 0;\n }\n this.log(this.t.dim('─'.repeat(40)));\n });\n }\n\n private handleFileChange(filePath: string): void {\n if (this.disposed) return;\n\n const currentHash = this.getHash(filePath);\n const lastHash = this.fileHashes.get(filePath);\n\n if (currentHash === lastHash) {\n this.logVerbose(this.t.gray(`Skipping ghost change: ${path.basename(filePath)}`));\n this.emit('skip', 'content unchanged', filePath);\n return;\n }\n\n if (currentHash) {\n this.fileHashes.set(filePath, currentHash);\n }\n\n this.emit('change', filePath);\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(() => {\n if (!this.disposed) {\n this.log(`${this.timestamp()} ${this.t.yellow('⚡ Change detected:')} ${path.basename(filePath)}`);\n this.logJson('change', { file: path.basename(filePath) });\n this.runCommand();\n }\n }, this.options.delay);\n }\n\n public async start(): Promise<void> {\n const validation = this.validate();\n if (!validation.valid) {\n const errorMsg = validation.errors.join(', ');\n this.log(this.t.red(`Validation error: ${errorMsg}`));\n this.emit('error', new Error(errorMsg));\n throw new Error(errorMsg);\n }\n\n const effectivePattern = this.getEffectivePattern();\n\n this.log(this.t.bold(`\\n🔭 Steady Watch Initialized`));\n this.log(` ${this.t.dim('Pattern:')} ${effectivePattern}`);\n this.log(` ${this.t.dim('Command:')} ${this.options.cmd}`);\n this.log(` ${this.t.dim('Delay:')} ${this.options.delay}ms`);\n if (this.options.quiet) this.log(` ${this.t.dim('Mode:')} quiet`);\n if (this.options.killTimeout > 0) this.log(` ${this.t.dim('Kill:')} ${this.options.killTimeout}ms`);\n if (this.options.retry > 0) this.log(` ${this.t.dim('Retry:')} ${this.options.retry}x`);\n if (this.options.mtimeOnly) this.log(` ${this.t.dim('Hash:')} mtime-only (fastest)`);\n else this.log(` ${this.t.dim('Hash:')} ${this.options.hash}`);\n this.log('');\n\n this.watcher = chokidar.watch(effectivePattern, {\n ignored: this.options.ignore,\n ignoreInitial: false,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100\n }\n });\n\n this.watcher.on('ready', () => {\n this.log(this.t.green('👁️ Watcher ready. Monitoring for changes...'));\n this.logVerbose(this.t.dim(` Tracking ${this.fileHashes.size} file(s)`));\n this.emit('ready');\n });\n\n this.watcher.on('error', (error) => {\n this.log(this.t.red(`Watcher error: ${error.message}`));\n this.emit('error', error);\n });\n\n this.watcher.on('add', (filePath) => {\n if (this.disposed) return;\n const hash = this.getHash(filePath);\n if (hash) this.fileHashes.set(filePath, hash);\n this.logVerbose(this.t.dim(`Indexed: ${path.basename(filePath)}`));\n });\n\n this.watcher.on('change', (filePath) => this.handleFileChange(filePath));\n\n this.watcher.on('unlink', (filePath) => {\n if (this.disposed) return;\n this.fileHashes.delete(filePath);\n this.logVerbose(this.t.dim(`Removed: ${path.basename(filePath)}`));\n });\n }\n\n public async close(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n\n this.log(this.t.yellow('\\n🛑 Shutting down...'));\n this.logJson('shutdown', {});\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n\n if (this.activeProcess) {\n this.activeProcess.kill('SIGTERM');\n this.activeProcess = null;\n }\n\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n\n this.removeAllListeners();\n }\n\n public getTrackedFiles(): string[] {\n return Array.from(this.fileHashes.keys());\n }\n\n public isCurrentlyRunning(): boolean {\n return this.isRunning;\n }\n\n public isDisposed(): boolean {\n return this.disposed;\n }\n}\n\nexport function steadyWatch(options: SteadyWatchOptions): SteadyWatcher {\n return new SteadyWatcher(options);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { program } from 'commander';\nimport { CliOptions, CliArgs, SteadyWatchOptions, HashAlgorithm, ThemeName } from './types.js';\n\nexport function loadConfig(configPath?: string): Record<string, unknown> {\n const searchPaths = [\n configPath,\n '.steady-watchrc',\n '.steady-watchrc.json',\n 'steady-watch.config.json'\n ].filter(Boolean) as string[];\n\n for (const cfgPath of searchPaths) {\n try {\n const fullPath = path.resolve(cfgPath);\n if (fs.existsSync(fullPath)) {\n return JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n }\n } catch {\n continue;\n }\n }\n\n return {};\n}\n\nexport function parseIgnorePatterns(patternString?: string): (string | RegExp)[] {\n if (!patternString) return [];\n return patternString.split(',').map(p => p.trim()).filter(Boolean);\n}\n\nexport function parseExtFilter(extString?: string): string[] {\n if (!extString) return [];\n return extString.split(',').map(e => e.trim()).filter(Boolean);\n}\n\nexport function parseBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return false;\n}\n\nexport function parseNumber(value: unknown, defaultValue: number): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n return defaultValue;\n}\n\nexport function mergeOptions(\n cliArgs: CliArgs,\n cliOpts: CliOptions,\n config: Record<string, unknown>\n): SteadyWatchOptions {\n return {\n pattern: cliArgs.pattern || (config.pattern as string) || '',\n cmd: cliOpts.cmd || (config.cmd as string) || '', \n delay: parseNumber(cliOpts.delay ?? config.delay, 300),\n verbose: parseBoolean(cliOpts.verbose ?? config.verbose),\n quiet: parseBoolean(cliOpts.quiet ?? config.quiet),\n ignore: [...parseIgnorePatterns(cliOpts.ignore), ...(config.ignore as string[] || [])],\n ext: cliOpts.ext ? parseExtFilter(cliOpts.ext) : (config.ext as string[] || []),\n killTimeout: parseNumber(cliOpts.killTimeout ?? config.killTimeout, 0),\n retry: parseNumber(cliOpts.retry ?? config.retry, 0),\n hash: (cliOpts.hash as HashAlgorithm) || (config.hash as HashAlgorithm) || 'md5',\n mtimeOnly: cliOpts.noHash ?? (config.mtimeOnly as boolean) ?? false,\n clearScreen: parseBoolean(cliOpts.clear ?? config.clearScreen),\n json: parseBoolean(cliOpts.json ?? config.json),\n theme: (cliOpts.theme as ThemeName) || (config.theme as ThemeName) || 'default'\n };\n}\n\nexport function parseCliArgs(): { args: CliArgs; opts: CliOptions } {\n program\n .name('steady-watch')\n .description('Intelligent file watcher with debouncing and content hashing.')\n .argument('<files>', 'Glob pattern to watch (e.g., \"src/**/*.ts\")')\n .requiredOption('-c, --cmd <command>', 'Command(s) to execute on change (supports quotes)')\n .option('-d, --delay <ms>', 'Debounce delay in milliseconds', '300')\n .option('-v, --verbose', 'Show hash calculations', false)\n .option('-q, --quiet', 'Minimize output', false)\n .option('--ignore <patterns>', 'Additional ignore patterns (comma-separated)')\n .option('--ext <extensions>', 'Filter by file extensions (e.g., .ts,.tsx)')\n .option('--config <path>', 'Path to config file')\n .option('--kill-timeout <ms>', 'Force kill process after timeout', '0')\n .option('--retry <count>', 'Retry failed command (0 = disabled)', '0')\n .option('--hash <algorithm>', 'Hash algorithm (md5, sha1, sha256)', 'md5')\n .option('--no-hash', 'Use mtime only instead of content hash (fastest)')\n .option('--clear', 'Clear screen on each trigger')\n .option('--json', 'Output in JSON format')\n .option('--theme <theme>', 'Color theme (default, minimal, none)', 'default')\n .version('2.0.0')\n .parse();\n\n const cliOpts = program.opts() as CliOptions;\n const cliArgs: CliArgs = { pattern: program.args[0] || '' };\n\n return { args: cliArgs, opts: cliOpts };\n}\n","export * from './types.js';\nexport * from './theme.js';\nexport { SteadyWatcher, steadyWatch } from './watcher.js';\n\nimport { SteadyWatcher, steadyWatch } from './watcher.js';\nimport { parseCliArgs, loadConfig, mergeOptions } from './cli.js';\n\nexport function runCli(): void {\n const { args, opts } = parseCliArgs();\n const config = loadConfig(opts.config);\n \n if (opts.config && config.cmd) {\n opts.cmd = config.cmd as string;\n }\n\n const options = mergeOptions(args, opts, config);\n \n if (!options.cmd) {\n console.error('Error: Command is required. Use -c option or config file.');\n process.exit(1);\n }\n\n const watcher = new SteadyWatcher(options);\n\n watcher.on('error', (err) => {\n console.error(`Error: ${err.message}`);\n process.exit(1);\n });\n\n watcher.start().catch((err) => {\n console.error(`Failed to start: ${err.message}`);\n process.exit(1);\n });\n\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n await watcher.close();\n process.exit(0);\n };\n\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('uncaughtException', (err) => {\n console.error('Uncaught exception:', err);\n process.exit(1);\n });\n}\n\nif (require.main === module) {\n runCli();\n}\n"],"mappings":"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","names":["fs","path"]}
1
+ {"version":3,"sources":["../src/theme.ts","../src/watcher.ts","../src/cli.ts","../src/index.ts"],"sourcesContent":["import chalk from 'chalk';\nimport { ThemeName } from './types.js';\n\nexport type ChalkStyle = (s: string) => string;\n\nexport interface Theme {\n blue: ChalkStyle;\n green: ChalkStyle;\n yellow: ChalkStyle;\n red: ChalkStyle;\n cyan: ChalkStyle;\n gray: ChalkStyle;\n dim: ChalkStyle;\n bold: ChalkStyle;\n}\n\nexport const themes: Record<ThemeName, Theme> = {\n default: {\n blue: chalk.blue,\n green: chalk.green,\n yellow: chalk.yellow,\n red: chalk.red,\n cyan: chalk.cyan,\n gray: chalk.gray,\n dim: chalk.dim,\n bold: chalk.bold\n },\n minimal: {\n blue: (s: string) => s,\n green: (s: string) => s,\n yellow: (s: string) => s,\n red: (s: string) => s,\n cyan: (s: string) => s,\n gray: (s: string) => s,\n dim: (s: string) => s,\n bold: (s: string) => s\n },\n none: {\n blue: () => '',\n green: () => '',\n yellow: () => '',\n red: () => '',\n cyan: () => '',\n gray: () => '',\n dim: () => '',\n bold: (s: string) => s\n }\n};\n\nexport function getTheme(name: ThemeName): Theme {\n return themes[name] || themes.default;\n}\n","import { ChildProcess, spawn } from 'child_process';\nimport chokidar, { FSWatcher } from 'chokidar';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { EventEmitter } from 'events';\nimport { \n SteadyWatchOptions, \n NormalizedOptions, \n ValidationResult,\n HashAlgorithm,\n ThemeName,\n SteadyWatchEvents\n} from './types.js';\nimport { getTheme, Theme } from './theme.js';\n\nexport class SteadyWatcher extends EventEmitter {\n private options: NormalizedOptions;\n private watcher: FSWatcher | null = null;\n private fileHashes = new Map<string, string>();\n private timeout: NodeJS.Timeout | null = null;\n private isRunning = false;\n private activeProcess: ChildProcess | null = null;\n private killTimer: NodeJS.Timeout | null = null;\n private retryCount = 0;\n private disposed = false;\n private t: Theme;\n\n private static readonly DEFAULT_IGNORE = [/node_modules/, /\\.git/, /dist/, /build/];\n private static readonly VALID_HASH_ALGORITHMS: HashAlgorithm[] = ['md5', 'sha1', 'sha256'];\n private static readonly VALID_THEMES: ThemeName[] = ['default', 'minimal', 'none'];\n\n constructor(options: SteadyWatchOptions) {\n super();\n this.options = this.normalizeOptions(options);\n this.t = getTheme(this.options.theme);\n }\n\n private normalizeOptions(options: SteadyWatchOptions): NormalizedOptions {\n const hash = SteadyWatcher.VALID_HASH_ALGORITHMS.includes(options.hash as HashAlgorithm)\n ? options.hash as HashAlgorithm\n : 'md5';\n \n const theme = SteadyWatcher.VALID_THEMES.includes(options.theme as ThemeName)\n ? options.theme as ThemeName\n : 'default';\n\n const mergedIgnore = [\n ...SteadyWatcher.DEFAULT_IGNORE,\n ...this.normalizeIgnorePatterns(options.ignore || [])\n ];\n\n return {\n pattern: options.pattern,\n cmd: options.cmd,\n delay: Math.max(0, options.delay ?? 300),\n verbose: options.verbose ?? false,\n quiet: options.quiet ?? false,\n ignore: mergedIgnore,\n ext: options.ext || [],\n killTimeout: Math.max(0, options.killTimeout ?? 0),\n retry: Math.max(0, options.retry ?? 0),\n hash,\n mtimeOnly: options.mtimeOnly ?? false,\n clearScreen: options.clearScreen ?? false,\n json: options.json ?? false,\n theme\n };\n }\n\n private normalizeIgnorePatterns(patterns: (string | RegExp)[]): RegExp[] {\n return patterns.map(p => {\n if (p instanceof RegExp) return p;\n try {\n return new RegExp(p);\n } catch {\n return new RegExp(`^${p.replace(/\\*/g, '.*')}$`);\n }\n });\n }\n\n public validate(): ValidationResult {\n const errors: string[] = [];\n\n if (!this.options.pattern) {\n errors.push('Pattern is required');\n }\n\n if (!this.options.cmd) {\n errors.push('Command is required');\n }\n\n if (this.options.delay < 0) {\n errors.push('Delay must be a non-negative number');\n }\n\n if (this.options.killTimeout < 0) {\n errors.push('Kill timeout must be a non-negative number');\n }\n\n if (this.options.retry < 0) {\n errors.push('Retry must be a non-negative number');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n private getEffectivePattern(): string {\n if (this.options.ext.length === 0) {\n return this.options.pattern;\n }\n\n const extGlob = this.options.ext\n .map(e => e.startsWith('.') ? `*${e}` : `*.${e}`)\n .join(',');\n \n const pattern = this.options.pattern;\n return pattern.includes('{')\n ? pattern.replace(/\\}$/, `,${extGlob}}`)\n : `${pattern.replace(/\\/$/, '')}/{${extGlob}}`;\n }\n\n private getHash(filePath: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n \n if (this.options.mtimeOnly) {\n const stats = fs.statSync(filePath);\n return `mtime:${stats.mtimeMs}`;\n }\n \n const content = fs.readFileSync(filePath);\n return crypto.createHash(this.options.hash).update(content).digest('hex');\n } catch {\n return null;\n }\n }\n\n private log(...args: unknown[]): void {\n if (!this.options.quiet && !this.disposed) console.log(...args);\n }\n\n private logVerbose(...args: unknown[]): void {\n if (this.options.verbose && !this.options.quiet && !this.disposed) {\n console.log(...args);\n }\n }\n\n private logJson(type: string, data: Record<string, unknown>): void {\n if (this.options.json && !this.disposed) {\n console.log(JSON.stringify({ timestamp: new Date().toISOString(), type, ...data }));\n }\n }\n\n private timestamp(): string {\n return this.t.gray(`[${new Date().toLocaleTimeString()}]`);\n }\n\n private parseCommand(cmdString: string): { cmd: string; args: string[] } {\n const tokens: string[] = [];\n let current = '';\n let inQuote = false;\n let quoteChar = '';\n let escaped = false;\n\n for (let i = 0; i < cmdString.length; i++) {\n const char = cmdString[i];\n const prevChar = i > 0 ? cmdString[i - 1] : '';\n\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === '\\\\' && !inQuote) {\n escaped = true;\n continue;\n }\n\n if ((char === '\"' || char === \"'\") && !inQuote) {\n inQuote = true;\n quoteChar = char;\n } else if (char === quoteChar && inQuote) {\n inQuote = false;\n quoteChar = '';\n } else if (char === ' ' && !inQuote) {\n if (current) {\n tokens.push(current);\n current = '';\n }\n } else {\n current += char;\n }\n }\n\n if (current) {\n tokens.push(current);\n }\n\n return { cmd: tokens[0] || '', args: tokens.slice(1) };\n }\n\n private runCommand(): void {\n if (this.disposed) return;\n\n if (this.isRunning) {\n this.logVerbose(this.t.yellow('⚠️ Previous command still running, skipping...'));\n this.emit('skip', 'previous command still running');\n return;\n }\n\n if (this.options.clearScreen) {\n console.clear();\n }\n\n this.isRunning = true;\n const retryInfo = this.retryCount > 0 ? ` (Retry ${this.retryCount}/${this.options.retry})` : '';\n this.log(`${this.timestamp()} ${this.t.cyan('🚀 Triggering:')} ${this.t.bold(this.options.cmd)}${retryInfo}`);\n this.logJson('trigger', { command: this.options.cmd, retry: this.retryCount });\n this.emit('trigger', this.options.cmd);\n\n const { cmd, args } = this.parseCommand(this.options.cmd);\n const startTime = Date.now();\n\n this.activeProcess = spawn(cmd, args, {\n stdio: 'inherit',\n shell: true,\n env: { ...process.env }\n });\n\n if (this.options.killTimeout > 0) {\n this.killTimer = setTimeout(() => {\n if (this.activeProcess && !this.disposed) {\n this.log(this.t.yellow(`⚠️ Process timeout (${this.options.killTimeout}ms), force killing...`));\n this.activeProcess.kill('SIGKILL');\n }\n }, this.options.killTimeout);\n }\n\n this.activeProcess.on('error', (err) => {\n this.log(this.t.red(`Process error: ${err.message}`));\n this.emit('error', err);\n });\n\n this.activeProcess.on('close', (code, signal) => {\n if (this.disposed) return;\n\n this.isRunning = false;\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n this.activeProcess = null;\n const duration = ((Date.now() - startTime) / 1000).toFixed(2);\n\n if (code === 0) {\n this.log(`${this.timestamp()} ${this.t.green('✔ Done')} in ${duration}s`);\n this.logJson('done', { duration: parseFloat(duration) });\n this.emit('done', parseFloat(duration));\n this.retryCount = 0;\n } else {\n const exitMessage = signal ? ` (Signal: ${signal})` : ` (Exit code: ${code})`;\n this.log(`${this.timestamp()} ${this.t.red('✘ Failed')}${exitMessage}`);\n this.logJson('failed', { exitCode: code, signal });\n this.emit('fail', code, signal ?? undefined);\n \n if (this.options.retry > 0 && this.retryCount < this.options.retry) {\n this.retryCount++;\n this.log(this.t.yellow(`🔄 Retrying in 1s... (${this.retryCount}/${this.options.retry})`));\n setTimeout(() => this.runCommand(), 1000);\n return;\n }\n this.retryCount = 0;\n }\n this.log(this.t.dim('─'.repeat(40)));\n });\n }\n\n private handleFileChange(filePath: string): void {\n if (this.disposed) return;\n\n const currentHash = this.getHash(filePath);\n const lastHash = this.fileHashes.get(filePath);\n\n if (currentHash === lastHash) {\n this.logVerbose(this.t.gray(`Skipping ghost change: ${path.basename(filePath)}`));\n this.emit('skip', 'content unchanged', filePath);\n return;\n }\n\n if (currentHash) {\n this.fileHashes.set(filePath, currentHash);\n }\n\n this.emit('change', filePath);\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(() => {\n if (!this.disposed) {\n this.log(`${this.timestamp()} ${this.t.yellow('⚡ Change detected:')} ${path.basename(filePath)}`);\n this.logJson('change', { file: path.basename(filePath) });\n this.runCommand();\n }\n }, this.options.delay);\n }\n\n public async start(): Promise<void> {\n const validation = this.validate();\n if (!validation.valid) {\n const errorMsg = validation.errors.join(', ');\n this.log(this.t.red(`Validation error: ${errorMsg}`));\n this.emit('error', new Error(errorMsg));\n throw new Error(errorMsg);\n }\n\n const effectivePattern = this.getEffectivePattern();\n\n this.log(this.t.bold(`\\n🔭 Steady Watch Initialized`));\n this.log(` ${this.t.dim('Pattern:')} ${effectivePattern}`);\n this.log(` ${this.t.dim('Command:')} ${this.options.cmd}`);\n this.log(` ${this.t.dim('Delay:')} ${this.options.delay}ms`);\n if (this.options.quiet) this.log(` ${this.t.dim('Mode:')} quiet`);\n if (this.options.killTimeout > 0) this.log(` ${this.t.dim('Kill:')} ${this.options.killTimeout}ms`);\n if (this.options.retry > 0) this.log(` ${this.t.dim('Retry:')} ${this.options.retry}x`);\n if (this.options.mtimeOnly) this.log(` ${this.t.dim('Hash:')} mtime-only (fastest)`);\n else this.log(` ${this.t.dim('Hash:')} ${this.options.hash}`);\n this.log('');\n\n this.watcher = chokidar.watch(effectivePattern, {\n ignored: this.options.ignore,\n ignoreInitial: false,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100\n }\n });\n\n this.watcher.on('ready', () => {\n this.log(this.t.green('👁️ Watcher ready. Monitoring for changes...'));\n this.logVerbose(this.t.dim(` Tracking ${this.fileHashes.size} file(s)`));\n this.emit('ready');\n });\n\n this.watcher.on('error', (error) => {\n this.log(this.t.red(`Watcher error: ${error.message}`));\n this.emit('error', error);\n });\n\n this.watcher.on('add', (filePath) => {\n if (this.disposed) return;\n const hash = this.getHash(filePath);\n if (hash) this.fileHashes.set(filePath, hash);\n this.logVerbose(this.t.dim(`Indexed: ${path.basename(filePath)}`));\n });\n\n this.watcher.on('change', (filePath) => this.handleFileChange(filePath));\n\n this.watcher.on('unlink', (filePath) => {\n if (this.disposed) return;\n this.fileHashes.delete(filePath);\n this.logVerbose(this.t.dim(`Removed: ${path.basename(filePath)}`));\n });\n }\n\n public async close(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n\n this.log(this.t.yellow('\\n🛑 Shutting down...'));\n this.logJson('shutdown', {});\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = null;\n }\n\n if (this.activeProcess) {\n this.activeProcess.kill('SIGTERM');\n this.activeProcess = null;\n }\n\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n\n this.removeAllListeners();\n }\n\n public getTrackedFiles(): string[] {\n return Array.from(this.fileHashes.keys());\n }\n\n public isCurrentlyRunning(): boolean {\n return this.isRunning;\n }\n\n public isDisposed(): boolean {\n return this.disposed;\n }\n}\n\nexport function steadyWatch(options: SteadyWatchOptions): SteadyWatcher {\n return new SteadyWatcher(options);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { program } from 'commander';\nimport { CliOptions, CliArgs, SteadyWatchOptions, HashAlgorithm, ThemeName } from './types.js';\n\nexport function loadConfig(configPath?: string): Record<string, unknown> {\n const searchPaths = [\n configPath,\n '.steady-watchrc',\n '.steady-watchrc.json',\n 'steady-watch.config.json'\n ];\n\n for (const cfgPath of searchPaths) {\n if (!cfgPath) continue;\n try {\n const fullPath = path.resolve(cfgPath);\n if (fs.existsSync(fullPath)) {\n return JSON.parse(fs.readFileSync(fullPath, 'utf-8'));\n }\n } catch {\n continue;\n }\n }\n\n return {};\n}\n\nexport function parseIgnorePatterns(patternString?: string): (string | RegExp)[] {\n if (!patternString) return [];\n return patternString.split(',').map(p => p.trim()).filter(Boolean);\n}\n\nexport function parseExtFilter(extString?: string): string[] {\n if (!extString) return [];\n return extString.split(',').map(e => e.trim()).filter(Boolean);\n}\n\nexport function parseBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return false;\n}\n\nexport function parseNumber(value: unknown, defaultValue: number): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n return defaultValue;\n}\n\nexport function mergeOptions(\n cliArgs: CliArgs,\n cliOpts: CliOptions,\n config: Record<string, unknown>\n): SteadyWatchOptions {\n return {\n pattern: cliArgs.pattern || (config.pattern as string) || '',\n cmd: cliOpts.cmd || (config.cmd as string) || '', \n delay: parseNumber(cliOpts.delay ?? config.delay, 300),\n verbose: parseBoolean(cliOpts.verbose ?? config.verbose),\n quiet: parseBoolean(cliOpts.quiet ?? config.quiet),\n ignore: [...parseIgnorePatterns(cliOpts.ignore), ...(config.ignore as string[] || [])],\n ext: cliOpts.ext ? parseExtFilter(cliOpts.ext) : (config.ext as string[] || []),\n killTimeout: parseNumber(cliOpts.killTimeout ?? config.killTimeout, 0),\n retry: parseNumber(cliOpts.retry ?? config.retry, 0),\n hash: (cliOpts.hash as HashAlgorithm) || (config.hash as HashAlgorithm) || 'md5',\n mtimeOnly: cliOpts.noHash ?? (config.mtimeOnly as boolean) ?? false,\n clearScreen: parseBoolean(cliOpts.clear ?? config.clearScreen),\n json: parseBoolean(cliOpts.json ?? config.json),\n theme: (cliOpts.theme as ThemeName) || (config.theme as ThemeName) || 'default'\n };\n}\n\nexport function parseCliArgs(): { args: CliArgs; opts: CliOptions } {\n program\n .name('steady-watch')\n .description('Intelligent file watcher with debouncing and content hashing.')\n .argument('[files]', 'Glob pattern to watch (e.g., \"src/**/*.ts\")')\n .option('-c, --cmd <command>', 'Command(s) to execute on change (supports quotes)')\n .option('-d, --delay <ms>', 'Debounce delay in milliseconds', '300')\n .option('-v, --verbose', 'Show hash calculations', false)\n .option('-q, --quiet', 'Minimize output', false)\n .option('--ignore <patterns>', 'Additional ignore patterns (comma-separated)')\n .option('--ext <extensions>', 'Filter by file extensions (e.g., .ts,.tsx)')\n .option('--config <path>', 'Path to config file')\n .option('--kill-timeout <ms>', 'Force kill process after timeout', '0')\n .option('--retry <count>', 'Retry failed command (0 = disabled)', '0')\n .option('--hash <algorithm>', 'Hash algorithm (md5, sha1, sha256)', 'md5')\n .option('--no-hash', 'Use mtime only instead of content hash (fastest)')\n .option('--clear', 'Clear screen on each trigger')\n .option('--json', 'Output in JSON format')\n .option('--theme <theme>', 'Color theme (default, minimal, none)', 'default')\n .version('2.0.0')\n .parse();\n\n const cliOpts = program.opts() as CliOptions;\n const cliArgs: CliArgs = { pattern: program.args[0] || '' };\n\n return { args: cliArgs, opts: cliOpts };\n}\n","export * from './types.js';\nexport * from './theme.js';\nexport { SteadyWatcher, steadyWatch } from './watcher.js';\n\nimport { SteadyWatcher, steadyWatch } from './watcher.js';\nimport { parseCliArgs, loadConfig, mergeOptions } from './cli.js';\n\nexport function runCli(): void {\n const { args, opts } = parseCliArgs();\n const config = loadConfig(opts.config);\n \n if (opts.config && config.cmd) {\n opts.cmd = config.cmd as string;\n }\n\n const options = mergeOptions(args, opts, config);\n \n if (!options.cmd) {\n console.error('Error: Command is required. Use -c option or config file.');\n process.exit(1);\n }\n\n const watcher = new SteadyWatcher(options);\n\n watcher.on('error', (err) => {\n console.error(`Error: ${err.message}`);\n process.exit(1);\n });\n\n watcher.start().catch((err) => {\n console.error(`Failed to start: ${err.message}`);\n process.exit(1);\n });\n\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n await watcher.close();\n process.exit(0);\n };\n\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('uncaughtException', (err) => {\n console.error('Uncaught exception:', err);\n process.exit(1);\n });\n}\n\nconst isMain = require.main === module || process.argv[1]?.includes('index.js') || process.argv[1]?.includes('steady-watch');\n\nif (isMain) {\n runCli();\n}\n"],"mappings":"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","names":["fs","path"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laphilosophia/steady-watch",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Intelligent file watcher with content hashing and debouncing. No more ghost rebuilds.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -20,10 +20,11 @@
20
20
  "steady-watch": "./bin/steady-watch",
21
21
  "sw": "./bin/steady-watch"
22
22
  },
23
- "files": [
24
- "dist",
25
- "bin"
26
- ],
23
+ "files": [
24
+ "dist",
25
+ "bin",
26
+ "steady-watch.config.json"
27
+ ],
27
28
  "keywords": [
28
29
  "watch",
29
30
  "watcher",
@@ -0,0 +1,4 @@
1
+ {
2
+ "pattern": "src/**/*.ts",
3
+ "cmd": "npm run build"
4
+ }