1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-15 15:45:06 +00:00

Merge branch 'windows' into windows

This commit is contained in:
Bhadra
2026-01-16 12:54:40 +05:30
committed by GitHub
8 changed files with 381 additions and 182 deletions

5
.gitignore vendored
View File

@@ -14,3 +14,8 @@ bin/*.exe
# Test artifacts # Test artifacts
*.test *.test
coverage.out coverage.out
# Main branch specific files
ANTIGRAVITY.md
CLAUDE.md
windows-readme-update.md

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 309 KiB

After

Width:  |  Height:  |  Size: 325 KiB

View File

@@ -1,4 +1,5 @@
<div align="center"> <div align="center">
<img src="https://cdn.tw93.fun/pic/cole.png" alt="Mole Logo" width="120" height="120" style="border-radius:50%" />
<h1>Mole</h1> <h1>Mole</h1>
<p><em>Deep clean and optimize your Windows.</em></p> <p><em>Deep clean and optimize your Windows.</em></p>
</div> </div>
@@ -12,9 +13,8 @@
<a href="https://t.me/+GclQS9ZnxyI2ODQ1"><img src="https://img.shields.io/badge/chat-Telegram-blueviolet?style=flat-square&logo=Telegram" alt="Telegram"></a> <a href="https://t.me/+GclQS9ZnxyI2ODQ1"><img src="https://img.shields.io/badge/chat-Telegram-blueviolet?style=flat-square&logo=Telegram" alt="Telegram"></a>
</p> </p>
<p align="center"> > [!WARNING]
<img src="https://cdn.tw93.fun/img/mole.jpeg" alt="Mole - 95.50GB freed" width="1000" /> > **Experimental Status**: The Windows version is currently **not mature**. If your computer is critical or contains important data, **please do not use this tool**.
</p>
## Features ## Features
@@ -36,26 +36,33 @@ Mole is designed for Windows 10/11. This is the native Windows version ported fr
## Quick Start ## Quick Start
Install via PowerShell: ### Quick Install (One-Liner)
**Recommended:** Run this single command in PowerShell:
```powershell ```powershell
# Download and run installer (recommended) iwr -useb https://raw.githubusercontent.com/tw93/Mole/windows/quick-install.ps1 | iex
iwr -Uri "https://raw.githubusercontent.com/tw93/mole/windows/install.ps1" -OutFile "$env:TEMP\mole-install.ps1"; & "$env:TEMP\mole-install.ps1" -AddToPath
# Or install with specific options
# -Branch windows for latest code, -Tag v1.17.0 for specific version
iwr -Uri "https://raw.githubusercontent.com/tw93/mole/windows/install.ps1" -OutFile "$env:TEMP\mole-install.ps1"; & "$env:TEMP\mole-install.ps1" -AddToPath -CreateShortcut
``` ```
Or install manually: This will automatically download and install Mole with PATH configuration.
### Manual Installation
If you prefer to review the code first or customize the installation:
```powershell ```powershell
# Clone the repository and checkout windows branch # Clone the repository
git clone -b windows https://github.com/tw93/Mole.git git clone https://github.com/tw93/Mole.git
cd Mole cd Mole
# Switch to windows branch
git checkout windows
# Run the installer # Run the installer
.\install.ps1 -AddToPath .\install.ps1 -AddToPath
# Optional: Create Start Menu shortcut
.\install.ps1 -AddToPath -CreateShortcut
``` ```
Run: Run:
@@ -153,6 +160,7 @@ System: 12/32 GB RAM | 280/460 GB Disk (61%) | Uptime 6d
✓ Refresh Windows Search index ✓ Refresh Windows Search index
✓ Clear thumbnail cache ✓ Clear thumbnail cache
✓ Optimize startup programs ✓ Optimize startup programs
✓ System repairs (Font/Icon/Store/Search)
==================================================================== ====================================================================
System optimization completed System optimization completed
@@ -242,6 +250,9 @@ Custom scan paths can be configured with `mo purge --paths`.
# Create Start Menu shortcut # Create Start Menu shortcut
.\install.ps1 -AddToPath -CreateShortcut .\install.ps1 -AddToPath -CreateShortcut
# Optional: Custom install location
.\install.ps1 -InstallDir C:\Tools\Mole -AddToPath
``` ```
### Uninstall ### Uninstall
@@ -269,12 +280,12 @@ mole/ (windows branch)
├── go.mod # Go module definition ├── go.mod # Go module definition
├── go.sum # Go dependencies ├── go.sum # Go dependencies
├── bin/ ├── bin/
│ ├── clean.ps1 # Deep cleanup orchestrator 301: │ ├── clean.ps1 # Deep cleanup orchestrator
│ ├── uninstall.ps1 # Interactive app uninstaller 302: │ ├── uninstall.ps1 # Interactive app uninstaller
│ ├── optimize.ps1 # System optimization 303: │ ├── optimize.ps1 # System optimization
│ ├── purge.ps1 # Project artifact cleanup 304: │ ├── purge.ps1 # Project artifact cleanup
│ ├── analyze.ps1 # Disk analyzer wrapper 305: │ ├── analyze.ps1 # Disk analyzer wrapper
│ └── status.ps1 # Status monitor wrapper 306: │ └── status.ps1 # Status monitor wrapper
├── cmd/ ├── cmd/
│ ├── analyze/ # Disk analyzer (Go TUI) │ ├── analyze/ # Disk analyzer (Go TUI)
│ │ └── main.go │ │ └── main.go
@@ -320,6 +331,33 @@ go build -o bin/status.exe ./cmd/status/
## Community Love ## Community Love
### Phase 1: Core Infrastructure ✅
- [x] `install.ps1` - Windows installer
- [x] `mole.ps1` - Main CLI entry point
- [x] `lib/core/*` - Core utility libraries
### Phase 2: Cleanup Features ✅
- [x] `bin/clean.ps1` - Deep cleanup orchestrator
- [x] `bin/uninstall.ps1` - App removal with leftover detection
- [x] `bin/optimize.ps1` - System optimization
- [x] `bin/purge.ps1` - Project artifact cleanup
- [x] `lib/clean/*` - Cleanup modules
### Phase 3: TUI Tools ✅
- [x] `cmd/analyze/` - Disk usage analyzer (Go)
- [x] `cmd/status/` - Real-time system monitor (Go)
- [x] `bin/analyze.ps1` - Analyzer wrapper
- [x] `bin/status.ps1` - Status wrapper
### Phase 4: Testing & CI (Planned)
- [ ] `tests/` - Pester tests
- [ ] GitHub Actions workflows
- [ ] `scripts/build.ps1` - Build automation
Mole wouldn't be possible without these amazing contributors. They've built countless features that make Mole what it is today. Go follow them! ❤️ Mole wouldn't be possible without these amazing contributors. They've built countless features that make Mole what it is today. Go follow them! ❤️
[![Contributors](https://contrib.rocks/image?repo=tw93/Mole)](https://github.com/tw93/Mole/graphs/contributors) [![Contributors](https://contrib.rocks/image?repo=tw93/Mole)](https://github.com/tw93/Mole/graphs/contributors)

View File

@@ -20,6 +20,20 @@ param(
[switch]$Whitelist, [switch]$Whitelist,
[Alias('h')] [Alias('h')]
[Alias('system')]
[switch]$System,
[Alias('game-media')]
[switch]$GameMedia,
[Alias('debug')]
[switch]$DebugMode,
[Alias('whitelist')]
[switch]$Whitelist,
[Alias('help')]
[switch]$ShowHelp [switch]$ShowHelp
) )

View File

@@ -11,6 +11,11 @@ param(
[switch]$DebugMode, [switch]$DebugMode,
[Alias('h')] [Alias('h')]
[Alias('debug')]
[switch]$DebugMode,
[Alias('help')]
[switch]$ShowHelp [switch]$ShowHelp
) )
@@ -52,16 +57,15 @@ function Show-OptimizeHelp {
Write-Host " --help Show this help message" Write-Host " --help Show this help message"
Write-Host "" Write-Host ""
Write-Host "$esc[33mWhat it does:$esc[0m" Write-Host "$esc[33mWhat it does:$esc[0m"
Write-Host " - Disk optimization (TRIM for SSD, defrag for HDD)" Write-Host " - Disk optimization (TRIM/Defrag)"
Write-Host " - DNS cache flush" Write-Host " - Windows Search & Update check"
Write-Host " - Network stack optimization" Write-Host " - Network & DNS optimization"
Write-Host " - Font cache rebuild" Write-Host " - System cache cleanup & repairs"
Write-Host " - Icon cache rebuild" Write-Host " (Font cache, Icon cache, Store cache)"
Write-Host " - Windows Search optimization" Write-Host ""
Write-Host " - Windows Store cache reset" Write-Host "$esc[33mExamples:$esc[0m"
Write-Host " - Startup program analysis" Write-Host " mo optimize # Run all optimizations"
Write-Host " - Disk health check" Write-Host " mo optimize --dry-run # Preview what would happen"
Write-Host " - Windows Update status"
Write-Host "" Write-Host ""
Write-Host "$esc[33mExamples:$esc[0m" Write-Host "$esc[33mExamples:$esc[0m"
Write-Host " mo optimize # Run all optimizations" Write-Host " mo optimize # Run all optimizations"
@@ -78,38 +82,38 @@ function Get-SystemHealth {
.SYNOPSIS .SYNOPSIS
Collect system health metrics Collect system health metrics
#> #>
$health = @{} $health = @{}
# Memory info # Memory info
$os = Get-WmiObject Win32_OperatingSystem $os = Get-WmiObject Win32_OperatingSystem
$health.MemoryTotalGB = [Math]::Round($os.TotalVisibleMemorySize / 1MB, 1) $health.MemoryTotalGB = [Math]::Round($os.TotalVisibleMemorySize / 1MB, 1)
$health.MemoryUsedGB = [Math]::Round(($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / 1MB, 1) $health.MemoryUsedGB = [Math]::Round(($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / 1MB, 1)
$health.MemoryUsedPercent = [Math]::Round((($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / $os.TotalVisibleMemorySize) * 100, 0) $health.MemoryUsedPercent = [Math]::Round((($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / $os.TotalVisibleMemorySize) * 100, 0)
# Disk info # Disk info
$disk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='$env:SystemDrive'" $disk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='$env:SystemDrive'"
$health.DiskTotalGB = [Math]::Round($disk.Size / 1GB, 0) $health.DiskTotalGB = [Math]::Round($disk.Size / 1GB, 0)
$health.DiskUsedGB = [Math]::Round(($disk.Size - $disk.FreeSpace) / 1GB, 0) $health.DiskUsedGB = [Math]::Round(($disk.Size - $disk.FreeSpace) / 1GB, 0)
$health.DiskUsedPercent = [Math]::Round((($disk.Size - $disk.FreeSpace) / $disk.Size) * 100, 0) $health.DiskUsedPercent = [Math]::Round((($disk.Size - $disk.FreeSpace) / $disk.Size) * 100, 0)
# Uptime # Uptime
$uptime = (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime $uptime = (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
$health.UptimeDays = [Math]::Round($uptime.TotalDays, 1) $health.UptimeDays = [Math]::Round($uptime.TotalDays, 1)
# CPU info # CPU info
$cpu = Get-WmiObject Win32_Processor $cpu = Get-WmiObject Win32_Processor
$health.CPUName = $cpu.Name $health.CPUName = $cpu.Name
$health.CPUCores = $cpu.NumberOfLogicalProcessors $health.CPUCores = $cpu.NumberOfLogicalProcessors
return $health return $health
} }
function Show-SystemHealth { function Show-SystemHealth {
param([hashtable]$Health) param([hashtable]$Health)
$esc = [char]27 $esc = [char]27
Write-Host "$esc[34m$($script:Icons.Admin)$esc[0m System " -NoNewline Write-Host "$esc[34m$($script:Icons.Admin)$esc[0m System " -NoNewline
Write-Host "$($Health.MemoryUsedGB)/$($Health.MemoryTotalGB)GB RAM | " -NoNewline Write-Host "$($Health.MemoryUsedGB)/$($Health.MemoryTotalGB)GB RAM | " -NoNewline
Write-Host "$($Health.DiskUsedGB)/$($Health.DiskTotalGB)GB Disk | " -NoNewline Write-Host "$($Health.DiskUsedGB)/$($Health.DiskTotalGB)GB Disk | " -NoNewline
@@ -125,28 +129,28 @@ function Optimize-DiskDrive {
.SYNOPSIS .SYNOPSIS
Optimize disk (defrag for HDD, TRIM for SSD) Optimize disk (defrag for HDD, TRIM for SSD)
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) Disk Optimization$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) Disk Optimization$esc[0m"
if (-not (Test-IsAdmin)) { if (-not (Test-IsAdmin)) {
Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges" Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges"
return return
} }
if ($script:DryRun) { if ($script:DryRun) {
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would optimize $env:SystemDrive" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would optimize $env:SystemDrive"
$script:OptimizationsApplied++ $script:OptimizationsApplied++
return return
} }
try { try {
# Check if SSD or HDD # Check if SSD or HDD
$diskNumber = (Get-Partition -DriveLetter $env:SystemDrive[0]).DiskNumber $diskNumber = (Get-Partition -DriveLetter $env:SystemDrive[0]).DiskNumber
$mediaType = (Get-PhysicalDisk | Where-Object { $_.DeviceId -eq $diskNumber }).MediaType $mediaType = (Get-PhysicalDisk | Where-Object { $_.DeviceId -eq $diskNumber }).MediaType
if ($mediaType -eq "SSD") { if ($mediaType -eq "SSD") {
Write-Host " Running TRIM on SSD..." Write-Host " Running TRIM on SSD..."
$null = Optimize-Volume -DriveLetter $env:SystemDrive[0] -ReTrim -ErrorAction Stop $null = Optimize-Volume -DriveLetter $env:SystemDrive[0] -ReTrim -ErrorAction Stop
@@ -169,27 +173,27 @@ function Optimize-SearchIndex {
.SYNOPSIS .SYNOPSIS
Rebuild Windows Search index if needed Rebuild Windows Search index if needed
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) Windows Search$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) Windows Search$esc[0m"
$searchService = Get-Service -Name WSearch -ErrorAction SilentlyContinue $searchService = Get-Service -Name WSearch -ErrorAction SilentlyContinue
if (-not $searchService) { if (-not $searchService) {
Write-Host " $esc[90mWindows Search service not found$esc[0m" Write-Host " $esc[90mWindows Search service not found$esc[0m"
return return
} }
if ($searchService.Status -ne 'Running') { if ($searchService.Status -ne 'Running') {
Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Windows Search service is not running" Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Windows Search service is not running"
if ($script:DryRun) { if ($script:DryRun) {
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would start search service" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would start search service"
return return
} }
try { try {
Start-Service -Name WSearch -ErrorAction Stop Start-Service -Name WSearch -ErrorAction Stop
Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Started Windows Search service" Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Started Windows Search service"
@@ -209,18 +213,18 @@ function Clear-DnsCache {
.SYNOPSIS .SYNOPSIS
Clear DNS resolver cache Clear DNS resolver cache
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) DNS Cache$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) DNS Cache$esc[0m"
if ($script:DryRun) { if ($script:DryRun) {
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would flush DNS cache" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would flush DNS cache"
$script:OptimizationsApplied++ $script:OptimizationsApplied++
return return
} }
try { try {
Clear-DnsClientCache -ErrorAction Stop Clear-DnsClientCache -ErrorAction Stop
Write-Host " $esc[32m$($script:Icons.Success)$esc[0m DNS cache flushed" Write-Host " $esc[32m$($script:Icons.Success)$esc[0m DNS cache flushed"
@@ -236,24 +240,24 @@ function Optimize-Network {
.SYNOPSIS .SYNOPSIS
Network stack optimization Network stack optimization
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) Network Optimization$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) Network Optimization$esc[0m"
if (-not (Test-IsAdmin)) { if (-not (Test-IsAdmin)) {
Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges" Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges"
return return
} }
if ($script:DryRun) { if ($script:DryRun) {
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would reset Winsock catalog" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would reset Winsock catalog"
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would reset TCP/IP stack" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would reset TCP/IP stack"
$script:OptimizationsApplied += 2 $script:OptimizationsApplied += 2
return return
} }
try { try {
# Reset Winsock # Reset Winsock
$null = netsh winsock reset 2>&1 $null = netsh winsock reset 2>&1
@@ -263,7 +267,7 @@ function Optimize-Network {
catch { catch {
Write-Host " $esc[31m$($script:Icons.Error)$esc[0m Winsock reset failed" Write-Host " $esc[31m$($script:Icons.Error)$esc[0m Winsock reset failed"
} }
try { try {
# Flush ARP cache # Flush ARP cache
$null = netsh interface ip delete arpcache 2>&1 $null = netsh interface ip delete arpcache 2>&1
@@ -280,37 +284,37 @@ function Get-StartupPrograms {
.SYNOPSIS .SYNOPSIS
Analyze startup programs Analyze startup programs
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) Startup Programs$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) Startup Programs$esc[0m"
$startupPaths = @( $startupPaths = @(
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run" "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run"
) )
$startupCount = 0 $startupCount = 0
foreach ($path in $startupPaths) { foreach ($path in $startupPaths) {
if (Test-Path $path) { if (Test-Path $path) {
$items = Get-ItemProperty -Path $path -ErrorAction SilentlyContinue $items = Get-ItemProperty -Path $path -ErrorAction SilentlyContinue
$props = @($items.PSObject.Properties | Where-Object { $props = @($items.PSObject.Properties | Where-Object {
$_.Name -notin @('PSPath', 'PSParentPath', 'PSChildName', 'PSDrive', 'PSProvider') $_.Name -notin @('PSPath', 'PSParentPath', 'PSChildName', 'PSDrive', 'PSProvider')
}) })
$startupCount += $props.Count $startupCount += $props.Count
} }
} }
# Also check startup folder # Also check startup folder
$startupFolder = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup" $startupFolder = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup"
if (Test-Path $startupFolder) { if (Test-Path $startupFolder) {
$startupFiles = @(Get-ChildItem -Path $startupFolder -File -ErrorAction SilentlyContinue) $startupFiles = @(Get-ChildItem -Path $startupFolder -File -ErrorAction SilentlyContinue)
$startupCount += $startupFiles.Count $startupCount += $startupFiles.Count
} }
if ($startupCount -gt 10) { if ($startupCount -gt 10) {
Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m $startupCount startup programs (high)" Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m $startupCount startup programs (high)"
Write-Host " $esc[90mConsider disabling unnecessary startup items in Task Manager$esc[0m" Write-Host " $esc[90mConsider disabling unnecessary startup items in Task Manager$esc[0m"
@@ -330,31 +334,31 @@ function Test-SystemFiles {
.SYNOPSIS .SYNOPSIS
Run System File Checker (SFC) Run System File Checker (SFC)
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) System File Verification$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) System File Verification$esc[0m"
if (-not (Test-IsAdmin)) { if (-not (Test-IsAdmin)) {
Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges" Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges"
return return
} }
if ($script:DryRun) { if ($script:DryRun) {
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would run System File Checker" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would run System File Checker"
return return
} }
Write-Host " Running System File Checker (this may take several minutes)..." Write-Host " Running System File Checker (this may take several minutes)..."
try { try {
$sfcResult = Start-Process -FilePath "sfc.exe" -ArgumentList "/scannow" ` $sfcResult = Start-Process -FilePath "sfc.exe" -ArgumentList "/scannow" `
-Wait -PassThru -NoNewWindow -RedirectStandardOutput "$env:TEMP\sfc_output.txt" -ErrorAction Stop -Wait -PassThru -NoNewWindow -RedirectStandardOutput "$env:TEMP\sfc_output.txt" -ErrorAction Stop
$output = Get-Content "$env:TEMP\sfc_output.txt" -ErrorAction SilentlyContinue $output = Get-Content "$env:TEMP\sfc_output.txt" -ErrorAction SilentlyContinue
Remove-Item "$env:TEMP\sfc_output.txt" -Force -ErrorAction SilentlyContinue Remove-Item "$env:TEMP\sfc_output.txt" -Force -ErrorAction SilentlyContinue
if ($output -match "did not find any integrity violations") { if ($output -match "did not find any integrity violations") {
Write-Host " $esc[32m$($script:Icons.Success)$esc[0m No integrity violations found" Write-Host " $esc[32m$($script:Icons.Success)$esc[0m No integrity violations found"
} }
@@ -381,19 +385,19 @@ function Test-DiskHealth {
.SYNOPSIS .SYNOPSIS
Check disk health status Check disk health status
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) Disk Health$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) Disk Health$esc[0m"
try { try {
$disks = Get-PhysicalDisk -ErrorAction Stop $disks = Get-PhysicalDisk -ErrorAction Stop
foreach ($disk in $disks) { foreach ($disk in $disks) {
$status = $disk.HealthStatus $status = $disk.HealthStatus
$name = $disk.FriendlyName $name = $disk.FriendlyName
if ($status -eq "Healthy") { if ($status -eq "Healthy") {
Write-Host " $esc[32m$($script:Icons.Success)$esc[0m $name - Healthy" Write-Host " $esc[32m$($script:Icons.Success)$esc[0m $name - Healthy"
} }
@@ -419,23 +423,23 @@ function Test-WindowsUpdate {
.SYNOPSIS .SYNOPSIS
Check Windows Update status Check Windows Update status
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) Windows Update$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) Windows Update$esc[0m"
try { try {
$updateSession = New-Object -ComObject Microsoft.Update.Session $updateSession = New-Object -ComObject Microsoft.Update.Session
$updateSearcher = $updateSession.CreateUpdateSearcher() $updateSearcher = $updateSession.CreateUpdateSearcher()
Write-Host " Checking for updates..." Write-Host " Checking for updates..."
$searchResult = $updateSearcher.Search("IsInstalled=0") $searchResult = $updateSearcher.Search("IsInstalled=0")
$importantUpdates = $searchResult.Updates | Where-Object { $importantUpdates = $searchResult.Updates | Where-Object {
$_.MsrcSeverity -in @('Critical', 'Important') $_.MsrcSeverity -in @('Critical', 'Important')
} }
if ($importantUpdates.Count -gt 0) { if ($importantUpdates.Count -gt 0) {
Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m $($importantUpdates.Count) important updates available" Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m $($importantUpdates.Count) important updates available"
Write-Host " $esc[90mRun Windows Update to install$esc[0m" Write-Host " $esc[90mRun Windows Update to install$esc[0m"
@@ -465,24 +469,24 @@ function Repair-FontCache {
Stops the font cache service, clears the cache files, and restarts. Stops the font cache service, clears the cache files, and restarts.
Fixes issues with fonts not displaying correctly or missing fonts. Fixes issues with fonts not displaying correctly or missing fonts.
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) Font Cache Rebuild$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) Font Cache Rebuild$esc[0m"
if (-not (Test-IsAdmin)) { if (-not (Test-IsAdmin)) {
Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges" Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges"
return return
} }
# Font cache locations # Font cache locations
$fontCachePaths = @( $fontCachePaths = @(
"$env:LOCALAPPDATA\Microsoft\Windows\Fonts" "$env:LOCALAPPDATA\Microsoft\Windows\Fonts"
"$env:WINDIR\ServiceProfiles\LocalService\AppData\Local\FontCache" "$env:WINDIR\ServiceProfiles\LocalService\AppData\Local\FontCache"
"$env:WINDIR\System32\FNTCACHE.DAT" "$env:WINDIR\System32\FNTCACHE.DAT"
) )
if ($script:DryRun) { if ($script:DryRun) {
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would stop Windows Font Cache Service" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would stop Windows Font Cache Service"
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would delete font cache files" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would delete font cache files"
@@ -490,21 +494,21 @@ function Repair-FontCache {
$script:OptimizationsApplied++ $script:OptimizationsApplied++
return return
} }
try { try {
# Stop font cache service # Stop font cache service
Write-Host " $esc[90mStopping Font Cache Service...$esc[0m" Write-Host " $esc[90mStopping Font Cache Service...$esc[0m"
Stop-Service -Name "FontCache" -Force -ErrorAction SilentlyContinue Stop-Service -Name "FontCache" -Force -ErrorAction SilentlyContinue
Stop-Service -Name "FontCache3.0.0.0" -Force -ErrorAction SilentlyContinue Stop-Service -Name "FontCache3.0.0.0" -Force -ErrorAction SilentlyContinue
# Wait a moment for service to stop # Wait a moment for service to stop
Start-Sleep -Seconds 2 Start-Sleep -Seconds 2
# Delete font cache files # Delete font cache files
foreach ($path in $fontCachePaths) { foreach ($path in $fontCachePaths) {
if (Test-Path $path) { if (Test-Path $path) {
if (Test-Path $path -PathType Container) { if (Test-Path $path -PathType Container) {
Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue | Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue |
Remove-Item -Force -Recurse -ErrorAction SilentlyContinue Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
} }
else { else {
@@ -512,12 +516,12 @@ function Repair-FontCache {
} }
} }
} }
# Restart font cache service # Restart font cache service
Write-Host " $esc[90mRestarting Font Cache Service...$esc[0m" Write-Host " $esc[90mRestarting Font Cache Service...$esc[0m"
Start-Service -Name "FontCache" -ErrorAction SilentlyContinue Start-Service -Name "FontCache" -ErrorAction SilentlyContinue
Start-Service -Name "FontCache3.0.0.0" -ErrorAction SilentlyContinue Start-Service -Name "FontCache3.0.0.0" -ErrorAction SilentlyContinue
Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Font cache rebuilt successfully" Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Font cache rebuilt successfully"
Write-Host " $esc[90mNote: Some apps may need restart to see changes$esc[0m" Write-Host " $esc[90mNote: Some apps may need restart to see changes$esc[0m"
$script:OptimizationsApplied++ $script:OptimizationsApplied++
@@ -536,14 +540,14 @@ function Repair-IconCache {
Clears the icon cache database files, forcing Windows to rebuild them. Clears the icon cache database files, forcing Windows to rebuild them.
Fixes issues with missing, corrupted, or outdated icons. Fixes issues with missing, corrupted, or outdated icons.
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) Icon Cache Rebuild$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) Icon Cache Rebuild$esc[0m"
$iconCachePath = "$env:LOCALAPPDATA\Microsoft\Windows\Explorer" $iconCachePath = "$env:LOCALAPPDATA\Microsoft\Windows\Explorer"
if ($script:DryRun) { if ($script:DryRun) {
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would stop Explorer" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would stop Explorer"
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would delete icon cache files (iconcache_*.db)" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would delete icon cache files (iconcache_*.db)"
@@ -551,36 +555,36 @@ function Repair-IconCache {
$script:OptimizationsApplied++ $script:OptimizationsApplied++
return return
} }
try { try {
Write-Host " $esc[90mStopping Explorer...$esc[0m" Write-Host " $esc[90mStopping Explorer...$esc[0m"
Stop-Process -Name "explorer" -Force -ErrorAction SilentlyContinue Stop-Process -Name "explorer" -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2 Start-Sleep -Seconds 2
# Delete icon cache files # Delete icon cache files
$iconCacheFiles = Get-ChildItem -Path $iconCachePath -Filter "iconcache_*.db" -Force -ErrorAction SilentlyContinue $iconCacheFiles = Get-ChildItem -Path $iconCachePath -Filter "iconcache_*.db" -Force -ErrorAction SilentlyContinue
$thumbCacheFiles = Get-ChildItem -Path $iconCachePath -Filter "thumbcache_*.db" -Force -ErrorAction SilentlyContinue $thumbCacheFiles = Get-ChildItem -Path $iconCachePath -Filter "thumbcache_*.db" -Force -ErrorAction SilentlyContinue
$deletedCount = 0 $deletedCount = 0
foreach ($file in $iconCacheFiles) { foreach ($file in $iconCacheFiles) {
Remove-Item -Path $file.FullName -Force -ErrorAction SilentlyContinue Remove-Item -Path $file.FullName -Force -ErrorAction SilentlyContinue
$deletedCount++ $deletedCount++
} }
foreach ($file in $thumbCacheFiles) { foreach ($file in $thumbCacheFiles) {
Remove-Item -Path $file.FullName -Force -ErrorAction SilentlyContinue Remove-Item -Path $file.FullName -Force -ErrorAction SilentlyContinue
$deletedCount++ $deletedCount++
} }
$systemIconCache = "$env:LOCALAPPDATA\IconCache.db" $systemIconCache = "$env:LOCALAPPDATA\IconCache.db"
if (Test-Path $systemIconCache) { if (Test-Path $systemIconCache) {
Remove-Item -Path $systemIconCache -Force -ErrorAction SilentlyContinue Remove-Item -Path $systemIconCache -Force -ErrorAction SilentlyContinue
$deletedCount++ $deletedCount++
} }
Write-Host " $esc[90mRestarting Explorer...$esc[0m" Write-Host " $esc[90mRestarting Explorer...$esc[0m"
Start-Process "explorer.exe" Start-Process "explorer.exe"
Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Icon cache rebuilt ($deletedCount files cleared)" Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Icon cache rebuilt ($deletedCount files cleared)"
Write-Host " $esc[90mNote: Icons will rebuild gradually as you browse$esc[0m" Write-Host " $esc[90mNote: Icons will rebuild gradually as you browse$esc[0m"
$script:OptimizationsApplied++ $script:OptimizationsApplied++
@@ -599,19 +603,19 @@ function Repair-SearchIndex {
Stops the Windows Search service, deletes the search index, and restarts. Stops the Windows Search service, deletes the search index, and restarts.
Fixes issues with search not finding files or returning incorrect results. Fixes issues with search not finding files or returning incorrect results.
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) Windows Search Index Reset$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) Windows Search Index Reset$esc[0m"
if (-not (Test-IsAdmin)) { if (-not (Test-IsAdmin)) {
Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges" Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges"
return return
} }
$searchIndexPath = "$env:ProgramData\Microsoft\Search\Data\Applications\Windows" $searchIndexPath = "$env:ProgramData\Microsoft\Search\Data\Applications\Windows"
if ($script:DryRun) { if ($script:DryRun) {
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would stop Windows Search service" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would stop Windows Search service"
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would delete search index database" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would delete search index database"
@@ -619,20 +623,20 @@ function Repair-SearchIndex {
$script:OptimizationsApplied++ $script:OptimizationsApplied++
return return
} }
try { try {
Write-Host " $esc[90mStopping Windows Search service...$esc[0m" Write-Host " $esc[90mStopping Windows Search service...$esc[0m"
Stop-Service -Name "WSearch" -Force -ErrorAction Stop Stop-Service -Name "WSearch" -Force -ErrorAction Stop
Start-Sleep -Seconds 3 Start-Sleep -Seconds 3
if (Test-Path $searchIndexPath) { if (Test-Path $searchIndexPath) {
Write-Host " $esc[90mDeleting search index...$esc[0m" Write-Host " $esc[90mDeleting search index...$esc[0m"
Remove-Item -Path "$searchIndexPath\*" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "$searchIndexPath\*" -Recurse -Force -ErrorAction SilentlyContinue
} }
Write-Host " $esc[90mRestarting Windows Search service...$esc[0m" Write-Host " $esc[90mRestarting Windows Search service...$esc[0m"
Start-Service -Name "WSearch" -ErrorAction Stop Start-Service -Name "WSearch" -ErrorAction Stop
Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Search index reset successfully" Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Search index reset successfully"
Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Indexing will rebuild in the background (may take hours)" Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Indexing will rebuild in the background (may take hours)"
$script:OptimizationsApplied++ $script:OptimizationsApplied++
@@ -651,23 +655,23 @@ function Repair-StoreCache {
Runs wsreset.exe to clear the Windows Store cache. Runs wsreset.exe to clear the Windows Store cache.
Fixes issues with Store apps not installing, updating, or launching. Fixes issues with Store apps not installing, updating, or launching.
#> #>
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) Windows Store Cache Reset$esc[0m" Write-Host "$esc[34m$($script:Icons.Arrow) Windows Store Cache Reset$esc[0m"
if ($script:DryRun) { if ($script:DryRun) {
Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would run wsreset.exe" Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would run wsreset.exe"
$script:OptimizationsApplied++ $script:OptimizationsApplied++
return return
} }
try { try {
Write-Host " $esc[90mResetting Windows Store cache...$esc[0m" Write-Host " $esc[90mResetting Windows Store cache...$esc[0m"
$wsreset = Start-Process -FilePath "wsreset.exe" -PassThru -WindowStyle Hidden $wsreset = Start-Process -FilePath "wsreset.exe" -PassThru -WindowStyle Hidden
$wsreset.WaitForExit(30000) $wsreset.WaitForExit(30000)
if ($wsreset.ExitCode -eq 0) { if ($wsreset.ExitCode -eq 0) {
Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Windows Store cache reset successfully" Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Windows Store cache reset successfully"
} }
@@ -687,7 +691,7 @@ function Repair-StoreCache {
function Show-OptimizeSummary { function Show-OptimizeSummary {
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[1;35m" -NoNewline Write-Host "$esc[1;35m" -NoNewline
if ($script:DryRun) { if ($script:DryRun) {
@@ -698,18 +702,22 @@ function Show-OptimizeSummary {
} }
Write-Host "$esc[0m" Write-Host "$esc[0m"
Write-Host "" Write-Host ""
if ($script:DryRun) { if ($script:DryRun) {
Write-Host " Would apply $esc[33m$($script:OptimizationsApplied)$esc[0m optimizations" Write-Host " Would apply $esc[33m$($script:OptimizationsApplied)$esc[0m optimizations"
Write-Host " Run without --dry-run to apply changes" Write-Host " Run without --dry-run to apply changes"
} }
else { else {
Write-Host " Optimizations applied: $esc[32m$($script:OptimizationsApplied)$esc[0m" Write-Host " Optimizations applied: $esc[32m$($script:OptimizationsApplied)$esc[0m"
if ($script:RepairsApplied -gt 0) {
Write-Host " Repairs applied: $esc[32m$($script:RepairsApplied)$esc[0m"
}
if ($script:IssuesFixed -gt 0) { if ($script:IssuesFixed -gt 0) {
Write-Host " Issues fixed: $esc[32m$($script:IssuesFixed)$esc[0m" Write-Host " Issues fixed: $esc[32m$($script:IssuesFixed)$esc[0m"
} }
if ($script:IssuesFound -gt 0) { if ($script:IssuesFound -gt 0) {
Write-Host " Issues found: $esc[33m$($script:IssuesFound)$esc[0m" Write-Host " Issues found: $esc[33m$($script:IssuesFound)$esc[0m"
} }
@@ -717,7 +725,7 @@ function Show-OptimizeSummary {
Write-Host " System health: $esc[32mGood$esc[0m" Write-Host " System health: $esc[32mGood$esc[0m"
} }
} }
Write-Host "" Write-Host ""
} }
@@ -731,49 +739,61 @@ function Main {
$env:MOLE_DEBUG = "1" $env:MOLE_DEBUG = "1"
$DebugPreference = "Continue" $DebugPreference = "Continue"
} }
# Show help # Show help
if ($ShowHelp) { if ($ShowHelp) {
Show-OptimizeHelp Show-OptimizeHelp
return return
} }
# Set dry-run mode # Set dry-run mode
$script:DryRun = $DryRun $script:DryRun = $DryRun
# Clear screen # Clear screen
Clear-Host Clear-Host
$esc = [char]27 $esc = [char]27
Write-Host "" Write-Host ""
Write-Host "$esc[1;35mOptimize and Maintain$esc[0m" Write-Host "$esc[1;35mOptimize and Maintain$esc[0m"
Write-Host "" Write-Host ""
if ($script:DryRun) { if ($script:DryRun) {
Write-Host "$esc[33m$($script:Icons.DryRun) DRY RUN MODE$esc[0m - No changes will be made" Write-Host "$esc[33m$($script:Icons.DryRun) DRY RUN MODE$esc[0m - No changes will be made"
Write-Host "" Write-Host ""
} }
# Show system health # Show system health
$health = Get-SystemHealth $health = Get-SystemHealth
Show-SystemHealth -Health $health Show-SystemHealth -Health $health
# Run optimizations # Run optimizations
Optimize-DiskDrive Optimize-DiskDrive
Clear-DnsCache Clear-DnsCache
Optimize-Network Optimize-Network
# Run cache rebuilds (repairs integrated into optimize)
Repair-FontCache
Repair-IconCache
Optimize-SearchIndex
Repair-StoreCache
# Run health checks # Run health checks
Get-StartupPrograms Get-StartupPrograms
Test-DiskHealth Test-DiskHealth
Test-WindowsUpdate Test-WindowsUpdate
# Run repairs (consolidated)
Write-Host ""
Write-Host "$esc[34m$($script:Icons.Arrow) System Repairs$esc[0m"
Repair-FontCache
Repair-StoreCache
Repair-SearchIndex
Repair-IconCache
# System file check is slow, ask first
if (-not $script:DryRun -and (Test-IsAdmin)) {
Write-Host ""
$runSfc = Read-Host "Run System File Checker? This may take several minutes (y/N)"
if ($runSfc -eq 'y' -or $runSfc -eq 'Y') {
Test-SystemFiles
}
}
# Summary # Summary
Show-OptimizeSummary Show-OptimizeSummary
} }

View File

@@ -11,6 +11,13 @@ param(
[switch]$Paths, [switch]$Paths,
[Alias('h')] [Alias('h')]
[Alias('debug')]
[switch]$DebugMode,
[Alias('paths')]
[switch]$Paths,
[Alias('help')]
[switch]$ShowHelp [switch]$ShowHelp
) )

View File

@@ -60,12 +60,12 @@ function Show-MainHelp {
Write-Host "" Write-Host ""
Write-Host " ${green}COMMANDS:${nc}" Write-Host " ${green}COMMANDS:${nc}"
Write-Host "" Write-Host ""
Write-Host " ${cyan}clean${nc} Deep system cleanup (caches, temp, logs)" Write-Host " ${cyan}clean${nc} Deep system cleanup"
Write-Host " ${cyan}uninstall${nc} Smart application uninstaller" Write-Host " ${cyan}uninstall${nc} Smart application uninstaller"
Write-Host " ${cyan}analyze${nc} Visual disk space analyzer"
Write-Host " ${cyan}status${nc} Real-time system monitor"
Write-Host " ${cyan}optimize${nc} System optimization and repairs" Write-Host " ${cyan}optimize${nc} System optimization and repairs"
Write-Host " ${cyan}purge${nc} Clean project build artifacts" Write-Host " ${cyan}analyze${nc} Disk space analyzer"
Write-Host " ${cyan}status${nc} System monitor"
Write-Host " ${cyan}purge${nc} Clean project artifacts"
Write-Host "" Write-Host ""
Write-Host " ${green}OPTIONS:${nc}" Write-Host " ${green}OPTIONS:${nc}"
Write-Host "" Write-Host ""
@@ -83,6 +83,12 @@ function Show-MainHelp {
Write-Host " ${gray}mo optimize${nc} ${gray}# Optimize system (includes repairs)${nc}" Write-Host " ${gray}mo optimize${nc} ${gray}# Optimize system (includes repairs)${nc}"
Write-Host " ${gray}mo optimize --dry-run${nc} ${gray}# Preview optimizations${nc}" Write-Host " ${gray}mo optimize --dry-run${nc} ${gray}# Preview optimizations${nc}"
Write-Host " ${gray}mo purge${nc} ${gray}# Clean dev artifacts${nc}" Write-Host " ${gray}mo purge${nc} ${gray}# Clean dev artifacts${nc}"
Write-Host " ${gray}mo${nc} ${gray}# Interactive menu${nc}"
Write-Host " ${gray}mo clean${nc} ${gray}# Deep cleanup${nc}"
Write-Host " ${gray}mo clean --dry-run${nc} ${gray}# Preview cleanup${nc}"
Write-Host " ${gray}mo optimize${nc} ${gray}# Optimize system${nc}"
Write-Host " ${gray}mo optimize --dry-run${nc} ${gray}# Preview optimization${nc}"
Write-Host " ${gray}mo uninstall${nc} ${gray}# Uninstall apps${nc}"
Write-Host "" Write-Host ""
Write-Host " ${green}ENVIRONMENT:${nc}" Write-Host " ${green}ENVIRONMENT:${nc}"
Write-Host "" Write-Host ""
@@ -105,6 +111,12 @@ function Show-MainMenu {
Command = "clean" Command = "clean"
Icon = $script:Icons.Trash Icon = $script:Icons.Trash
} }
@{
Name = "Optimize"
Description = "Optimization & repairs"
Command = "optimize"
Icon = $script:Icons.Arrow
}
@{ @{
Name = "Uninstall" Name = "Uninstall"
Description = "Remove applications" Description = "Remove applications"
@@ -123,12 +135,6 @@ function Show-MainMenu {
Command = "status" Command = "status"
Icon = $script:Icons.Solid Icon = $script:Icons.Solid
} }
@{
Name = "Optimize"
Description = "Optimization & repairs"
Command = "optimize"
Icon = $script:Icons.Arrow
}
@{ @{
Name = "Purge" Name = "Purge"
Description = "Clean dev artifacts" Description = "Clean dev artifacts"
@@ -161,7 +167,7 @@ function Invoke-MoleCommand {
if (-not (Test-Path $scriptPath)) { if (-not (Test-Path $scriptPath)) {
Write-MoleError "Unknown command: $CommandName" Write-MoleError "Unknown command: $CommandName"
Write-Host "" Write-Host ""
Write-Host "Run 'mole -ShowHelp' for available commands" Write-Host "Run 'mo --help' for available commands"
return return
} }
@@ -177,13 +183,13 @@ function Invoke-MoleCommand {
# Remove surrounding quotes if present # Remove surrounding quotes if present
$cleanArg = $arg.Trim("'`"") $cleanArg = $arg.Trim("'`"")
if ($cleanArg -match '^-(\w+)$') { if ($cleanArg -match '^-{1,2}([\w-]+)$') {
# It's a switch parameter (e.g., -DryRun) # It's a switch parameter (e.g., -DryRun or --dry-run)
$paramName = $Matches[1] $paramName = $Matches[1]
$splatParams[$paramName] = $true $splatParams[$paramName] = $true
} }
elseif ($cleanArg -match '^-(\w+)[=:](.+)$') { elseif ($cleanArg -match '^-{1,2}([\w-]+)[=:](.+)$') {
# It's a named parameter with value (e.g., -Name=Value or -Name:Value) # It's a named parameter with value (e.g., --name=value)
$paramName = $Matches[1] $paramName = $Matches[1]
$paramValue = $Matches[2].Trim("'`"") $paramValue = $Matches[2].Trim("'`"")
$splatParams[$paramName] = $paramValue $splatParams[$paramName] = $paramValue

87
quick-install.ps1 Normal file
View File

@@ -0,0 +1,87 @@
#!/usr/bin/env pwsh
# Mole Quick Installer for Windows
# One-liner install: iwr -useb https://raw.githubusercontent.com/tw93/Mole/windows/quick-install.ps1 | iex
#Requires -Version 5.1
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
# Colors
$ESC = [char]27
$Colors = @{
Green = "$ESC[32m"
Yellow = "$ESC[33m"
Cyan = "$ESC[36m"
Red = "$ESC[31m"
NC = "$ESC[0m"
}
function Write-Step {
param([string]$Message)
Write-Host " $($Colors.Cyan)$($Colors.NC) $Message"
}
function Write-Success {
param([string]$Message)
Write-Host " $($Colors.Green)$($Colors.NC) $Message"
}
function Write-ErrorMsg {
param([string]$Message)
Write-Host " $($Colors.Red)$($Colors.NC) $Message"
}
# Main installation
try {
Write-Host ""
Write-Host " $($Colors.Cyan)Mole Quick Installer$($Colors.NC)"
Write-Host " $($Colors.Yellow)Installing experimental Windows version...$($Colors.NC)"
Write-Host ""
# Check prerequisites
Write-Step "Checking prerequisites..."
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
Write-ErrorMsg "Git is not installed. Please install Git first:"
Write-Host " https://git-scm.com/download/win"
exit 1
}
Write-Success "Git found"
# Create temp directory
$TempDir = Join-Path $env:TEMP "mole-install-$(Get-Random)"
Write-Step "Downloading Mole..."
# Clone windows branch
git clone --quiet --depth 1 --branch windows https://github.com/tw93/Mole.git $TempDir 2>&1 | Out-Null
if (-not (Test-Path "$TempDir\install.ps1")) {
Write-ErrorMsg "Failed to download installer"
exit 1
}
Write-Success "Downloaded to temp directory"
# Run installer
Write-Step "Running installer..."
Write-Host ""
& "$TempDir\install.ps1" -AddToPath
Write-Host ""
Write-Success "Installation complete!"
Write-Host ""
Write-Host " Run ${Colors.Green}mole$($Colors.NC) to get started"
Write-Host ""
} catch {
Write-ErrorMsg "Installation failed: $_"
exit 1
} finally {
# Cleanup
if (Test-Path $TempDir) {
Remove-Item $TempDir -Recurse -Force -ErrorAction SilentlyContinue
}
}