CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sane

Fast, small, and reliable file system watcher with multiple monitoring strategies.

Pending
Overview
Eval results
Files

cli.mddocs/

Command Line Interface

CLI tool for running commands when files change, with support for throttling and various watch modes. Perfect for development workflows, build automation, and continuous testing.

Capabilities

Basic Command

The CLI watches a directory and executes a command whenever files change.

sane <command> [...directory] [options]

Arguments:

  • <command> - Shell command to execute when files change (required)
  • [directory] - Directory to watch (optional, defaults to current directory)

Basic Examples:

# Watch current directory, run tests on any change
sane 'npm test'

# Watch specific directory
sane 'npm run build' src/

# Run linter when JavaScript files change
sane 'eslint src/' --glob='**/*.js'

Watch Options

Control which files are watched and how they're filtered.

--glob=<pattern>, -g    # Glob pattern(s) to watch
--ignored=<pattern>, -i # Pattern(s) to ignore
--dot, -d              # Watch dot files

Examples:

# Watch only CSS files
sane 'sass compile' --glob='**/*.scss'

# Watch multiple file types
sane 'npm run build' --glob='**/*.js' --glob='**/*.css'

# Ignore specific directories
sane 'npm test' --ignored='node_modules/**' --ignored='dist/**'

# Watch dot files (like .env files)
sane 'npm run env-check' --dot

Watcher Mode Options

Choose the file watching strategy based on your environment.

--poll, -p                          # Use polling mode
--watchman                          # Use Watchman mode (note: -w conflicts with --wait)  
--watchman-path=<path>              # Custom Watchman binary path

Examples:

# Use polling (good for virtual environments)
sane 'npm test' --poll

# Use Watchman for large projects
sane 'npm run build' --watchman

# Custom Watchman path
sane 'npm test' --watchman --watchman-path=/usr/local/bin/watchman

Execution Control Options

Control when and how the command executes.

--wait=<seconds>, -w    # Throttle command execution (note: -w conflicts with --watchman)
--only-changes, -o      # Run command only on changes (skip initial run)
--quiet, -q            # Disable console output

Examples:

# Wait 3 seconds between command executions
sane 'npm run build' --wait=3

# Only run on file changes, not at startup
sane 'npm test' --only-changes

# Suppress sane's output messages
sane 'npm run build' --quiet

Usage Patterns

Development Workflows

# Live reload development server
sane 'npm run dev' src/ --glob='**/*.js' --wait=1

# Auto-compile TypeScript
sane 'tsc' --glob='**/*.ts' --ignored='**/*.d.ts'

# Run tests on source changes
sane 'npm test' src/ test/ --glob='**/*.js' --only-changes

Build Automation

# Rebuild CSS when SCSS changes
sane 'sass src/styles:dist/css' --glob='**/*.scss'

# Lint and format code
sane 'npm run lint && npm run format' --glob='**/*.js'

# Generate documentation
sane 'jsdoc src/' --glob='**/*.js' --wait=5

File Processing

# Optimize images when added
sane 'imagemin src/images/* --out-dir=dist/images' --glob='**/*.{jpg,png,gif}'

# Copy assets to build directory
sane 'cp -r src/assets/* dist/' src/assets/ --wait=2

# Update translation files
sane 'i18n-extract' --glob='**/*.js' --ignored='**/*.spec.js'

Command Output

The CLI provides informative output about its operations:

$ sane 'echo "Files changed!"' src/ --glob='**/*.js'
Watching: /path/to/project/src/**/*.js
ready
Change detected in: src/main.js
Files changed!

With --quiet flag:

$ sane 'echo "Files changed!"' --quiet
Files changed!

Error Handling

The CLI handles various error conditions gracefully:

  • Invalid command: Exits with helpful usage message
  • Directory not found: Shows error and exits
  • Command execution failure: Shows command error but continues watching
  • Watcher initialization failure: Shows error and attempts fallback modes

CLI Limitations

Flag Conflict: The CLI implementation has a bug where the -w flag is mapped to both --wait and --watchman options. When using -w, the last parsed option will take precedence. To avoid conflicts:

  • Use full flag names: --wait=3 and --watchman
  • Or be aware that -w will activate both wait and watchman modes simultaneously

Environment Integration

Package.json Scripts

{
  "scripts": {
    "watch": "sane 'npm run build' src/ --glob='**/*.js'",
    "watch:test": "sane 'npm test' --only-changes --quiet",
    "watch:scss": "sane 'sass compile' --glob='**/*.scss' --wait=1"
  }
}

Makefile Integration

watch:
	sane 'make build' src/ --glob='**/*.js'

watch-test:
	sane 'make test' --only-changes

.PHONY: watch watch-test

Shell Aliases

# .bashrc or .zshrc
alias watch-js='sane "npm test" --glob="**/*.js" --only-changes'
alias watch-build='sane "npm run build" --wait=2'

Advanced Usage

Complex Commands

# Multiple commands with conditional logic
sane 'npm run lint && npm test && npm run build' --wait=3

# Using shell operators
sane 'npm test || echo "Tests failed!"' --only-changes

# Background processes
sane 'npm run build &' --wait=1

Directory-Specific Watching

# Watch specific subdirectories
sane 'npm run build-components' src/components/ --glob='**/*.jsx'
sane 'npm run build-styles' src/styles/ --glob='**/*.scss'

# Multiple directory patterns
sane 'npm test' --glob='src/**/*.js' --glob='test/**/*.js'

Integration with External Tools

# With Docker
sane 'docker-compose restart api' api/ --glob='**/*.js' --wait=5

# With PM2
sane 'pm2 restart app' --only-changes --quiet

# With systemd
sane 'sudo systemctl reload nginx' config/ --glob='**/*.conf' --wait=10

Install with Tessl CLI

npx tessl i tessl/npm-sane

docs

cli.md

core-factory.md

index.md

watcher-modes.md

tile.json