824 lines
17 KiB
Markdown
824 lines
17 KiB
Markdown
# Explorer Workbench - Backlog
|
|
|
|
> Personal file management workbench.
|
|
>
|
|
> Goal: Make working with files faster - not necessarily the filesystem itself.
|
|
>
|
|
> **Primary success metric:** One happy customer. 😎
|
|
|
|
---
|
|
|
|
## Core Principles
|
|
|
|
### Windows remains the source of truth
|
|
|
|
Explorer Workbench may discover, index, display and organize Windows resources, but should not silently modify Windows configuration.
|
|
|
|
Example:
|
|
|
|
- Removing `Z:` from Workbench removes the Workbench location and its index data.
|
|
- It does **not** disconnect the Windows network drive.
|
|
- Existing Windows resources should be discoverable/importable again.
|
|
|
|
### Workbench owns the workflow
|
|
|
|
Specialized tools may provide execution capabilities.
|
|
|
|
Possible providers:
|
|
|
|
- Robocopy - robust file transfers
|
|
- 7-Zip - archive operations
|
|
- FFmpeg - media conversion
|
|
- Git - repository operations
|
|
|
|
Explorer Workbench provides:
|
|
|
|
- UI
|
|
- orchestration
|
|
- metadata
|
|
- index
|
|
- profiles
|
|
- queue
|
|
- status
|
|
- history
|
|
|
|
### File Operations Queue is the execution engine
|
|
|
|
Whenever possible, features that modify files should create operations instead of modifying the filesystem directly.
|
|
|
|
Examples:
|
|
|
|
- Copy
|
|
- Move
|
|
- Recycle
|
|
- Delete
|
|
- Rename
|
|
- Extract
|
|
- Compress
|
|
- Convert
|
|
- Sync
|
|
- Reorganize
|
|
|
|
### Analyze aggressively, modify conservatively
|
|
|
|
Analysis may be ambitious.
|
|
|
|
Filesystem modifications should be predictable, reviewable and safe.
|
|
|
|
Complex operations should preferably follow:
|
|
|
|
`Analyze -> Preview -> Operation Plan -> Queue -> Execute`
|
|
|
|
### Configuration rule
|
|
|
|
If both behaviors are useful depending on the situation:
|
|
|
|
**Make it an option.**
|
|
|
|
---
|
|
|
|
# Current Features
|
|
|
|
## Navigation
|
|
|
|
- [x] Group locations into `This PC`, `Network` and `Cloud`
|
|
- [x] Optional grouping via Settings
|
|
- [x] Remove locations from Workbench
|
|
- [x] Remove associated index/database data
|
|
- [x] Do not modify Windows mappings when removing Workbench locations
|
|
- [x] Add network/cloud locations
|
|
- [x] Discover/import existing Windows network drives
|
|
- [x] Restore a previously removed Workbench location from Windows discovery
|
|
|
|
## UI
|
|
|
|
- [x] Classic application menu
|
|
- [x] Icon-based toolbar
|
|
- [x] Settings dialog
|
|
- [x] Help menu with About and in-app Documentation
|
|
- [x] Expandable Settings architecture
|
|
- [x] Show `Free Space` next to `Size` where meaningful
|
|
- [x] Consistent capacity information for local/network/cloud providers
|
|
- [x] Organize folder (classify → preview → queue moves)
|
|
|
|
## Search / Index
|
|
|
|
- [x] Central filesystem index
|
|
- [x] Fast indexed search
|
|
- [ ] Search offline locations
|
|
- [x] Search archive contents
|
|
- [ ] Store originating machine/location
|
|
- [ ] Multi-PC search
|
|
- [ ] Richer metadata indexing
|
|
|
|
## Storage Analysis
|
|
|
|
- [x] Storage usage analysis
|
|
- [x] WinDirStat-style functionality
|
|
- [x] Duplicate detection
|
|
- [x] Duplicate classification
|
|
- [x] Distinguish intentional duplicates
|
|
- [x] Recognize Sync copies
|
|
- [ ] Recognize Backup copies
|
|
- [x] Detect hardlinks
|
|
|
|
---
|
|
|
|
# File Operations Queue
|
|
|
|
## Implemented
|
|
|
|
- [x] Central File Operations Queue
|
|
- [x] Copy
|
|
- [x] Move
|
|
- [x] Move to Recycle Bin
|
|
- [x] Queue Rename
|
|
- [x] Queue Extract
|
|
- [x] Queue Compress
|
|
- [x] Sequential execution
|
|
- [x] Pause / Resume
|
|
- [x] Pause all
|
|
- [x] Progress display
|
|
- [x] Queue status
|
|
- [x] Reorder operations
|
|
- [x] Remove queued operations
|
|
- [x] Clear finished operations
|
|
- [x] Auto-clear when done
|
|
- [x] Compact queue status in main UI
|
|
- [x] Persist queue across Workbench restarts
|
|
- [x] Retry failed operations
|
|
- [x] `Waiting for destination` state
|
|
- [x] Resume automatically when destination becomes available
|
|
- [x] Handle temporarily unavailable network shares
|
|
- [x] Handle removable media (wait until reachable)
|
|
- [x] Detect file locks (Failed + Retry)
|
|
- [x] Operation history (append-only)
|
|
|
|
## Planned
|
|
|
|
- [ ] Conflict resolution
|
|
- [x] Undo last rename batch
|
|
- [ ] Undo copy / move
|
|
- [ ] Resource-aware scheduling
|
|
|
|
### Resource-aware scheduling
|
|
|
|
Potential future behavior:
|
|
|
|
Instead of always running exactly one operation, allow concurrent operations when they do not compete for the same I/O resources.
|
|
|
|
Example:
|
|
|
|
`C: -> D:` and `NAS -> USB` may run simultaneously.
|
|
|
|
Two operations using the same physical source/target should normally remain serialized.
|
|
|
|
---
|
|
|
|
# Protected Windows Filesystem Locations
|
|
|
|
## Visibility
|
|
|
|
- [x] Hidden file support
|
|
- [x] Setting: `Show protected system locations`
|
|
- [x] Detect `FileAttributes.Hidden`
|
|
- [x] Detect `FileAttributes.System`
|
|
- [x] Classify known protected Windows locations
|
|
- [x] Distinguish `Access denied` from empty folders
|
|
|
|
Known examples:
|
|
|
|
- `System Volume Information`
|
|
- `$RECYCLE.BIN`
|
|
- `Recovery`
|
|
- `pagefile.sys`
|
|
- `hiberfil.sys`
|
|
|
|
## Size calculation
|
|
|
|
Never display:
|
|
|
|
`0 B`
|
|
|
|
when the actual state is:
|
|
|
|
`Unknown because access was denied`
|
|
|
|
Possible states:
|
|
|
|
- Calculated
|
|
- Partial
|
|
- Unknown
|
|
- Access denied
|
|
|
|
## Elevated scan
|
|
|
|
- [ ] Detect when elevation would provide additional information
|
|
- [ ] Optional elevated/deep scan
|
|
- [ ] Never silently elevate
|
|
- [ ] Keep normal Workbench operation non-elevated
|
|
|
|
## Recycle Bin
|
|
|
|
- [x] Classify `$RECYCLE.BIN` specially
|
|
- [x] Do not expose it merely as a normal filesystem folder
|
|
- [x] Show logical Recycle Bin information
|
|
- [x] Number of deleted items
|
|
- [x] Used space
|
|
- [x] Open Recycle Bin
|
|
- [x] Empty Recycle Bin
|
|
|
|
---
|
|
|
|
# Folder Sync
|
|
|
|
Goal: Replace the relevant AllSync workflows.
|
|
|
|
## Sync modes
|
|
|
|
- [x] Copy / Update
|
|
- [x] Mirror
|
|
- [ ] Two-way sync
|
|
- [ ] Versioned backup
|
|
|
|
Two-way sync should be implemented later because it requires proper conflict and deletion tracking.
|
|
|
|
## Integration
|
|
|
|
- [x] Analyze differences
|
|
- [x] Generate operation plan
|
|
- [x] Submit operations to File Operations Queue
|
|
- [x] Preview before execution
|
|
- [x] Conflict detection
|
|
- [ ] Sync history
|
|
|
|
## Offline / removable locations
|
|
|
|
- [x] Detect target availability
|
|
- [x] Wait when target is offline
|
|
- [x] Automatically continue when target returns
|
|
- [x] Identify removable media using stable volume identity
|
|
- [x] Do not depend only on drive letters
|
|
- [x] Trigger sync when known media is connected
|
|
|
|
Example:
|
|
|
|
`When PhotosBackup becomes available -> run Photos Sync`
|
|
|
|
## Duplicate awareness
|
|
|
|
Files intentionally created by Folder Sync should be marked as intentional duplicates.
|
|
|
|
Possible classification:
|
|
|
|
- `Accidental`
|
|
- `Synchronized`
|
|
- `Backup`
|
|
- `Unknown`
|
|
|
|
The Duplicate Finder hides intentional duplicates by default. Sync and backup tags are written when those operations exist.
|
|
|
|
---
|
|
|
|
# Batch Rename
|
|
|
|
Goal: Replace FileRenamer workflows.
|
|
|
|
## Rename rules
|
|
|
|
- [x] Search / Replace
|
|
- [x] Regex
|
|
- [x] Prefix
|
|
- [x] Suffix
|
|
- [x] Counter
|
|
- [x] Counter padding
|
|
- [x] Case conversion
|
|
- [x] Extension handling
|
|
- [ ] Metadata placeholders
|
|
|
|
Potential placeholders:
|
|
|
|
- `{CreatedDate}`
|
|
- `{ModifiedDate}`
|
|
- `{Counter}`
|
|
- `{Width}`
|
|
- `{Height}`
|
|
- `{Artist}`
|
|
- `{Title}`
|
|
- `{Project}`
|
|
- `{Extension}`
|
|
|
|
## Workflow
|
|
|
|
`Select -> Configure -> Preview -> Validate -> Queue`
|
|
|
|
- [x] Preview all resulting names
|
|
- [x] Detect collisions
|
|
- [x] Detect invalid filenames
|
|
- [x] Add Rename operations to File Operations Queue
|
|
- [x] Store `OldPath -> NewPath`
|
|
- [x] Support Undo for completed rename batches
|
|
|
|
---
|
|
|
|
# File Operation Profiles
|
|
|
|
Reusable workflows built from Workbench operations.
|
|
|
|
## Core
|
|
|
|
- [x] Create profile
|
|
- [x] Edit profile
|
|
- [x] Delete profile
|
|
- [x] Duplicate profile
|
|
- [x] Run profile
|
|
- [x] Preview operation plan
|
|
- [x] Add resulting operations to queue
|
|
|
|
## Example: Archive Project
|
|
|
|
1. Verify Git status
|
|
2. Require clean working tree
|
|
3. Exclude `.git`, `bin`, `obj`, `.vs`
|
|
4. Compress using 7-Zip
|
|
5. Generate SHA-256
|
|
6. Copy archive to NAS
|
|
7. Verify destination
|
|
8. Recycle source only if all previous steps succeeded
|
|
|
|
## Example: Phone Videos
|
|
|
|
1. Find matching videos
|
|
2. Convert to configured format
|
|
3. Preserve timestamps
|
|
4. Copy converted files to Media
|
|
5. Archive originals
|
|
6. Queue cleanup
|
|
|
|
## Example: Clean Downloads
|
|
|
|
Classify files and propose:
|
|
|
|
- Installers -> Software
|
|
- Images -> Pictures
|
|
- Video -> Media
|
|
- Archives -> Archive
|
|
- Git repositories -> Development
|
|
- Unknown -> Leave untouched
|
|
|
|
Available as **Tools → Organize folder…** and **Organize this folder…** on a directory. Suggestions only; nothing moves until Queue.
|
|
|
|
## Profile triggers
|
|
|
|
- [x] Manual
|
|
- [x] Context menu: `Run Profile`
|
|
- [x] Drag files onto profile
|
|
- [x] When location becomes available
|
|
- [x] When removable media is connected
|
|
- [ ] Scheduled
|
|
- [ ] Folder watcher
|
|
|
|
---
|
|
|
|
# Archives
|
|
|
|
## Supported concepts
|
|
|
|
- [x] ZIP
|
|
- [x] 7z
|
|
- [x] RAR
|
|
- [x] Additional archive formats through providers
|
|
|
|
## Indexing
|
|
|
|
- [x] Scan archive contents without extraction
|
|
- [x] Add archive entries to search index
|
|
- [x] Search inside archives
|
|
- [x] Display archive path as virtual hierarchy
|
|
|
|
Example search result:
|
|
|
|
`\\NAS\Archive\2019-backup.7z\Projects\Explorer\README.md`
|
|
|
|
even when the NAS is currently offline.
|
|
|
|
## Operations
|
|
|
|
- [x] Extract
|
|
- [x] Compress
|
|
- [x] Add to archive
|
|
- [x] Verify archive
|
|
- [x] Queue archive operations
|
|
|
|
Potential provider:
|
|
|
|
`7-Zip`
|
|
|
|
---
|
|
|
|
# File Classification
|
|
|
|
Goal: Understand what files and folders represent rather than relying only on extensions.
|
|
|
|
## Initial categories
|
|
|
|
- [x] Media (Photos / Video / Audio)
|
|
- [x] Photos
|
|
- [x] Video
|
|
- [x] Audio
|
|
- [x] Documents
|
|
- [x] Code repositories
|
|
- [x] Installers
|
|
- [x] Backups (classified; left in place)
|
|
- [x] Archives
|
|
- [x] System data
|
|
- [x] Unknown
|
|
|
|
## Detection signals
|
|
|
|
- [x] File extension
|
|
- [ ] MIME/content signature
|
|
- [x] Folder structure
|
|
- [x] Git metadata
|
|
- [ ] Media metadata
|
|
- [x] Known application structures (`node_modules`, `bin`, `obj`, `.vs`)
|
|
- [x] File age (old installers flagged in preview)
|
|
- [ ] File relationships
|
|
- [ ] Index metadata
|
|
|
|
---
|
|
|
|
# Reorganization / Consolidation
|
|
|
|
Use file classification and metadata to propose better organization.
|
|
|
|
## Concepts
|
|
|
|
- [x] Analyze directory
|
|
- [x] Classify contents
|
|
- [x] Detect misplaced files
|
|
- [ ] Detect redundant files
|
|
- [x] Detect old installers
|
|
- [x] Detect old build output
|
|
- [ ] Detect archived projects
|
|
- [x] Generate reorganization proposal
|
|
- [x] Preview proposed operations
|
|
- [x] Submit approved operations to queue
|
|
|
|
Important:
|
|
|
|
**Never automatically reorganize based only on classification.**
|
|
|
|
Always prefer:
|
|
|
|
`Analyze -> Suggest -> Review -> Queue`
|
|
|
|
---
|
|
|
|
# Multi-PC
|
|
|
|
Goal: Search and manage the user's complete file environment rather than only the current PC.
|
|
|
|
## Machines
|
|
|
|
- [ ] Register Workbench machine
|
|
- [ ] Assign machine identity
|
|
- [ ] Store machine name with indexed files
|
|
- [ ] Track last-seen timestamp
|
|
- [ ] Track online/offline state
|
|
|
|
## Search
|
|
|
|
Example:
|
|
|
|
Search: `wallet.dat`
|
|
|
|
Results:
|
|
|
|
- `Desktop-PC -> D:\Backup\wallet.dat`
|
|
- `Laptop -> C:\Archive\wallet.dat`
|
|
- `NAS -> backup-2019.7z\Crypto\wallet.dat`
|
|
|
|
## Offline behavior
|
|
|
|
- [ ] Keep index searchable while machine is offline
|
|
- [ ] Show last known location
|
|
- [ ] Show last indexed timestamp
|
|
- [ ] Queue operations requiring offline machine
|
|
- [ ] Resume when machine becomes available
|
|
|
|
## Future
|
|
|
|
- [ ] Transfer files between Workbench machines
|
|
- [ ] Remote filesystem browsing
|
|
- [ ] Remote indexing
|
|
- [ ] Shared operation queue / agent model
|
|
|
|
---
|
|
|
|
# Secure Storage
|
|
|
|
## Concepts
|
|
|
|
- [ ] CryptDrive/Vault integration
|
|
- [ ] Secure Storage location category
|
|
- [ ] Detect mounted/unmounted state
|
|
- [ ] Index policy for encrypted locations
|
|
- [ ] Optional metadata-only index
|
|
- [ ] Security-sensitive search behavior
|
|
|
|
Workbench should preferably integrate existing encryption technology rather than implement cryptography itself.
|
|
|
|
---
|
|
|
|
# Conversion
|
|
|
|
Conversions should be represented as File Operations.
|
|
|
|
## Media
|
|
|
|
Potential provider:
|
|
|
|
`FFmpeg`
|
|
|
|
Possible operations:
|
|
|
|
- [x] Video conversion
|
|
- [ ] Audio conversion
|
|
- [ ] Codec conversion
|
|
- [ ] Resolution conversion
|
|
- [x] Extract audio
|
|
- [ ] Generate thumbnails
|
|
|
|
## Images
|
|
|
|
- [x] HEIC -> JPEG
|
|
- [ ] PNG -> JPEG
|
|
- [ ] Resize
|
|
- [ ] Rotate
|
|
- [ ] Metadata preservation/removal
|
|
|
|
## Workflow
|
|
|
|
Conversions should support:
|
|
|
|
`Input -> Conversion Profile -> Preview -> Queue`
|
|
|
|
and be usable inside File Operation Profiles.
|
|
|
|
V1: Convert… dialog and an operation-profile Convert toggle. Jobs run on the host through the File Operations Queue. FFmpeg is discovered, not bundled.
|
|
|
|
---
|
|
|
|
# Git Integration
|
|
|
|
Workbench should recognize repositories but not reimplement Git.
|
|
|
|
Potential provider:
|
|
|
|
`git`
|
|
|
|
## Repository detection
|
|
|
|
- [x] Detect Git repositories
|
|
- [x] Show current branch
|
|
- [x] Show modified count
|
|
- [x] Show untracked count
|
|
- [x] Show ahead/behind state
|
|
|
|
Example:
|
|
|
|
`Explorer-Workbench main 3 modified 1 untracked`
|
|
|
|
## Actions
|
|
|
|
- [x] Status
|
|
- [x] View Changes
|
|
- [x] Diff
|
|
- [x] Commit
|
|
- [x] Stage / Unstage / Discard
|
|
- [x] Merge (ours / theirs / continue / abort)
|
|
- [x] Pull
|
|
- [x] Push
|
|
- [x] Fetch
|
|
- [x] Open terminal here
|
|
- [x] Open in Cursor
|
|
|
|
## Profiles
|
|
|
|
Git state may be used as a profile condition.
|
|
|
|
Example:
|
|
|
|
`Archive Project`
|
|
|
|
requires:
|
|
|
|
`Working tree clean`
|
|
|
|
before archive operations continue.
|
|
|
|
---
|
|
|
|
# Sharing
|
|
|
|
## Basic sharing
|
|
|
|
- [ ] Share file
|
|
- [ ] Share folder
|
|
- [ ] Copy share link
|
|
- [ ] Temporary shares
|
|
- [ ] Expiration
|
|
- [ ] Password protection
|
|
- [ ] Read-only permissions
|
|
|
|
## Providers
|
|
|
|
Potential integrations:
|
|
|
|
- [ ] Nextcloud
|
|
- [ ] Network shares
|
|
- [ ] Other cloud providers
|
|
|
|
## Package for Sharing
|
|
|
|
Example profile:
|
|
|
|
1. Exclude unnecessary files
|
|
2. Clean temporary data
|
|
3. Compress
|
|
4. Encrypt
|
|
5. Upload
|
|
6. Create expiring share link
|
|
7. Copy link to clipboard
|
|
8. Queue temporary archive cleanup
|
|
|
|
---
|
|
|
|
# External Tool / Provider Integration
|
|
|
|
## Robocopy
|
|
|
|
Status:
|
|
|
|
**Documentation review / knowledge transfer pending. 😏**
|
|
|
|
Potential uses:
|
|
|
|
- [ ] Restartable copies
|
|
- [ ] Network transfers
|
|
- [ ] Retry handling
|
|
- [ ] Backup-mode access
|
|
- [ ] Mirror operations
|
|
- [ ] Metadata/ACL preservation
|
|
|
|
Possible architecture:
|
|
|
|
`RobocopyTransferProvider`
|
|
|
|
Workbench retains ownership of:
|
|
|
|
- Queue
|
|
- Progress
|
|
- State
|
|
- UI
|
|
- Retry policy
|
|
- History
|
|
|
|
Robocopy performs selected low-level transfers.
|
|
|
|
## 7-Zip
|
|
|
|
`SevenZipArchiveExecutor` (`IArchiveExecutor`)
|
|
|
|
Discovery: Settings path, then Program Files, then PATH. Missing 7-Zip fails the queued job with an install hint. 7-Zip is not bundled.
|
|
|
|
## FFmpeg
|
|
|
|
`FfmpegConversionExecutor` (`IMediaConversionProvider`)
|
|
|
|
Discovery: Settings path, then Program Files, then PATH. Missing FFmpeg fails the queued job with an install hint. FFmpeg is not bundled. V1: H.264 MP4, extract AAC/M4A, HEIC→JPEG. Preview first. Online-only cloud files are not hydrated.
|
|
|
|
## Git
|
|
|
|
`WindowsGitStatusProvider` (`IGitStatusProvider`, `IGitCommandProvider`)
|
|
|
|
Discovery: Settings path, then Program Files, then PATH. Missing git.exe means no badge. Git is not bundled. Status / View Changes lists porcelain paths. Diff is unified `git diff`. Commit stages checked files then `git commit --only`. Stage / unstage / discard, ours / theirs / mark resolved, continue / abort wrap `git.exe`. Fetch / fast-forward pull / merge pull / push use `GIT_TERMINAL_PROMPT=0`. No mergetool, stash, branch UI, or credential dialog. Failed fast-forward pull offers merge pull or a terminal.
|
|
|
|
---
|
|
|
|
# Future Intelligence
|
|
|
|
## File relationships
|
|
|
|
Workbench should eventually understand relationships between files.
|
|
|
|
Examples:
|
|
|
|
- Duplicate
|
|
- Sync copy
|
|
- Backup copy
|
|
- Converted version
|
|
- Archived version
|
|
- Renamed version
|
|
- Source/output relationship
|
|
|
|
This allows questions such as:
|
|
|
|
> Which duplicates are accidental?
|
|
|
|
instead of merely:
|
|
|
|
> Which files have the same hash?
|
|
|
|
## Forgotten Files
|
|
|
|
Potential analysis:
|
|
|
|
- Files not modified for many years
|
|
- Files not accessed for many years
|
|
- Old backups
|
|
- Forgotten projects
|
|
- Large unused files
|
|
- Old installers
|
|
- Historical archives
|
|
|
|
Possible feature name:
|
|
|
|
`Forgotten Files`
|
|
|
|
---
|
|
|
|
# Architectural Direction
|
|
|
|
Long-term conceptual model:
|
|
|
|
Filesystems / Providers
|
|
|
|
|
v
|
|
Scanner
|
|
|
|
|
v
|
|
Metadata Index
|
|
|
|
|
v
|
|
Intelligence Layer
|
|
|
|
|
+-----+-----+
|
|
| |
|
|
v v
|
|
Workbench Profiles
|
|
| |
|
|
+-----+-----+
|
|
|
|
|
v
|
|
File Operations Queue
|
|
|
|
|
v
|
|
Execution Providers
|
|
|
|
The Workbench should increasingly understand:
|
|
|
|
- What is this?
|
|
- Where is it?
|
|
- Which machine has it?
|
|
- Is it currently available?
|
|
- Is there another copy?
|
|
- Why does another copy exist?
|
|
- Is it part of a sync or backup?
|
|
- How much space does it consume?
|
|
- What operations are safe?
|
|
- What does the user want to do with it?
|
|
|
|
---
|
|
|
|
# Replaced / Potentially Replaced Tools
|
|
|
|
| Tool | Workbench capability |
|
|
| --- | --- |
|
|
| Windows Explorer | Navigation / file management |
|
|
| WinDirStat | Storage analysis |
|
|
| WhereIsIt? | Indexed catalog / offline search |
|
|
| AllSync | Folder synchronization |
|
|
| FileRenamer | Batch rename |
|
|
| Archive tools | Archive workflows |
|
|
| Conversion tools | Profile-driven conversion |
|
|
| Various sharing workflows | Integrated sharing |
|
|
|
|
The goal is not necessarily to completely replace every specialized tool.
|
|
|
|
The goal is to make Explorer Workbench the **central working environment** from which those capabilities are orchestrated.
|
|
|
|
---
|
|
|
|
# Definition of Done
|
|
|
|
Explorer Workbench is never truly finished.
|
|
|
|
A feature is useful when it improves the actual workflow of the primary user.
|
|
|
|
A release is successful when:
|
|
|
|
> Domi realizes he has not voluntarily opened Windows Explorer all week.
|
|
|
|
😎 |