ad50cf4
feat(config): define disabled tools option which filters out agent tools access (#1016)
Click to expand commit body
* test(config): ensure all tools are included if no disabled defined
* test(config): verify explicitly disabled tools are gone
* refactor(config): share manual slice iteration and selection logic
* refactor(config): move static slice of readonly tools into helper
* test(config): ensure allowed tools for task is at most in the read only
this was removed in a merge conflict in #1011
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
Carlos Alexandro Becker
created
46a3a37
feat: optimize LSP file watcher and ignore files (#959)
Click to expand commit body
* refactor: centralize file watching with single fsnotify.Watcher
Refactored the LSP watcher system to use a single shared fsnotify.Watcher
instance instead of one per LSP client, eliminating all file watching
duplication and significantly improving resource efficiency.
Key changes:
- Added GlobalWatcher singleton managing single fsnotify.Watcher
- Centralized all file system event processing and distribution
- Eliminated duplicate directory and file watching across clients
- Implemented global debouncing with per-client event filtering
- Maintained full backward compatibility with existing LSP integration
Benefits:
- Single watcher instance regardless of LSP client count
- Each directory/file watched exactly once
- Centralized event processing eliminates duplicate operations
- Significant reduction in file descriptors and memory usage
- Linear resource growth with unique files, not client count
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* docs: clarify directory-only watching strategy
Enhanced documentation and comments to clearly explain that the file
watcher implementation only watches directories, not individual files.
This approach is more efficient as fsnotify automatically provides
events for all files within watched directories.
Key clarifications:
- Added comprehensive documentation explaining directory-only approach
- Clarified that fsnotify automatically covers files in watched directories
- Enhanced comments explaining new directory detection and handling
- Added test to verify only directories are watched, never individual files
- Improved code organization and readability
Benefits of directory-only watching:
- Significantly fewer file descriptors used
- Automatic coverage of new files created in watched directories
- Better performance with large codebases
- Simplified deduplication logic
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* refactor: remove unnecessary directory tracking, rely on fsnotify deduplication
Simplified the GlobalWatcher by removing manual directory tracking since
fsnotify handles deduplication internally. According to fsnotify docs:
"A path can only be watched once; watching it more than once is a no-op"
Key improvements:
- Removed watchedDirs map and associated mutex (no longer needed)
- Simplified addDirectoryToWatcher method to directly call fsnotify
- Updated tests to verify fsnotify deduplication behavior
- Reduced memory usage and code complexity
- Maintained all functionality while relying on fsnotify's built-in deduplication
Benefits:
- Less memory usage (no directory tracking map)
- Simpler code with fewer mutexes and less complexity
- Relies on well-tested fsnotify deduplication instead of custom logic
- Better performance due to reduced synchronization overhead
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* refactor: remove workspace path tracking, embrace full idempotency
Removed unnecessary workspace path tracking since directory walking
and fsnotify.Add() calls are idempotent. Multiple WatchWorkspace calls
with the same path are now safe and simple.
Key improvements:
- Removed workspacePaths map and workspacesMu mutex
- Simplified WatchWorkspace to be fully idempotent
- Reduced GlobalWatcher struct size and complexity
- Updated tests to verify idempotent behavior instead of deduplication
- Embraced "simple and idempotent" over "complex and optimized"
Benefits:
- Even less memory usage (no workspace tracking)
- Simpler code with fewer mutexes (down to 2 from original 4)
- Fully idempotent operations - safe to call multiple times
- Better maintainability with less state to manage
- Relies entirely on fsnotify's proven deduplication
Philosophy: Let fsnotify handle what it's designed to handle, keep our
code simple and idempotent rather than trying to micro-optimize.
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* refactor: remove redundant file type validation in file opening
Removed duplicate file extension checking since HandlesFile() already
validates that the LSP client handles the file type. This eliminates
redundant hardcoded extension checks and potential inconsistencies.
Key improvements:
- Removed shouldOpen extension validation logic
- Simplified file opening to trust HandlesFile() validation
- Eliminated hardcoded extension lists that could become stale
- Reduced code duplication between global_watcher.go and watcher.go
- More consistent behavior across different file opening paths
Benefits:
- Single source of truth for file type handling (LSP client config)
- Less code to maintain and keep in sync
- More flexible - supports any file types configured for LSP clients
- Eliminates potential bugs from hardcoded extension mismatches
- Cleaner, more maintainable code
The file type validation now happens exactly once at the right place:
when checking if a client HandlesFile(), not again during file opening.
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* feat: add hierarchical .gitignore/.crushignore support to LSP file watcher
Implements proper hierarchical ignore file support that checks for .gitignore
and .crushignore files in each directory from the target path up to the
workspace root, following Git's ignore semantics.
Key improvements:
- Hierarchical ignore checking: walks directory tree from workspace root to target
- Supports both .gitignore and .crushignore patterns
- Handles trailing slash patterns correctly (e.g., "node_modules/" matches directories)
- Uses go-gitignore library for proper pattern matching
- Maintains workspace root tracking for multi-workspace support
- Comprehensive test coverage for ignore functionality
This ensures the LSP file watcher respects ignore patterns at all directory
levels, not just the workspace root, providing consistent behavior with Git
and other tools that support hierarchical ignore files.
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* chore: small improvement
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* refactor: simplify global watcher to single workspace
Remove multi-workspace concept that was never used in practice.
All LSP clients watch the same single workspace directory, so the
complexity of tracking multiple workspace roots was unnecessary.
Changes:
- Replace workspaceRoots map with single workspaceRoot string
- Remove unnecessary mutex protection (workspace set once at startup)
- Simplify shouldIgnoreDirectory logic
- Update tests to match simplified structure
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* refactor: major simplification of file watcher logic
Remove unnecessary complexity and consolidate duplicate code:
- Remove unnecessary watcherMu mutex (watcher set once at init)
- Consolidate duplicate file opening logic between GlobalWatcher and WorkspaceWatcher
- Simplify AddRegistrations by removing complex workspace scanning
- Replace custom glob matching with proven doublestar library
- Remove unused shouldExcludeDir function
- Streamline file preloading to only handle high-priority files
Benefits:
- ~200 lines of code removed
- Better reliability using doublestar for pattern matching
- Improved performance with event-driven approach vs bulk scanning
- Single source of truth for file operations
- Reduced memory usage and fewer goroutines
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* refactor: more cleanup
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* refactor: use csync
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* refactor: renaming some methods/structs
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* refactor: simplify
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* fix: errs/logs
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* refactor: simplify LSP watcher architecture and improve organization
- Rename WorkspaceWatcher to Client for clarity
- Add Start() function for one-time global watcher setup
- Extract ignore file logic to separate ignore.go module
- Add thread-safe csync.String type with comprehensive tests
- Simplify startup flow by initializing watcher once in app.go
- Improve naming consistency (getGlobalWatcher → instance, etc.)
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* chore: remove unused csync strings utilities
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* docs: add semantic commit guidelines to development guide
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* fix: exclude .git directories from LSP file watching
Explicitly exclude .git directories from file system watching to improve
performance and avoid unnecessary events from Git operations.
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* refactor: use fsext
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* fix: grep
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* merge
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
Co-authored-by: Crush <crush@charm.land>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Carlos Alexandro Becker
,
Crush
, and
Copilot
created
* refactor(fsext): improve hierarchical ignore handling and consolidate file exclusion logic
- Refactor FastGlobWalker to use directoryLister for consistent ignore handling
- Add ShouldExcludeFile function for unified file exclusion checking
- Add WalkDirectories function for directory traversal with ignore support
- Improve directory pattern matching by checking both with and without trailing slash
- Add comprehensive tests for hierarchical ignore behavior and common patterns
- Remove direct dependency on go-gitignore in favor of existing directoryLister implementation
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* fix: improvements
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* chore: t.Context()
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* fix: tests
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
---------
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
Co-authored-by: Crush <crush@charm.land>
Carlos Alexandro Becker
and
Crush
created
442867d
chore: bump bubbletea/ultraviolet to enable bracketed paste on windows (#1003)
Click to expand commit body
This trades enhanced keyboard with bracketed paste on Windows. This is due to some limitations in the Windows Console API and VT input mode and bracketed paste.
913ea55
fix(openrouter): fix api key validation for openrouter (#997)
Click to expand commit body
`/models` is accessible for everyone on OpenRouter, without the need for
any authorization. The `Authorization: Bearer *` was basically always
ignore by their API.
Using a different private API to validate the key for OpenRouter.