{"id":34836919,"url":"https://github.com/rodrigogs/vibewatch","last_synced_at":"2026-05-25T19:32:52.071Z","repository":{"id":318099652,"uuid":"1069993998","full_name":"rodrigogs/vibewatch","owner":"rodrigogs","description":"A file watcher utility with glob pattern support and event-specific commands","archived":false,"fork":false,"pushed_at":"2025-10-17T17:27:33.000Z","size":209,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-27T01:39:49.463Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rodrigogs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-05T03:25:37.000Z","updated_at":"2025-10-17T17:27:37.000Z","dependencies_parsed_at":"2025-10-05T05:35:55.902Z","dependency_job_id":"9f674238-c7d3-476d-92e2-0298258a720a","html_url":"https://github.com/rodrigogs/vibewatch","commit_stats":null,"previous_names":["rodrigogs/vibewatch"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/rodrigogs/vibewatch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigogs%2Fvibewatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigogs%2Fvibewatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigogs%2Fvibewatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigogs%2Fvibewatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rodrigogs","download_url":"https://codeload.github.com/rodrigogs/vibewatch/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigogs%2Fvibewatch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33490636,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-25T14:31:05.219Z","status":"ssl_error","status_checked_at":"2026-05-25T14:31:02.878Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-25T16:05:50.937Z","updated_at":"2026-05-25T19:32:52.029Z","avatar_url":"https://github.com/rodrigogs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# VibeWatch\n\n[![CI](https://github.com/rodrigogs/vibewatch/actions/workflows/ci.yml/badge.svg)](https://github.com/rodrigogs/vibewatch/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/rodrigogs/vibewatch/branch/master/graph/badge.svg)](https://codecov.io/gh/rodrigogs/vibewatch)\n[![Crates.io](https://img.shields.io/crates/v/vibewatch.svg)](https://crates.io/crates/vibewatch)\n[![Downloads](https://img.shields.io/crates/d/vibewatch.svg)](https://crates.io/crates/vibewatch)\n[![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)\n[![Rust Version](https://img.shields.io/badge/rust-1.89.0+-orange.svg)](https://www.rust-lang.org)\n\nA fast and extensible file watcher utility built in Rust with glob pattern support and cross-platform compatibility.\n\n## Features\n\n- **Custom command execution**: Run commands on file changes with event-specific triggers (`--on-create`, `--on-modify`, `--on-delete`, `--on-change`)\n- **Template substitution**: Use `{file_path}`, `{relative_path}`, `{absolute_path}`, `{event_type}` in commands\n- **Structured logging**: Objective, timestamp-based logs with exit codes for monitoring and automation\n- **Cross-platform file watching**: Fully tested on Linux, macOS, and Windows with platform-specific event handling\n- **Glob pattern support**: Include and exclude files using glob patterns like `*.rs`, `node_modules/**`\n- **Extensible architecture**: Clean separation of concerns for easy feature additions\n- **Fast performance**: Built in Rust for minimal resource usage\n- **Flexible CLI**: Intuitive command-line interface with verbose logging and quiet mode\n- **Comprehensive testing**: 90.95% code coverage with 187 tests covering unit, filesystem, and integration scenarios\n\n## Installation\n\n### From crates.io (Recommended)\n\n```bash\ncargo install vibewatch\n```\n\n### From Binary Releases (Recommended for Production)\n\nDownload pre-built binaries from the [latest release](https://github.com/rodrigogs/vibewatch/releases/latest).\n\n**Available platforms:**\n- **Linux**: x86_64, ARM64 (`.tar.gz`)\n- **macOS**: Intel (x86_64), Apple Silicon (ARM64) (`.tar.gz`)\n- **Windows**: x64 (`.zip`)\n\n```bash\n# Example: Linux x86_64\nwget https://github.com/rodrigogs/vibewatch/releases/latest/download/vibewatch-x86_64-unknown-linux-gnu.tar.gz\ntar -xzf vibewatch-x86_64-unknown-linux-gnu.tar.gz\nsudo mv vibewatch /usr/local/bin/\n\n# Example: macOS ARM (Apple Silicon)\nwget https://github.com/rodrigogs/vibewatch/releases/latest/download/vibewatch-aarch64-apple-darwin.tar.gz\ntar -xzf vibewatch-aarch64-apple-darwin.tar.gz\nsudo mv vibewatch /usr/local/bin/\n```\n\n### From Source\n\nMake sure you have Rust installed via `mise` or `rustup`:\n\n```bash\n# Clone and build\ngit clone https://github.com/rodrigogs/vibewatch.git\ncd vibewatch\ncargo build --release\n```\n\n## ⚡ Performance\n\nvibewatch is built in Rust for minimal resource usage and fast execution:\n\n- **Efficient memory usage** - Static strings and optimized path handling minimize allocations\n- **Async event processing** - Non-blocking command execution via tokio\n- **Smart debouncing** - Prevents redundant commands from rapid file changes (configurable with `--debounce`)\n- **Fast pattern matching** - Compiled glob patterns for quick file filtering\n- **Lightweight binary** - Single executable, no runtime dependencies\n\n### Benchmarks\n\nBenchmark the core operations to verify performance on your system:\n\n```bash\ncargo bench                               # Run all benchmarks\ncargo bench --bench template_substitution # Specific suite\ncargo bench --bench pattern_matching      # Pattern matching performance\n```\n\nThe benchmark suite measures:\n- **Template substitution** - Variable replacement in command strings\n- **Path normalization** - Cross-platform path handling\n- **Pattern matching** - Glob compilation and file filtering speed\n\nResults are compared against baseline measurements to track performance over time.\n\n## Usage\n\n### Command Execution on File Changes\n\nThe primary use case is executing commands when files change:\n\n```bash\n# Run tests on any change\nvibewatch . --on-change \"npm test\"\n\n# Format Rust files when modified\nvibewatch src --include \"*.rs\" --on-modify \"rustfmt {file_path}\"\n\n# Run linter on TypeScript files (using brace expansion)\nvibewatch . --include \"*.{ts,tsx}\" --exclude \"node_modules/**\" --on-modify \"npx eslint {file_path} --fix\"\n\n# Different commands for different events\nvibewatch src \\\n  --on-create \"git add {file_path}\" \\\n  --on-modify \"cargo check\" \\\n  --on-delete \"echo Removed: {relative_path}\"\n```\n\n**Available Templates:**\n- `{file_path}` - Full path to the changed file\n- `{relative_path}` - Path relative to watched directory\n- `{absolute_path}` - Absolute path to the changed file\n- `{event_type}` - Type of event (create, modify, delete)\n\n**Brace Expansion:** You can use brace expansion syntax for convenience with both `--include` and `--exclude` patterns:\n```bash\n# Include patterns - these are equivalent:\nvibewatch . --include \"*.{ts,tsx}\"\nvibewatch . --include \"*.ts\" --include \"*.tsx\"\n\n# Works with multiple extensions:\nvibewatch . --include \"*.{js,jsx,ts,tsx}\"\n\n# Works with paths:\nvibewatch . --include \"src/**/*.{rs,toml}\"\n\n# Exclude patterns - these are equivalent:\nvibewatch . --exclude \"{target,dist,node_modules}/**\"\nvibewatch . --exclude \"target/**\" --exclude \"dist/**\" --exclude \"node_modules/**\"\n\n# Combined include and exclude with brace expansion:\nvibewatch . --include \"src/**/*.{rs,toml}\" --exclude \"{target,build}/**\"\n```\n\n### Watch-Only Mode\n\nWatch a directory and log all file changes (no commands):\n\n```bash\nvibewatch /path/to/directory\n```\n\n### Include Patterns\n\nWatch only specific file types:\n\n```bash\nvibewatch /path/to/directory --include \"*.rs\" --include \"*.ts\"\n```\n\n### Exclude Patterns\n\nIgnore common directories and files:\n\n```bash\nvibewatch /path/to/directory --exclude \"node_modules/**\" --exclude \".git/**\" --exclude \"target/**\"\n```\n\n### Combined Patterns\n\nUse both include and exclude patterns:\n\n```bash\nvibewatch . \\\n  --include \"*.rs\" \\\n  --include \"*.ts\" \\\n  --include \"*.tsx\" \\\n  --exclude \"target/**\" \\\n  --exclude \"node_modules/**\" \\\n  --verbose\n```\n\n### Options\n\n**Directory:**\n- `\u003cDIRECTORY\u003e`: Directory to watch (can be relative or absolute)\n\n**Command Execution:**\n- `--on-create \u003cCOMMAND\u003e`: Run command when files are created\n- `--on-modify \u003cCOMMAND\u003e`: Run command when files are modified\n- `--on-delete \u003cCOMMAND\u003e`: Run command when files are deleted\n- `--on-change \u003cCOMMAND\u003e`: Run command on any file change (fallback)\n\n**Filtering:**\n- `-i, --include \u003cPATTERN\u003e`: Include patterns like `*.ts`, `*.rs` (use multiple times for multiple patterns)\n- `-e, --exclude \u003cPATTERN\u003e`: Exclude patterns like `node_modules/**`, `.git/**`, `.next/**`\n\n**General:**\n- `-v, --verbose`: Enable verbose output with debug logging\n- `-q, --quiet`: Suppress command output (only show file events and status)\n- `-h, --help`: Show help message\n- `-V, --version`: Show version information\n\n### Structured Logging (v0.4.0+)\n\nvibewatch provides objective, timestamp-based logs for monitoring and automation:\n\n**File Events:**\n```\n[2025-10-06T14:23:15] [CREATED] src/main.rs\n[2025-10-06T14:23:16] [MODIFIED] src/watcher.rs\n[2025-10-06T14:23:17] [DELETED] tmp/test.txt\n```\n\n**Command Execution:**\n```\n[2025-10-06T14:23:15] Executing command: cargo build\n\u003ccommand output appears here\u003e\n[2025-10-06T14:23:18] Command succeeded (exit code: 0)\n```\n\n**Command Failure:**\n```\n[2025-10-06T14:23:19] Executing command: cargo check\n\u003cerror output appears here\u003e\n[2025-10-06T14:23:20] Command failed (exit code: 1)\n```\n\n**Features:**\n- ISO 8601 timestamps for sortable, parseable logs\n- Uppercase event types (CREATED, MODIFIED, DELETED, CHANGED)\n- Exit codes shown for all command executions\n- Grep-friendly format (all lines start with `[YYYY-MM-DD`)\n- Use `--quiet` to suppress command output, keeping only events and status\n\n## Examples\n\n### Auto-format TypeScript on save\n\n```bash\nvibewatch src \\\n  --include \"*.{ts,tsx}\" \\\n  --exclude \"node_modules/**\" --exclude \"dist/**\" \\\n  --on-modify \"npx prettier --write {file_path}\"\n```\n\n### Run Rust tests on file changes\n\n```bash\nvibewatch . \\\n  --include \"*.rs\" --include \"Cargo.toml\" \\\n  --exclude \"target/**\" \\\n  --on-change \"cargo test\"\n```\n\n### Rebuild documentation on changes\n\n```bash\nvibewatch docs \\\n  --include \"*.md\" --include \"*.rst\" \\\n  --exclude \"_build/**\" \\\n  --on-change \"mdbook build\"\n```\n\n### Watch and restart development server\n\n```bash\nvibewatch src \\\n  --include \"*.js\" --include \"*.json\" \\\n  --exclude \"node_modules/**\" \\\n  --on-change \"pkill -f 'node server.js' \u0026\u0026 node server.js \u0026\"\n```\n\n### Auto-commit on file creation\n\n```bash\nvibewatch src \\\n  --on-create \"git add {file_path} \u0026\u0026 git commit -m 'Add {relative_path}'\"\n```\n\n## Architecture\n\nThe application is structured for extensibility:\n\n- **`main.rs`**: CLI argument parsing and application entry point\n- **`watcher.rs`**: Core file watching logic using the `notify` crate\n- **`filter.rs`**: Glob pattern matching for include/exclude functionality\n\n## Common Glob Patterns\n\n### Exclude Patterns\n- `node_modules/**` - Node.js dependencies\n- `.git/**` - Git repository files\n- `.next/**` - Next.js build files\n- `target/**` - Rust build directory\n- `dist/**` - Build output directory\n- `{target,dist,build}/**` - Multiple build directories (brace expansion)\n- `*.tmp` - Temporary files\n- `*.swp` - Vim swap files\n- `*.{tmp,swp,bak}` - Multiple temporary file types (brace expansion)\n\n### Include Patterns\n- `*.rs` - Rust source files\n- `*.{ts,tsx}` - TypeScript files (brace expansion supported)\n- `*.{js,jsx}` - JavaScript files (brace expansion supported)\n- `*.py` - Python files\n- `*.go` - Go files\n- `*.{cpp,c,h}` - C/C++ files (brace expansion supported)\n- `*.md` - Markdown files\n\n**Note:** Brace expansion like `*.{ext1,ext2}` or `{dir1,dir2}/**` works with both `--include` and `--exclude` patterns. The syntax is automatically expanded to multiple patterns before glob compilation. You can also use multiple flags if you prefer explicit patterns.\n\n## Future Enhancements\n\nThe following features are planned for future releases:\n\n- **Configuration file support**: Store watch patterns and commands in `.vibewatch.toml`\n- **Ignore file support**: Respect `.gitignore`, `.watchignore` patterns\n\n## Requirements\n\n- Rust 1.70+ (managed via `mise`)\n- Unix-like system (macOS, Linux) or Windows\n\n## Development\n\n### Quick Start with Just\n\nThe project uses [`just`](https://github.com/casey/just) for task automation:\n\n```bash\n# Install just (if not already installed)\ncargo install just\n# or: brew install just\n\n# List all available tasks\njust --list\n\n# Common tasks\njust test              # Run all tests\njust coverage          # Generate coverage report\njust lint              # Run linter\njust check             # Run all checks (fmt, lint, test)\njust demo              # Run vibewatch on src/ directory\n```\n\n### Running Tests\n\n```bash\n# Run all tests (187 total: 140 unit + 21 filesystem + 26 integration)\ncargo test\n# or: just test\n\n# Run tests with output\ncargo test -- --nocapture\n# or: just test-verbose\n\n# Run specific test suite\ncargo test --test it  # Integration tests only\n# or: just test-integration test_name\n```\n\n### Code Coverage\n\nThe project maintains **90.95% code coverage** (1096/1205 lines):\n\n```bash\n# Generate coverage report\ncargo llvm-cov --all-features --workspace --html\n\n# View report\nopen target/llvm-cov/html/index.html\n```\n\n**Coverage by file:**\n- `filter.rs`: 100.00% (177/177) ✅\n- `main.rs`: 97.67% (252/258) ✅\n- `watcher.rs`: 86.62% (667/770) ✅\n\n\u003e **Note:** The watcher.rs coverage is lower due to command execution happening in spawned async tasks that are harder to test in unit tests. All command execution logic is thoroughly tested through our comprehensive integration test suite.\n\n### Development Commands\n\n```bash\n# Run with debug logging\nRUST_LOG=debug cargo run -- /path/to/directory --verbose\n\n# Build for release\ncargo build --release\n\n# Run linter\ncargo clippy\n\n# Format code\ncargo fmt\n```\n\n## Contributing\n\n### Commit Message Convention\n\nThis project uses [Conventional Commits](https://www.conventionalcommits.org/) for automated versioning and changelog generation.\n\n**Format**: `\u003ctype\u003e(\u003coptional scope\u003e): \u003cdescription\u003e`\n\n**Types:**\n- `feat:` - New feature (triggers minor version bump)\n- `fix:` - Bug fix (triggers patch version bump)\n- `docs:` - Documentation changes\n- `chore:` - Maintenance tasks\n- `refactor:` - Code refactoring\n- `test:` - Adding or updating tests\n- `feat!:` or `fix!:` - Breaking changes (triggers major version bump)\n\n**Examples:**\n```bash\nfeat: add support for symlink watching\nfix: resolve race condition in file detection\ndocs: update README with new examples\nfeat!: change CLI argument structure (breaking change)\n```\n\n### Release Process\n\nReleases are fully automated via [Release Please](https://github.com/googleapis/release-please):\n\n1. **Commit using conventional commits** - Each commit to `master` is analyzed\n2. **Release PR is created** - Release Please opens a PR with updated version and CHANGELOG\n3. **Merge the Release PR** - This triggers:\n   - GitHub Release creation with release notes\n   - **Binary builds for 5 platforms** (parallel execution, ~4 minutes):\n     * Linux x86_64 and ARM64\n     * macOS Intel and Apple Silicon\n     * Windows x64\n   - Publish to crates.io (requires `CARGO_TOKEN` secret)\n\n**Current version**: v0.4.0 (October 2025)\n\n**Binary build tool**: Uses `taiki-e/upload-rust-binary-action` for reliable cross-compilation\n- Automatic cross-compilation for Linux ARM64\n- No timeout issues (resolved in v0.3.0)\n- Battle-tested by tokio-console and cargo-hack\n\n### CI/CD\n\n**Branch Protection**: Enabled on `master` with 6 required status checks\n\nAll PRs and pushes to `master` run:\n- ✅ Tests (187 tests on Linux, macOS, Windows)\n- ✅ Formatting check (`cargo fmt --check`)\n- ✅ Linting (`cargo clippy -D warnings`)\n- ✅ Coverage report (uploaded to Codecov)\n\n**On release** (after merging Release PR):\n- ✅ Build binaries for 5 platforms (parallel)\n- ✅ Create GitHub Release with all binaries\n- ✅ Publish to crates.io\n\n**Release Process**:\n- Uses Release Please with Personal Access Token (`RELEASE_PLEASE_TOKEN`)\n- PAT required to trigger CI workflows on Release Please PRs\n- Ensures all tests pass before releases are created\n\nSee [`docs/CI_CD.md`](docs/CI_CD.md) for complete CI/CD architecture documentation.\n\n## Documentation\n\nFor comprehensive technical documentation:\n- **CI/CD Architecture**: [`docs/CI_CD.md`](docs/CI_CD.md) - Complete CI/CD pipeline, release process, branch protection (v2.0)\n- **Testing Guide**: [`docs/TESTING.md`](docs/TESTING.md) - Test organization, best practices, and quick reference\n- **Coverage Analysis**: [`docs/COVERAGE.md`](docs/COVERAGE.md) - Detailed coverage metrics and industry benchmarks\n- **Integration Tests**: [`docs/INTEGRATION_TEST.md`](docs/INTEGRATION_TEST.md) - Testing research, rationale, and best practices\n- **Justfile Guide**: [`docs/JUSTFILE_IMPLEMENTATION.md`](docs/JUSTFILE_IMPLEMENTATION.md) - Task runner implementation and benefits\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodrigogs%2Fvibewatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frodrigogs%2Fvibewatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodrigogs%2Fvibewatch/lists"}