windowsweep 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/AI-INTEGRATION-GUIDE.md +16 -12
  2. package/CHANGELOG.md +82 -0
  3. package/LICENSE +21 -21
  4. package/README.md +104 -69
  5. package/VERSION +1 -1
  6. package/lib/actions.ps1 +212 -212
  7. package/lib/config.ps1 +108 -99
  8. package/lib/constants.ps1 +103 -93
  9. package/lib/external.ps1 +87 -0
  10. package/lib/fs.ps1 +189 -180
  11. package/lib/log.ps1 +140 -140
  12. package/lib/safety.ps1 +467 -493
  13. package/lib/scan.ps1 +109 -100
  14. package/lib/ui.ps1 +275 -275
  15. package/modules/android_avd.ps1 +36 -36
  16. package/modules/app_caches.ps1 +58 -58
  17. package/modules/browsers.ps1 +33 -33
  18. package/modules/build_tools.ps1 +35 -35
  19. package/modules/crash_trap.ps1 +89 -89
  20. package/modules/disk_usage.ps1 +49 -49
  21. package/modules/docker.ps1 +93 -93
  22. package/modules/editors.ps1 +150 -150
  23. package/modules/globals_audit.ps1 +236 -236
  24. package/modules/health.ps1 +101 -101
  25. package/modules/installed_programs.ps1 +118 -118
  26. package/modules/menu.ps1 +63 -63
  27. package/modules/notify.ps1 +60 -60
  28. package/modules/orphaned_appdata.ps1 +189 -189
  29. package/modules/personal.ps1 +126 -126
  30. package/modules/pkg_managers.ps1 +73 -73
  31. package/modules/projects.ps1 +160 -160
  32. package/modules/release_helpers.ps1 +438 -438
  33. package/modules/reports.ps1 +212 -212
  34. package/modules/runner.ps1 +246 -239
  35. package/modules/self_test_contract.ps1 +195 -0
  36. package/modules/self_test_extra.ps1 +366 -360
  37. package/modules/startup_audit.ps1 +126 -126
  38. package/modules/system_admin.ps1 +220 -220
  39. package/modules/test_runners.ps1 +24 -24
  40. package/modules/walkthrough.ps1 +80 -79
  41. package/modules/windows_user.ps1 +118 -118
  42. package/package.json +3 -3
  43. package/windowsweep.ps1 +322 -316
