Resolved conflict in core/src/infra/sync/hlc.rs by adopting the main branch's
improved test implementation that properly uses FakeTimeSource for deterministic
time control in tests.
- Removed the static ASCII logo and implemented a new function to calculate brightness on a sphere, allowing for a dynamic rendering of the Spacedrive logo as a purple orb using ANSI colors and Unicode half-blocks.
- Enhanced the `print_logo_colored` function to utilize the new brightness calculation and color gradient, improving visual representation.
- Updated related documentation to reflect the changes in logo rendering.
- Added device_id parameter to DatabaseAdapter and DatabaseAdapterForJob for improved context handling.
- Updated ChangeDetector to utilize device_id when creating persistence instances, ensuring accurate indexing behavior.
- Refactored related tests to verify correct parent-child relationships and prevent duplicate entries during folder moves.
- Normalize file paths to use forward slashes in Git pattern matching for better compatibility across platforms.
- Introduce a random suffix to temporary directory names in tests on Windows to avoid file lock contention during parallel execution.
- Add a delay after shutdown in tests to ensure SQLite file locks are released properly on Windows.
These changes aim to improve the reliability and consistency of tests in a Windows environment.
- Fix flaky HLC test by handling timing variations between sequential calls
- Move GENERIC_READ import to correct module in Windows file operations
- Add debug logging to change detection test for troubleshooting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Added GENERIC_READ import directly in both database_storage.rs and local.rs to enhance clarity in Windows API usage.
- Ensured consistency in handling Windows-specific functionality across the codebase.
- Removed unnecessary feature from windows-sys dependency to streamline functionality.
- Updated imports in database_storage.rs and local.rs to include GENERIC_READ directly, enhancing clarity and correctness in Windows API usage.
- Added "Win32_System_SystemServices" and "Win32_Security" features to the windows-sys dependency for enhanced functionality on Windows.
- Updated null pointer handling in database_storage.rs and local.rs to use std::ptr::null_mut() and 0 for better clarity and correctness.
- Changed get_all_allowed_paths() to async to properly await library manager operations
- Changed is_path_allowed() to async and fixed RwLock held across await points
- Changed validate_path_access() to async for consistency
- Replaced blocking_read() and block_on() with proper async/await
- Clone RwLock data before await to ensure future is Send
- Updated all call sites to use .await
- Improved error logging with structured tracing
This fixes compilation errors where futures were not Send due to
RwLockReadGuard being held across await points, and prevents potential
deadlocks from blocking operations in async contexts.
Fixes the file_transfer_test which now passes successfully.
Introduces a new markdown file detailing the implementation of Windows File ID support for stable file identification across renames. This documentation outlines the problem with current Windows file handling, the solution using NTFS File IDs, and the expected user impact. It also includes acceptance criteria, implementation plans, known limitations, and success metrics, ensuring comprehensive guidance for developers.
Additionally, updates the indexing rules to include macOS metadata files in the system file rejection list, enhancing cross-platform compatibility.
Addresses task CORE-015.
Implements Windows File ID support in the indexer to enable stable file
identification across renames on Windows NTFS filesystems. This brings
Windows to feature parity with Unix/Linux/macOS for change detection
and UUID persistence.
**Problem:**
Previously, Windows files didn't have stable identifiers across renames
because get_inode() returned None. This meant:
- Renamed files were treated as delete + create
- UUIDs were not preserved across renames
- Tags, metadata, and relationships were lost
- Files had to be re-indexed and re-hashed unnecessarily
**Solution:**
Uses Windows NTFS File IDs (64-bit file index) via GetFileInformationByHandle
API as the equivalent of Unix inodes for stable file identification.
**Changes:**
- Added windows-sys dependency for Win32 File System API access
- Implemented get_inode() for Windows using GetFileInformationByHandle
- Combines nFileIndexHigh and nFileIndexLow into 64-bit identifier
- Gracefully handles FAT32/exFAT (returns None) and permission errors
- Updated all call sites to pass both path and metadata parameters
- Updated test harness to verify Windows File ID tracking
**Benefits:**
- File renames now detected as moves (not delete + create)
- UUIDs preserved across renames within a volume
- Tags and metadata preserved across renames
- No re-indexing or re-hashing needed for renamed files
**Limitations:**
- Only works on NTFS (FAT32/exFAT fall back to path-only matching)
- File IDs are volume-specific (cross-volume copies get new UUIDs)
Addresses task CORE-015
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Sanitize remote filename to prevent path traversal attacks
- Distinguish EOF vs actual errors when reading from stream
- Fail transfer on byte count mismatch instead of just logging
- Validate transfer_completed after loop to catch interrupted transfers
- Warn when checksum verification enabled but no checksum provided
- Remove redundant contains('..') check after canonicalize()
- Update comments for clarity
Extends the FileCopyJob to support PULL operations, enabling files to be
copied FROM remote devices TO the local device. Previously, only PUSH
operations worked (local -> remote).
Changes:
- Add PullRequest/PullResponse messages to FileTransferMessage enum
- Add TransferDirection enum to detect PUSH vs PULL operations
- Refactor RemoteTransferStrategy to detect direction automatically
- Implement execute_pull() for remote source -> local destination
- Add handle_pull_request() handler on the protocol side
- Add path validation for security (prevent directory traversal)
- Add integration test for PULL operations
The strategy automatically detects direction based on SdPath:
- Source is local + Destination is remote = PUSH (existing behavior)
- Source is remote + Destination is local = PULL (new behavior)
This enables users to drag files from remote device explorers to local
folders, which previously failed with 'Source must be local path' error.
Closes FILE-005
- Updated `FileByIdQuery` and `FileByPathQuery` to populate alternate paths for files with the same content ID, improving data retrieval for file instances.
- Introduced `get_alternate_paths` method in both queries to fetch alternate file paths from the database.
- Modified the `InstancesTab` component to utilize a new query for alternate instances, enhancing the user interface with detailed instance information.
- Updated TypeScript types to support the new alternate instances query structure, ensuring type safety across the application.
- Adjusted various components to improve the display of alternate file instances, including device and path information.
- Added a new `files` field to `FileSearchOutput` to provide a flat array of files, improving integration with the explorer.
- Updated the `FileSearchQuery` to join directory paths directly on `parent_id`, simplifying the SQL query.
- Enhanced the query to batch fetch sidecars for content UUIDs, improving performance and data retrieval.
- Adjusted the handling of content identity fields to ensure proper association with files in search results.
- Updated the `SearchView` component to utilize the new `files` array instead of the previous `results` structure.
- Introduced a new column `device_id` in the entries table to denormalize device relationships, improving query performance.
- Updated related models and queries to accommodate the new device_id field.
- Enhanced foreign key mappings and migration scripts to support the addition of device_id.
- Adjusted various components to handle device_id, ensuring compatibility across the application.
- Improved release workflow to include specific file types for distribution.
- Updated `stream_file_data` to bypass encryption, as Iroh provides end-to-end encryption for connections.
- Adjusted `FileTransferProtocolHandler` to skip decryption, directly using the received encrypted data.
- Enhanced logging to reflect changes in data handling during file transfers.
- Added tests to ensure session keys are distinct and validate key swapping functionality.
- Improved error handling in `DevicePersistence` for corrupted session keys during device loading.
- Updated documentation for copy strategies to clarify their use cases and selection logic.
- Improved logging in `DevicePersistence` to track loading of paired devices and handle expired session keys.
- Added detailed logging for session key retrieval in `FileTransferProtocolHandler`.
- Introduced a new test for file transfer with daemon restart to ensure session key persistence across restarts.
- Updated macOS subproject reference to indicate a dirty state.
- Refactored `FileCopyJob` to improve logging for final destination calculations.
- Enhanced `stream_file_data` logging to include destination path in transfer requests.
- Added `find_containing` method to `EphemeralIndex` for substring search functionality.
- Improved logging in `ephemeral_search` to track search results and filtering.
- Replaced print statements with tracing logs in `FileTransferProtocolHandler` for better debugging.
- Adjusted indentation for clarity in the `search_ephemeral_index` function.
- Ensured consistent formatting for the filter application section to enhance code readability.
- Replaced the previous event processing loop with a select-based approach to handle both incoming events and periodic eviction ticks.
- Ensured that expired pending removes are processed even when no new events arrive.
- Improved efficiency by reducing busy waiting during event collection.
Implements comprehensive search functionality that intelligently routes between
ephemeral (in-memory) and persistent (FTS5 database) indexes, following the
directory listing pattern for consistency.
**Backend Changes:**
- Add IndexType enum (Persistent/Ephemeral/Hybrid) to communicate which index was used
- Add FilterKind enum to indicate available filters for each search type
- Implement ephemeral_search module with content type filtering via FileTypeRegistry
- Update FileSearchOutput with index_type and available_filters fields
- Add routing logic in FileSearchQuery to determine and use appropriate index
- Support file type, size, date, and content type filters in ephemeral search
**Frontend Changes:**
- Add search mode to Explorer context (browse vs search with query/scope)
- Create SearchView component with placeholder for search results
- Wire up SearchBar with debounced search (300ms, min 2 chars)
- Integrate search mode switching in ExplorerView router
**Key Features:**
- Fast, synchronous search (no events, no jobs)
- Defaults to current folder scope (not global like Finder)
- Backend as source of truth for all search operations
- Content type filtering using FileTypeRegistry.identify_by_extension()
- Ephemeral search supports: file types, size, dates, content types
- Persistent search supports: all ephemeral filters + tags + locations
**Architecture:**
Follows the directory listing pattern: checks location index mode, queries
database, falls back to ephemeral cache. Search results indicate which index
was used and which filters are available for dynamic UI updates.
- Marked several tasks as completed in the TODO list, including opening files with the default app, drag selection area functionality, and initializing the startup screen for Core/daemon.
- Added `run_in_background` field to ThumbnailPolicy to control background execution behavior.
Resolved conflicts in:
- SelectionContext.tsx: Merged rename state with isActiveTab prop
- useFileContextMenu.ts: Combined rename/folder actions with Open With submenu
- FileCard.tsx: Integrated InlineNameEdit with useOpenWith hook
- TableRow.tsx: Integrated InlineNameEdit with useOpenWith hook
- Updated ThumbnailJobConfig to include `run_in_background` field, allowing jobs to run without persisting to the database or updating the UI.
- Modified IndexerJob to inherit the background flag from its configuration.
- Implemented `should_persist` method in ThumbnailJob to determine persistence based on the background execution flag.
- Added `run_in_background` field to `IndexerJobConfig` to allow jobs to run without persisting to the database or updating the UI.
- Updated `should_persist` method in `IndexerJob` to account for background jobs.
- Modified `handle_new_directory` in `DatabaseAdapter` to create background indexer jobs.
- Ensured default value for `run_in_background` is set to false in various configurations.
- Introduced a new integration test for bulk file moves to validate cache updates and file handling.
- Added a new function `validate_and_reset_library_if_needed` to check if the current library exists and reset the state if it doesn't.
- Integrated this validation process into the daemon connection initialization, ensuring the app state is consistent with the available libraries.
- Enhanced error handling and logging for better debugging during library validation.
- Introduced a new test suite for file move operations, covering various scenarios to ensure robust handling of file movements and state integrity.
- Replaced synchronous job completion handling with an asynchronous background task to improve responsiveness.
- Extracted job output handling and stats saving into the background task, allowing for better event-driven processing.
- Updated the `save_volume_stats` method to be static and adjusted the output structure to reflect the new indexing approach.
- Added critical tasks for remote file access and updater functionality to the TODO list.
- Updated job logging configuration to include an option for logging ephemeral jobs, improving logging flexibility.
- Enhanced the job manager to conditionally log job events based on persistence settings, ensuring better tracking of job statuses.
- Refactored the inspector component to remove unnecessary console logs, streamlining the codebase.
- Improved the selection context to eliminate redundant logging during file synchronization, enhancing performance.
- Refactored the `IndexPersistence` implementation to improve error handling and logging when querying directory paths.
- Updated the change detection logic to always load existing entries during reindexing, ensuring accurate detection of moves, modifications, and deletions.
- Introduced a new test suite for folder rename operations, covering both persistent and ephemeral indexing scenarios, validating UUID/inode preservation and parent-child relationship integrity.
- Enhanced the `IndexingHarnessBuilder` to allow disabling the filesystem watcher for specific tests, improving test flexibility.
- Added closure table integrity verification to ensure proper connections between renamed folders and their children, preventing data inconsistencies.
- Introduced a new `IndexMode::Stale` variant to enhance the indexing process by leveraging modified time (mtime) pruning.
- Updated `IndexerJobConfig` to utilize the new mode, allowing for more efficient directory exploration based on filesystem changes.
- Implemented logic in the discovery phase to skip directories with matching mtime, improving performance and reducing unnecessary indexing.
- Enhanced `IndexMode` with helper methods to check for mtime pruning and retrieve the inner indexing mode.
- Updated relevant functions and tests to support the new stale detection capabilities, ensuring robust handling of file indexing and statistics tracking.
- Refactored existing code to accommodate the new indexing strategy while maintaining backward compatibility with previous modes.
- Updated the TODO list to clarify the quick preview reporting issue.
- Enhanced the Tauri app's menu to include custom clipboard operations (cut, copy, paste) with appropriate state management.
- Introduced a new `statistics_listener` service to manage per-library statistics recalculation based on resource changes, improving performance and responsiveness.
- Added configuration options for enabling/disabling the statistics listener in the application settings.
- Refactored event handling in the job manager to improve logging and status monitoring.
- Updated tests to include the new statistics listener functionality and ensure proper event collection during file operations.
- Replaced `eprintln!` with `tracing::warn!` for logging job cancellation, pause, and resume errors, improving logging consistency and integration with the tracing framework.
- Updated the `useJobs` hook to handle job pause, resume, and cancel actions with improved error handling, ensuring better user feedback on job status.
- Enhanced the UI components to reflect changes in job management, including better error reporting for failed actions.
- Added `remove_from_library` field to `DeviceRevokeInput` and `DeviceRevokeAction` to control whether a device should be removed from library databases during revocation.
- Updated the `from_input` method in `DeviceRevokeAction` to handle the new field.
- Modified the revocation logic to conditionally remove devices from libraries based on the `remove_from_library` flag, improving flexibility in device management.
- Adjusted the CLI argument parsing to default `remove_from_library` to false, ensuring devices remain in libraries unless explicitly specified for removal.
- Added `remove_paired_device_from_cache` method to `DeviceManager` for removing unpaired devices from the cache.
- Enhanced `DeviceRevokeAction` to handle device revocation, including detailed logging for each step of the removal process from network registry, persistence, and DeviceManager cache.
- Updated `DevicePersistence` to ensure proper deletion of device keys from KeyManager and improved logging for device removal.
- Refactored `DeviceRegistry` to clean up node-to-device and session mappings upon device removal.
- Introduced integration tests to verify the complete lifecycle of device operations, ensuring unpaired devices are correctly removed from all caches and persistent storage.