@@ -1,79 +1,80 @@
1
- # walkthrough.ps1 - the default interactive mode: every category, one step at a time, with a running total.
2
-
3
- function Show-Welcome {
4
- $ws = $Script:WS
5
- Write-Banner
6
- Write-Box "$Script:WS_NAME" $Script:WS_TAGLINE
7
- Show-DriveTable
8
- Write-UiLine '' 'Gray'
9
- Write-Plain ' This walkthrough visits every cleanup category. At each step:'
10
- Write-Plain ' a run it (default) s skip it q stop the walkthrough'
11
- if ($ws.DryRun) { Write-UiLine ' DRY-RUN: every step only reports what it would remove.' 'Magenta' }
12
- $dev = 'off'
13
- if ($ws.Developer) { $dev = 'on' }
14
- Write-Note "developer mode: $dev idle window: $($ws.Days) days temp window: $($ws.TempDays) days"
15
- Write-Note "logs and reports: $($ws.Home)"
16
- Write-Note "by $Script:WS_AUTHOR - $Script:WS_WEB"
17
- Wait-Enter
18
- }
19
-
20
- function Invoke-Walkthrough {
21
- $ws = $Script:WS
22
- if (-not $ws.Interactive) {
23
- Write-Err 'The walkthrough needs an interactive console. For unattended runs use: windowsweep --all --yes (or --scan / --dry-run to look first)'
24
- $ws.ExitCode = $Script:WS_EXIT_USAGE
25
- return
26
- }
27
- Show-Welcome
28
- Write-Box 'Pre-scan' 'Read-only - what each section can reach right now'
29
- if (Get-Command Invoke-Section00 -ErrorAction SilentlyContinue) { Invoke-Section00 }
30
- $null = Show-ScanTable
31
- Wait-Enter
32
-
33
- $steps = @($Script:WS_WALKTHROUGH)
34
- if ($ws.IsAdmin) { $steps += $Script:WS_WALKTHROUGH_ADMIN }
35
- $total = $steps.Count + 2
36
- $n = 0
37
- $quit = $false
38
- foreach ($id in $steps) {
39
- $n++
40
- $sec = Get-Section $id
41
- Write-Step -N $n -Total $total -Title $sec.Title
42
- $choice = Read-Choice -Prompt ' action: a run s skip q quit > ' -Default 'a'
43
- if ($choice -eq 'q') { Write-Warn 'walkthrough stopped'; Add-ReportStep -Section $id -Title $sec.Title -Status 'skipped' -Note 'quit'; $quit = $true; break }
44
- if ($choice -eq 's') { Write-Info 'skipped'; Add-ReportStep -Section $id -Title $sec.Title -Status 'skipped'; continue }
45
- $ws.SectionPreConfirmed = $true
46
- try { Invoke-SectionById -Id $id } finally { $ws.SectionPreConfirmed = $false }
47
- }
48
- if (-not $quit -and -not $ws.IsAdmin) {
49
- $n++
50
- Write-Step -N $n -Total $total -Title 'System-level cleanup (needs Administrator)'
51
- Write-Plain ' Sections 12 (Windows Update cache), 13 (Disk Cleanup engine) and 14 (component store) need an elevated'
52
- Write-Plain ' console. Run them afterwards with:'
53
- Write-Plain ' windowsweep --profile system --yes --elevate'
54
- Write-Plain ' and, if you want the hibernation file gone too (section 15):'
55
- Write-Plain ' windowsweep --only 12,13,14,15 --hiberfil off --yes --i-understand-deep --elevate'
56
- $ws.Hints += 'Admin sections: windowsweep --profile system --yes --elevate'
57
- Wait-Enter
58
- }
59
- if (-not $quit) {
60
- $n++
61
- Write-Step -N $n -Total $total -Title 'Disk usage report'
62
- Invoke-SectionById -Id 21
63
- }
64
- Show-SessionSummary
65
- Show-NextSteps
66
- }
67
-
68
- function Show-NextSteps {
69
- $ws = $Script:WS
70
- $tips = @()
71
- if (-not (Get-ScheduledTask -TaskName $Script:WS_TASK_NAME -ErrorAction SilentlyContinue)) { $tips += 'Schedule the safe batch weekly: windowsweep --install-task' }
72
- $tips += 'Browse or export past reports: windowsweep --reports'
73
- if ($ws.DryRun) { $tips += 'This was a dry-run. Run the same command without --dry-run to reclaim the space.' }
74
- if ($tips.Count -gt 0) {
75
- Write-UiLine '' 'Gray'
76
- Write-Info 'next steps:'
77
- foreach ($t in $tips) { Write-Note $t }
78
- }
79
- }
1
+ # walkthrough.ps1 - the default interactive mode: every category, one step at a time, with a running total.
2
+
3
+ function Show-Welcome {
4
+ $ws = $Script:WS
5
+ Write-Banner
6
+ Write-Box "$Script:WS_NAME" $Script:WS_TAGLINE
7
+ Show-DriveTable
8
+ Write-UiLine '' 'Gray'
9
+ Write-Plain " This walkthrough visits $($Script:WS_WALKTHROUGH.Count) sections, one at a time. At each step:"
10
+ Write-Plain ' a run it (default) s skip it q stop the walkthrough'
11
+ if ($ws.DryRun) { Write-UiLine ' DRY-RUN: every step only reports what it would remove.' 'Magenta' }
12
+ $dev = 'off'
13
+ if ($ws.Developer) { $dev = 'on' }
14
+ Write-Note "developer mode: $dev idle window: $($ws.Days) days temp window: $($ws.TempDays) days"
15
+ Write-Note "logs and reports: $($ws.Home)"
16
+ Write-Note "by $Script:WS_AUTHOR - $Script:WS_WEB"
17
+ Wait-Enter
18
+ }
19
+
20
+ function Invoke-Walkthrough {
21
+ $ws = $Script:WS
22
+ if (-not $ws.Interactive) {
23
+ Write-Err 'The walkthrough needs an interactive console. For unattended runs use: windowsweep --all --yes (or --scan / --dry-run to look first)'
24
+ $ws.ExitCode = $Script:WS_EXIT_USAGE
25
+ return
26
+ }
27
+ Show-Welcome
28
+ Write-Box 'Pre-scan' 'Deletes nothing - what each section can reach right now'
29
+ if (Get-Command Invoke-Section00 -ErrorAction SilentlyContinue) { Invoke-Section00 }
30
+ $null = Show-ScanTable
31
+ Wait-Enter
32
+
33
+ $steps = @($Script:WS_WALKTHROUGH)
34
+ if ($ws.IsAdmin) { $steps += $Script:WS_WALKTHROUGH_ADMIN }
35
+ $total = $steps.Count + 2
36
+ $n = 0
37
+ $quit = $false
38
+ foreach ($id in $steps) {
39
+ $n++
40
+ $sec = Get-Section $id
41
+ Write-Step -N $n -Total $total -Title $sec.Title
42
+ $choice = Read-Choice -Prompt ' action: a run s skip q quit > ' -Default 'a'
43
+ if ($choice -eq 'q') { Write-Warn 'walkthrough stopped'; Add-ReportStep -Section $id -Title $sec.Title -Status 'skipped' -Note 'quit'; $quit = $true; break }
44
+ if ($choice -eq 's') { Write-Info 'skipped'; Add-ReportStep -Section $id -Title $sec.Title -Status 'skipped'; continue }
45
+ $ws.SectionPreConfirmed = $true
46
+ try { Invoke-SectionById -Id $id } finally { $ws.SectionPreConfirmed = $false }
47
+ }
48
+ if (-not $quit -and -not $ws.IsAdmin) {
49
+ $n++
50
+ Write-Step -N $n -Total $total -Title 'System-level cleanup (needs Administrator)'
51
+ Write-Plain ' This walkthrough runs 12 (Windows Update cache), 13 (Disk Cleanup engine) and 14 (component'
52
+ Write-Plain ' store) when the console is elevated. Six sections need an elevated console in all - 15, 16 and'
53
+ Write-Plain ' 20 need --i-understand-deep as well. Run the three afterwards with:'
54
+ Write-Plain ' windowsweep --profile system --yes --elevate'
55
+ Write-Plain ' and, to remove the hibernation file too (section 15):'
56
+ Write-Plain ' windowsweep --only 12,13,14,15 --hiberfil off --yes --i-understand-deep --elevate'
57
+ $ws.Hints += 'Admin sections: windowsweep --profile system --yes --elevate'
58
+ Wait-Enter
59
+ }
60
+ if (-not $quit) {
61
+ $n++
62
+ Write-Step -N $n -Total $total -Title 'Disk usage report'
63
+ Invoke-SectionById -Id 21
64
+ }
65
+ Show-SessionSummary
66
+ Show-NextSteps
67
+ }
68
+
69
+ function Show-NextSteps {
70
+ $ws = $Script:WS
71
+ $tips = @()
72
+ if (-not (Get-ScheduledTask -TaskName $Script:WS_TASK_NAME -ErrorAction SilentlyContinue)) { $tips += 'Schedule the safe batch weekly: windowsweep --install-task' }
73
+ $tips += 'Browse or export past reports: windowsweep --reports'
74
+ if ($ws.DryRun) { $tips += 'This was a dry-run. Run the same command without --dry-run to reclaim the space.' }
75
+ if ($tips.Count -gt 0) {
76
+ Write-UiLine '' 'Gray'
77
+ Write-Info 'next steps:'
78
+ foreach ($t in $tips) { Write-Note $t }
79
+ }
80
+ }
@@ -1,118 +1,118 @@
1
- # windows_user.ps1 - section 9 (Windows user caches), section 10 (user temp), section 11 (Recycle Bin).
2
-
3
- function Get-Targets09 {
4
- $P = $Script:P
5
- return @(
6
- (New-Target 9 'Internet cache (INetCache)' "$($P.L)\Microsoft\Windows\INetCache" -Mode clear -Note 'IE / legacy WebView cache')
7
- (New-Target 9 'Windows Error Reporting (user)' "$($P.L)\Microsoft\Windows\WER" -Mode clear)
8
- (New-Target 9 'Crash dumps' "$($P.L)\CrashDumps" -Mode clear-old -Days 7)
9
- (New-Target 9 'DirectX shader cache' "$($P.L)\D3DSCache" -Mode clear)
10
- (New-Target 9 'NVIDIA DirectX shader cache' "$($P.L)\NVIDIA\DXCache" -Mode clear)
11
- (New-Target 9 'NVIDIA OpenGL shader cache' "$($P.L)\NVIDIA\GLCache" -Mode clear)
12
- (New-Target 9 'NVIDIA NV_Cache' "$($P.L)\NVIDIA Corporation\NV_Cache" -Mode clear)
13
- (New-Target 9 'AMD DirectX shader cache' "$($P.L)\AMD\DxCache" -Mode clear)
14
- (New-Target 9 'AMD OpenGL shader cache' "$($P.L)\AMD\GLCache" -Mode clear)
15
- (New-Target 9 'Intel shader cache' "$($P.L)\Intel\ShaderCache" -Mode clear)
16
- (New-Target 9 'Remote Desktop bitmap cache' "$($P.L)\Microsoft\Terminal Server Client\Cache" -Mode clear)
17
- (New-Target 9 'OneDrive logs' "$($P.L)\Microsoft\OneDrive\logs" -Mode clear-old -Days 7)
18
- (New-Target 9 'OneDrive setup logs' "$($P.L)\Microsoft\OneDrive\setup\logs" -Mode clear-old -Days 7)
19
- (New-Target 9 'Store apps TempState' "$($P.L)\Packages\*\TempState" -Kind glob -Mode clear)
20
- (New-Target 9 'Store apps AC\Temp' "$($P.L)\Packages\*\AC\Temp" -Kind glob -Mode clear)
21
- (New-Target 9 'Store apps AC\INetCache' "$($P.L)\Packages\*\AC\INetCache" -Kind glob -Mode clear)
22
- (New-Target 9 'Themes cached files' "$($P.L)\Microsoft\Windows\Themes\CachedFiles" -Mode clear)
23
- (New-Target 9 'PowerShell startup profile data' "$($P.L)\Microsoft\Windows\PowerShell\StartupProfileData-*" -Kind fileglob -Mode file)
24
- (New-Target 9 'CLR usage logs' "$($P.L)\Microsoft\CLR_v4.0\UsageLogs" -Mode clear)
25
- (New-Target 9 'CLR usage logs (32-bit)' "$($P.L)\Microsoft\CLR_v4.0_32\UsageLogs" -Mode clear)
26
- (New-Target 9 'Explorer thumbcache leftovers' "$($P.L)\Microsoft\Windows\Explorer\ThumbCacheToDelete" -Mode clear)
27
- (New-Target 9 'Explorer iconcache leftovers' "$($P.L)\Microsoft\Windows\Explorer\IconCacheToDelete" -Mode clear)
28
- (New-Target 9 'Explorer startup logs' "$($P.L)\Microsoft\Windows\Explorer\ExplorerStartupLog*.etl" -Kind fileglob -Mode file)
29
- (New-Target 9 'Windows schema cache' "$($P.L)\Microsoft\Windows\SchCache" -Mode clear)
30
- (New-Target 9 'Delivery Optimization (per user)' "$($P.L)\Microsoft\Windows\DeliveryOptimization\Cache" -Mode clear)
31
- (New-Target 9 'Certificate URL cache' "$($P.LL)\Microsoft\CryptnetUrlCache" -Mode clear)
32
- (New-Target 9 'Diagnostics results' "$($P.L)\Diagnostics" -Mode clear-old -Days 30)
33
- (New-Target 9 'DNS resolver cache' 'ipconfig /flushdns' -Kind cmd)
34
- (New-Target 9 'Microsoft Store download cache' 'wsreset.exe' -Kind cmd -Note 'printed as a next step, never run for you: wsreset has no silent mode and always opens the Store')
35
- )
36
- }
37
-
38
- function Invoke-Section09 {
39
- Write-SectionIntro @(
40
- 'Caches Windows and its drivers rebuild silently: shader caches, error-report queues, crash dumps, Store-app',
41
- 'temp folders, Remote Desktop bitmaps. Files an app is holding open are skipped. The Explorer thumbnail and',
42
- 'icon databases themselves belong to Disk Cleanup (section 13, admin), which rebuilds them cleanly.'
43
- )
44
- $targets = Get-Targets09
45
- $null = Show-TargetSizes $targets
46
- if (-not (Confirm-Section 'Clear Windows user caches now?')) { Write-Info 'skipped'; return }
47
- $null = Invoke-TargetList $targets
48
- $r = Invoke-External -FilePath 'ipconfig.exe' -ArgumentList @('/flushdns') -Destructive -Quiet -Label 'ipconfig /flushdns'
49
- if ($r.Ran -and $r.ExitCode -eq 0) { Write-Ok 'DNS resolver cache flushed' }
50
- # wsreset is the only lever for the Store download cache, and it has no silent switch: every build opens
51
- # the Store window when it finishes. A cleanup run must not pop a window, so it is offered, never executed.
52
- if (Test-PathPresent (Join-Path $Script:P.SR 'System32\wsreset.exe')) {
53
- $Script:WS.Hints += 'Microsoft Store cache: run wsreset.exe yourself when you want it cleared (it opens the Store when it finishes)'
54
- }
55
- }
56
-
57
- # ---------------------------------------------------------------------------------------------
58
- # Section 10 - user temp
59
- # ---------------------------------------------------------------------------------------------
60
-
61
- function Get-TempRoots {
62
- $P = $Script:P
63
- $roots = @()
64
- foreach ($r in @($P.TEMP, $P.TMP, (Join-Path $P.L 'Temp'), (Join-Path $P.LL 'Temp'))) {
65
- if ($r -and (Test-DirPresent $r)) { $f = Get-FullPath $r; if ($roots -notcontains $f) { $roots += $f } }
66
- }
67
- return $roots
68
- }
69
-
70
- function Get-Targets10 {
71
- $t = @()
72
- foreach ($r in (Get-TempRoots)) { $t += (New-Target 10 'User temp' $r -Mode prune -Days $Script:WS.TempDays -Note "files idle $($Script:WS.TempDays)+ days; open files are skipped") }
73
- return $t
74
- }
75
-
76
- function Invoke-Section10 {
77
- $ws = $Script:WS
78
- Write-SectionIntro @(
79
- "Temporary files idle for $($ws.TempDays)+ days. Files a running program still has open are skipped, so an",
80
- 'installer or build that is in progress right now is safe. Lower the window with --temp-days 1 for a harder sweep.'
81
- )
82
- $targets = @(Get-Targets10)
83
- if ($targets.Count -eq 0) { Write-Info 'no temp folders found'; return }
84
- $null = Show-TargetSizes $targets
85
- if (-not (Confirm-Section "Remove temp files idle $($ws.TempDays)+ days?")) { Write-Info 'skipped'; return }
86
- $null = Invoke-TargetList $targets
87
- }
88
-
89
- # ---------------------------------------------------------------------------------------------
90
- # Section 11 - Recycle Bin
91
- # ---------------------------------------------------------------------------------------------
92
-
93
- function Get-Targets11 { return @((New-Target 11 'Recycle Bin (all drives)' 'Clear-RecycleBin' -Kind cmd -Note 'PERMANENT - everything in the bin is gone')) }
94
-
95
- function Get-RecycleBinStats {
96
- $items = 0; $bytes = [long]0
97
- try {
98
- $shell = New-Object -ComObject Shell.Application
99
- $bin = $shell.NameSpace(0xA)
100
- foreach ($i in $bin.Items()) { $items++; try { $bytes += [long]$i.Size } catch { $null = $_ } }
101
- } catch { $null = $_ }
102
- return [pscustomobject]@{ Items = $items; Bytes = $bytes }
103
- }
104
-
105
- function Invoke-Section11 {
106
- $ws = $Script:WS
107
- Write-SectionIntro @('Emptying the Recycle Bin is permanent: nothing in it can be restored afterwards.')
108
- $s = Get-RecycleBinStats
109
- Write-Kv 'Recycle Bin:' ("{0} item(s), {1}" -f $s.Items, (Format-Bytes $s.Bytes))
110
- if ($s.Items -eq 0) { Write-Info 'already empty'; return }
111
- if ($ws.DryRun) { Write-DryRun ("would empty the Recycle Bin (" + (Format-Bytes $s.Bytes) + ')'); Add-Freed $s.Bytes; return }
112
- if (-not (Confirm-Ui -Prompt "Permanently delete all $($s.Items) item(s) in the Recycle Bin?" -Default 'n')) { Write-Info 'skipped'; return }
113
- try {
114
- Clear-RecycleBin -Force -ErrorAction Stop
115
- Add-Freed $s.Bytes
116
- Write-Ok ("Recycle Bin emptied (" + (Format-Bytes $s.Bytes) + ')')
117
- } catch { Write-Err "could not empty the Recycle Bin: $($_.Exception.Message)" }
118
- }
1
+ # windows_user.ps1 - section 9 (Windows user caches), section 10 (user temp), section 11 (Recycle Bin).
2
+
3
+ function Get-Targets09 {
4
+ $P = $Script:P
5
+ return @(
6
+ (New-Target 9 'Internet cache (INetCache)' "$($P.L)\Microsoft\Windows\INetCache" -Mode clear -Note 'IE / legacy WebView cache')
7
+ (New-Target 9 'Windows Error Reporting (user)' "$($P.L)\Microsoft\Windows\WER" -Mode clear)
8
+ (New-Target 9 'Crash dumps' "$($P.L)\CrashDumps" -Mode clear-old -Days 7)
9
+ (New-Target 9 'DirectX shader cache' "$($P.L)\D3DSCache" -Mode clear)
10
+ (New-Target 9 'NVIDIA DirectX shader cache' "$($P.L)\NVIDIA\DXCache" -Mode clear)
11
+ (New-Target 9 'NVIDIA OpenGL shader cache' "$($P.L)\NVIDIA\GLCache" -Mode clear)
12
+ (New-Target 9 'NVIDIA NV_Cache' "$($P.L)\NVIDIA Corporation\NV_Cache" -Mode clear)
13
+ (New-Target 9 'AMD DirectX shader cache' "$($P.L)\AMD\DxCache" -Mode clear)
14
+ (New-Target 9 'AMD OpenGL shader cache' "$($P.L)\AMD\GLCache" -Mode clear)
15
+ (New-Target 9 'Intel shader cache' "$($P.L)\Intel\ShaderCache" -Mode clear)
16
+ (New-Target 9 'Remote Desktop bitmap cache' "$($P.L)\Microsoft\Terminal Server Client\Cache" -Mode clear)
17
+ (New-Target 9 'OneDrive logs' "$($P.L)\Microsoft\OneDrive\logs" -Mode clear-old -Days 7)
18
+ (New-Target 9 'OneDrive setup logs' "$($P.L)\Microsoft\OneDrive\setup\logs" -Mode clear-old -Days 7)
19
+ (New-Target 9 'Store apps TempState' "$($P.L)\Packages\*\TempState" -Kind glob -Mode clear)
20
+ (New-Target 9 'Store apps AC\Temp' "$($P.L)\Packages\*\AC\Temp" -Kind glob -Mode clear)
21
+ (New-Target 9 'Store apps AC\INetCache' "$($P.L)\Packages\*\AC\INetCache" -Kind glob -Mode clear)
22
+ (New-Target 9 'Themes cached files' "$($P.L)\Microsoft\Windows\Themes\CachedFiles" -Mode clear)
23
+ (New-Target 9 'PowerShell startup profile data' "$($P.L)\Microsoft\Windows\PowerShell\StartupProfileData-*" -Kind fileglob -Mode file)
24
+ (New-Target 9 'CLR usage logs' "$($P.L)\Microsoft\CLR_v4.0\UsageLogs" -Mode clear)
25
+ (New-Target 9 'CLR usage logs (32-bit)' "$($P.L)\Microsoft\CLR_v4.0_32\UsageLogs" -Mode clear)
26
+ (New-Target 9 'Explorer thumbcache leftovers' "$($P.L)\Microsoft\Windows\Explorer\ThumbCacheToDelete" -Mode clear)
27
+ (New-Target 9 'Explorer iconcache leftovers' "$($P.L)\Microsoft\Windows\Explorer\IconCacheToDelete" -Mode clear)
28
+ (New-Target 9 'Explorer startup logs' "$($P.L)\Microsoft\Windows\Explorer\ExplorerStartupLog*.etl" -Kind fileglob -Mode file)
29
+ (New-Target 9 'Windows schema cache' "$($P.L)\Microsoft\Windows\SchCache" -Mode clear)
30
+ (New-Target 9 'Delivery Optimization (per user)' "$($P.L)\Microsoft\Windows\DeliveryOptimization\Cache" -Mode clear)
31
+ (New-Target 9 'Certificate URL cache' "$($P.LL)\Microsoft\CryptnetUrlCache" -Mode clear)
32
+ (New-Target 9 'Diagnostics results' "$($P.L)\Diagnostics" -Mode clear-old -Days 30)
33
+ (New-Target 9 'DNS resolver cache' 'ipconfig /flushdns' -Kind cmd)
34
+ (New-Target 9 'Microsoft Store download cache' 'wsreset.exe' -Kind cmd -Note 'printed as a next step, never run for you: wsreset has no silent mode and always opens the Store')
35
+ )
36
+ }
37
+
38
+ function Invoke-Section09 {
39
+ Write-SectionIntro @(
40
+ 'Caches Windows and its drivers rebuild silently: shader caches, error-report queues, crash dumps, Store-app',
41
+ 'temp folders, Remote Desktop bitmaps. Files an app is holding open are skipped. The Explorer thumbnail and',
42
+ 'icon databases themselves belong to Disk Cleanup (section 13, admin), which rebuilds them cleanly.'
43
+ )
44
+ $targets = Get-Targets09
45
+ $null = Show-TargetSizes $targets
46
+ if (-not (Confirm-Section 'Clear Windows user caches now?')) { Write-Info 'skipped'; return }
47
+ $null = Invoke-TargetList $targets
48
+ $r = Invoke-External -FilePath 'ipconfig.exe' -ArgumentList @('/flushdns') -Destructive -Quiet -Label 'ipconfig /flushdns'
49
+ if ($r.Ran -and $r.ExitCode -eq 0) { Write-Ok 'DNS resolver cache flushed' }
50
+ # wsreset is the only lever for the Store download cache, and it has no silent switch: every build opens
51
+ # the Store window when it finishes. A cleanup run must not pop a window, so it is offered, never executed.
52
+ if (Test-PathPresent (Join-Path $Script:P.SR 'System32\wsreset.exe')) {
53
+ $Script:WS.Hints += 'Microsoft Store cache: run wsreset.exe yourself when you want it cleared (it opens the Store when it finishes)'
54
+ }
55
+ }
56
+
57
+ # ---------------------------------------------------------------------------------------------
58
+ # Section 10 - user temp
59
+ # ---------------------------------------------------------------------------------------------
60
+
61
+ function Get-TempRoots {
62
+ $P = $Script:P
63
+ $roots = @()
64
+ foreach ($r in @($P.TEMP, $P.TMP, (Join-Path $P.L 'Temp'), (Join-Path $P.LL 'Temp'))) {
65
+ if ($r -and (Test-DirPresent $r)) { $f = Get-FullPath $r; if ($roots -notcontains $f) { $roots += $f } }
66
+ }
67
+ return $roots
68
+ }
69
+
70
+ function Get-Targets10 {
71
+ $t = @()
72
+ foreach ($r in (Get-TempRoots)) { $t += (New-Target 10 'User temp' $r -Mode prune -Days $Script:WS.TempDays -Note "files idle $($Script:WS.TempDays)+ days; open files are skipped") }
73
+ return $t
74
+ }
75
+
76
+ function Invoke-Section10 {
77
+ $ws = $Script:WS
78
+ Write-SectionIntro @(
79
+ "Temporary files idle for $($ws.TempDays)+ days. Files a running program still has open are skipped, so an",
80
+ 'installer or build that is in progress right now is safe. Lower the window with --temp-days 1 for a harder sweep.'
81
+ )
82
+ $targets = @(Get-Targets10)
83
+ if ($targets.Count -eq 0) { Write-Info 'no temp folders found'; return }
84
+ $null = Show-TargetSizes $targets
85
+ if (-not (Confirm-Section "Remove temp files idle $($ws.TempDays)+ days?")) { Write-Info 'skipped'; return }
86
+ $null = Invoke-TargetList $targets
87
+ }
88
+
89
+ # ---------------------------------------------------------------------------------------------
90
+ # Section 11 - Recycle Bin
91
+ # ---------------------------------------------------------------------------------------------
92
+
93
+ function Get-Targets11 { return @((New-Target 11 'Recycle Bin (all drives)' 'Clear-RecycleBin' -Kind cmd -Note 'PERMANENT - everything in the bin is gone')) }
94
+
95
+ function Get-RecycleBinStats {
96
+ $items = 0; $bytes = [long]0
97
+ try {
98
+ $shell = New-Object -ComObject Shell.Application
99
+ $bin = $shell.NameSpace(0xA)
100
+ foreach ($i in $bin.Items()) { $items++; try { $bytes += [long]$i.Size } catch { $null = $_ } }
101
+ } catch { $null = $_ }
102
+ return [pscustomobject]@{ Items = $items; Bytes = $bytes }
103
+ }
104
+
105
+ function Invoke-Section11 {
106
+ $ws = $Script:WS
107
+ Write-SectionIntro @('Emptying the Recycle Bin is permanent: nothing in it can be restored afterwards.')
108
+ $s = Get-RecycleBinStats
109
+ Write-Kv 'Recycle Bin:' ("{0} item(s), {1}" -f $s.Items, (Format-Bytes $s.Bytes))
110
+ if ($s.Items -eq 0) { Write-Info 'already empty'; return }
111
+ if ($ws.DryRun) { Write-DryRun ("would empty the Recycle Bin (" + (Format-Bytes $s.Bytes) + ')'); Add-Freed $s.Bytes; return }
112
+ if (-not (Confirm-Ui -Prompt "Permanently delete all $($s.Items) item(s) in the Recycle Bin?" -Default 'n')) { Write-Info 'skipped'; return }
113
+ try {
114
+ Clear-RecycleBin -Force -ErrorAction Stop
115
+ Add-Freed $s.Bytes
116
+ Write-Ok ("Recycle Bin emptied (" + (Format-Bytes $s.Bytes) + ')')
117
+ } catch { Write-Err "could not empty the Recycle Bin: $($_.Exception.Message)" }
118
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "windowsweep",
3
- "version": "1.1.0",
4
- "description": "Safe-by-default Windows cleanup CLI - developer-aware, dry-run first, zero install via npx.",
3
+ "version": "1.3.0",
4
+ "description": "Developer-aware Windows cleanup CLI: dry-run first, personal folders refused, zero install via npx.",
5
5
  "bin": {
6
6
  "windowsweep": "bin/windowsweep.js"
7
7
  },
@@ -53,7 +53,7 @@
53
53
  "url": "https://aoneahsan.com"
54
54
  },
55
55
  "license": "MIT",
56
- "homepage": "https://github.com/aoneahsan/windowsweep",
56
+ "homepage": "https://windowsweep.aoneahsan.com",
57
57
  "repository": {
58
58
  "type": "git",
59
59
  "url": "git+https://github.com/aoneahsan/windowsweep.git"