windowsweep 1.0.1 → 1.2.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.
- package/AI-INTEGRATION-GUIDE.md +203 -0
- package/CHANGELOG.md +124 -0
- package/LICENSE +21 -21
- package/README.md +88 -49
- package/VERSION +1 -1
- package/lib/actions.ps1 +212 -209
- package/lib/config.ps1 +108 -99
- package/lib/constants.ps1 +103 -89
- package/lib/fs.ps1 +189 -180
- package/lib/log.ps1 +140 -140
- package/lib/safety.ps1 +541 -493
- package/lib/scan.ps1 +109 -94
- package/lib/ui.ps1 +275 -235
- package/modules/android_avd.ps1 +36 -36
- package/modules/app_caches.ps1 +58 -58
- package/modules/browsers.ps1 +33 -33
- package/modules/build_tools.ps1 +35 -35
- package/modules/crash_trap.ps1 +89 -89
- package/modules/disk_usage.ps1 +49 -49
- package/modules/docker.ps1 +93 -93
- package/modules/editors.ps1 +150 -150
- package/modules/globals_audit.ps1 +236 -0
- package/modules/health.ps1 +101 -101
- package/modules/installed_programs.ps1 +118 -0
- package/modules/menu.ps1 +63 -61
- package/modules/notify.ps1 +60 -0
- package/modules/orphaned_appdata.ps1 +189 -0
- package/modules/personal.ps1 +126 -124
- package/modules/pkg_managers.ps1 +73 -69
- package/modules/projects.ps1 +160 -143
- package/modules/release_helpers.ps1 +438 -434
- package/modules/reports.ps1 +212 -212
- package/modules/runner.ps1 +242 -190
- package/modules/self_test_extra.ps1 +537 -86
- package/modules/startup_audit.ps1 +126 -0
- package/modules/system_admin.ps1 +220 -220
- package/modules/test_runners.ps1 +24 -24
- package/modules/walkthrough.ps1 +80 -79
- package/modules/windows_user.ps1 +118 -112
- package/package.json +4 -3
- package/windowsweep.ps1 +322 -296
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# AI integration guide
|
|
2
|
+
|
|
3
|
+
This is the contract an automated caller can rely on: what windowsweep promises, what it refuses, what it
|
|
4
|
+
prints, and what it returns. It is written for an agent or a script rather than a person. For what the tool
|
|
5
|
+
*is*, read the [README](https://github.com/aoneahsan/windowsweep#readme); for what each section touches, read
|
|
6
|
+
[Sections 0-25](https://github.com/aoneahsan/windowsweep/blob/main/docs/sections.md).
|
|
7
|
+
|
|
8
|
+
**windowsweep deletes files.** Every command below that is not marked read-only can remove data. There is no
|
|
9
|
+
undo for caches. Treat a real run as an irreversible operation and preview it first.
|
|
10
|
+
|
|
11
|
+
## The safe sequence
|
|
12
|
+
|
|
13
|
+
```powershell
|
|
14
|
+
npx windowsweep --self-test --no-color --no-report # read-only: proves the guards on this machine
|
|
15
|
+
npx windowsweep --scan --no-color --no-report # read-only: every target and its size
|
|
16
|
+
npx windowsweep --dry-run --all --yes --no-color # writes nothing; reports what a real run would remove
|
|
17
|
+
npx windowsweep --all --yes --no-color # the real safe batch
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Add `--json` when a program reads the result. In that mode **stdout carries exactly one line, the JSON
|
|
21
|
+
summary**, and every human-readable line goes to stderr. `--json` also implies `--quiet`.
|
|
22
|
+
|
|
23
|
+
## What `--yes` covers, and what it never covers
|
|
24
|
+
|
|
25
|
+
`--yes` auto-confirms **regenerable caches only**: sections 0-3, 5-10, 21, and 12-13 when the console is
|
|
26
|
+
already elevated.
|
|
27
|
+
|
|
28
|
+
| Never covered by `--yes` | Behaviour |
|
|
29
|
+
|---|---|
|
|
30
|
+
| Sections 17, 18, 19, 23 | The selection prompt appears even with `--yes` and defaults to none. With no console attached nothing is selected, and each asks a final question `--yes` does not answer. Only `--select` / `--select-file` supply a choice (see below) |
|
|
31
|
+
| Sections 11, 15, 16, 20 | Deep. Refused in batch mode unless `--i-understand-deep` is also passed |
|
|
32
|
+
| `--uninstall-data` | Always asks; `--yes` does not answer it |
|
|
33
|
+
| `--purge-all` | From a console it asks for a typed `purge` once per run. In a batch run `--yes` is the confirmation |
|
|
34
|
+
|
|
35
|
+
In batch mode (`--all`, `--only`, `--profile`) sections 17, 18, 19 and 23 are refused outright and reported as
|
|
36
|
+
`refused`, unless a `--select` or `--select-file` choice was supplied. They need a person choosing items -
|
|
37
|
+
in advance is fine, absent is not.
|
|
38
|
+
|
|
39
|
+
## Exit codes
|
|
40
|
+
|
|
41
|
+
| Code | Meaning |
|
|
42
|
+
|---|---|
|
|
43
|
+
| 0 | Success |
|
|
44
|
+
| 1 | A section failed, or the self-test found a failure |
|
|
45
|
+
| 2 | Usage error, or an interactive mode was started without a console |
|
|
46
|
+
| 3 | A section named in `--only` was refused, or an installer was started from `npx` |
|
|
47
|
+
| 130 | Interrupted before the run finished (Ctrl-C) |
|
|
48
|
+
|
|
49
|
+
## Flags that matter to automation
|
|
50
|
+
|
|
51
|
+
| Flag | Effect |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `--json` | One JSON line on stdout; everything else on stderr. Implies `--quiet` |
|
|
54
|
+
| `--no-color`, `--ascii` | Disable colour and Unicode glyphs. Both are automatic when output is redirected |
|
|
55
|
+
| `--no-report` | Skip the JSON report file; the session log is still written |
|
|
56
|
+
| `--cleanup-logs` | Delete this run's log at exit; reports are kept |
|
|
57
|
+
| `--quiet` | Fewer informational lines |
|
|
58
|
+
| `--only L`, `--profile NAME`, `--exclude L` | Choose sections: `--only 1,3,5-7`; profiles `dev`, `minimal`, `cache-only`, `system`, `deep`, `audit` |
|
|
59
|
+
| `--days N`, `--temp-days N` | Idle windows, default 100 and 3 |
|
|
60
|
+
| `--developer`, `--not-developer` | Override the saved developer answer for this run |
|
|
61
|
+
| `--scan-roots "P1;P2"`, `--exclude-path P` | Section 17 roots and exclusions |
|
|
62
|
+
| `--logs-dir P`, `--reports-dir P` | Redirect this run's output |
|
|
63
|
+
| `--select L`, `--select-file P` | Supply an interactive section's selection in advance, by index or by full path. The only way sections 17/18/19/23 run unattended |
|
|
64
|
+
| `--notify` | A Windows notification when the run ends. Never changes the exit code, never writes to stdout |
|
|
65
|
+
| `--list --json` | Print the section catalogue as one JSON line instead of the human table |
|
|
66
|
+
| `--pwsh` | Launcher only: run the engine on PowerShell 7 |
|
|
67
|
+
|
|
68
|
+
A non-interactive run with no saved developer answer defaults to developer mode **on**, the conservative
|
|
69
|
+
choice, and says so.
|
|
70
|
+
|
|
71
|
+
## The `--json` line
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{"tool":"windowsweep","version":"1.1.0","mode":"all","dry_run":false,"elevated":false,"developer":true,
|
|
75
|
+
"freed_bytes":0,"estimated_bytes":0,
|
|
76
|
+
"sections":[{"section":1,"status":"ran","freed_bytes":0}],
|
|
77
|
+
"candidates":[],"targets":[],
|
|
78
|
+
"refusals":[],"excluded":[],"log_file":"...","report_file":"..."}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| Key | Meaning |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `tool`, `version` | Always `windowsweep` and the running version |
|
|
84
|
+
| `mode` | `all`, `only`, `scan`, `walkthrough`, `menu`, ... |
|
|
85
|
+
| `dry_run`, `elevated` | The two booleans that change what a run does |
|
|
86
|
+
| `developer` | `true`, `false`, or `null` in a mode that never resolves the question (`--scan`, `--list`) |
|
|
87
|
+
| `freed_bytes` | Real bytes removed. `0` in a dry-run |
|
|
88
|
+
| `estimated_bytes` | What a dry-run says a real run would remove. `0` in a real run |
|
|
89
|
+
| `sections[]` | One entry per section attempted: `section`, `status`, `freed_bytes` |
|
|
90
|
+
| `candidates[]` | What an interactive section offered: `section`, `index`, `path`, `bytes`, `idle_days`, `project`. Always present, empty when none were collected |
|
|
91
|
+
| `targets[]` | Scan mode only: `section`, `label`, `path`, `bytes`, `newest_write_utc`. Always present, empty otherwise |
|
|
92
|
+
| `refusals[]` | Human-readable reasons a section was refused in batch mode, plus one `excluded: <path>` line per honoured `--exclude-path` |
|
|
93
|
+
| `excluded[]` | Every path an exclusion actually kept, listed once each. Empty means "nothing was excluded", never "not reported" |
|
|
94
|
+
| `log_file`, `report_file` | Absolute paths, or `null` under `--no-report` |
|
|
95
|
+
|
|
96
|
+
`status` is one of `ran`, `dry-run`, `skipped`, `refused`, `failed`.
|
|
97
|
+
|
|
98
|
+
`newest_write_utc` is ISO 8601 UTC (`2026-09-08T13:14:15Z`) - the newest of write, access and creation time
|
|
99
|
+
found anywhere under that target, which is the same rule the idle gate uses. It is **`null`** when the
|
|
100
|
+
target is absent or holds no files, rather than a zero date a caller would sort as if it were real. It is
|
|
101
|
+
emitted only under `--json`, because computing it needs the file walk that `--json` already performs.
|
|
102
|
+
|
|
103
|
+
## Where output lands
|
|
104
|
+
|
|
105
|
+
| Item | Path |
|
|
106
|
+
|---|---|
|
|
107
|
+
| Session logs | `%USERPROFILE%\.windowsweep\logs\` |
|
|
108
|
+
| JSON reports and exports | `%USERPROFILE%\.windowsweep\reports\` |
|
|
109
|
+
| Debug and crash bundles | `%USERPROFILE%\.windowsweep\feedback\` |
|
|
110
|
+
| Settings | `%USERPROFILE%\.windowsweep\config.json` |
|
|
111
|
+
|
|
112
|
+
Override the root with `WINDOWSWEEP_HOME`, or the two folders with `--logs-dir` / `--reports-dir`
|
|
113
|
+
(`WINDOWSWEEP_LOG_DIR` / `WINDOWSWEEP_REPORTS_DIR`). `WINDOWSWEEP_NO_COLOR`, `NO_COLOR` and
|
|
114
|
+
`WINDOWSWEEP_ASCII` are honoured; `WINDOWSWEEP_SHELL=pwsh` selects PowerShell 7 through the Node launcher.
|
|
115
|
+
|
|
116
|
+
The report file is schema-versioned JSON (`schema_version: 1`) with five top-level blocks: `credits`, `meta`
|
|
117
|
+
(times, host, OS, PowerShell version, mode, the three flags, the idle windows, the launcher), `disk`
|
|
118
|
+
(`before` and `after` snapshots per fixed drive), `steps` (one row per section with `status` and
|
|
119
|
+
`freed_bytes`), and `totals`. `--export md|html|both [N|latest|all]` renders any report to Markdown or a
|
|
120
|
+
self-contained HTML page without extra tools.
|
|
121
|
+
|
|
122
|
+
## Elevation
|
|
123
|
+
|
|
124
|
+
Sections 12-16 and 20 need Administrator rights. Without them the runner skips each with the exact command
|
|
125
|
+
to run. `--elevate` relaunches the whole run through a UAC prompt: **a new elevated window opens with its own
|
|
126
|
+
log and report**, and the original process waits and returns the child's exit code. That prompt cannot be
|
|
127
|
+
answered by a script, so `--elevate` does not belong in an unattended context.
|
|
128
|
+
|
|
129
|
+
## Guarantees
|
|
130
|
+
|
|
131
|
+
- - **No network calls of its own**. Self-test check [9] greps every source file for `Invoke-WebRequest`, `Invoke-RestMethod`, `Net.WebClient`, `HttpClient`, `Sockets.TcpClient`, `curl.exe` and `wget`, and fails the run if it finds one. There is no telemetry and no update check. `--report-issue` and `--feedback` hand a URL to the user's browser after they confirm, and neither belongs in an unattended run.
|
|
132
|
+
- - **Every deletion of anything on the user's machine passes one chokepoint** with a declared root, and is refused if it falls outside it. windowsweep's own logs, reports and fixtures are the exception, reachable only through `--cleanup-logs`, `--prune-history` and `--uninstall-data`.
|
|
133
|
+
- - **Protected paths are refused regardless of flags**: every drive root, fifteen declared roots (Windows, System32, SysWOW64, both Program Files folders, ProgramData, `C:\Users` with Default and Public, the profile root, and the AppData Roaming, Local and LocalLow folders), 66 protected subtrees, 50 path patterns and 13 file names. Two paths are declared exceptions - `%LOCALAPPDATA%\Android\Sdk\.temp` and `.downloadIntermediates` - and there are no others. No flag bypasses any of it.
|
|
134
|
+
- **Junctions and symlinks are removed as links, never followed.**
|
|
135
|
+
- **`--dry-run` and `--scan` write nothing** but the log and the report.
|
|
136
|
+
- **Section numbers are a public contract.** 0-25 today; a section may be retired as a no-op, and a number is
|
|
137
|
+
never reused. Read `--list --json` rather than hard-coding the set.
|
|
138
|
+
- **Zero runtime dependencies.** The package is PowerShell plus a Node launcher that uses only built-in
|
|
139
|
+
modules.
|
|
140
|
+
|
|
141
|
+
## Do not
|
|
142
|
+
|
|
143
|
+
- Do not run `npx windowsweep` from a directory that contains a checkout of this repository: npx resolves the
|
|
144
|
+
local package and the command fails. Run it from anywhere else.
|
|
145
|
+
- Do not schedule `npx windowsweep` as a task action. The npx cache is evicted and the task breaks; install
|
|
146
|
+
globally and use `--install-task`, which refuses under npx for this reason.
|
|
147
|
+
- Do not pipe `y` into the tool to force a personal section. Sections 17, 18, 19 and 23 are interactive by
|
|
148
|
+
design and a piped answer selects nothing - pass `--select` or `--select-file` instead, which is the
|
|
149
|
+
supported way and names exactly what goes.
|
|
150
|
+
- Do not treat a green `--dry-run` as proof that a real run frees the same amount: an app that is open at run
|
|
151
|
+
time keeps its caches.
|
|
152
|
+
|
|
153
|
+
## Driving the interactive sections (1.1.0+)
|
|
154
|
+
|
|
155
|
+
Sections 17, 18, 19 and 23 refuse to run unattended, because they delete things a person should choose. Two
|
|
156
|
+
flags supply that choice in advance, and either one lifts the refusal:
|
|
157
|
+
|
|
158
|
+
```powershell
|
|
159
|
+
# 1. list what the section would offer - deletes nothing
|
|
160
|
+
npx windowsweep --only 17 --dry-run --json --no-color
|
|
161
|
+
# -> read .candidates[] from the single stdout line:
|
|
162
|
+
# { "section": 17, "index": 1, "path": "...", "bytes": 0, "idle_days": 400, "project": "..." }
|
|
163
|
+
|
|
164
|
+
# 2. act on exactly the ones you chose
|
|
165
|
+
npx windowsweep --only 17 --select 1,3 # by index, one list per prompt, in prompt order
|
|
166
|
+
npx windowsweep --only 17 --select-file picks.txt # by full path, one per line, UTF-8, # comments allowed
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Rules a caller can rely on:
|
|
170
|
+
|
|
171
|
+
- **`--yes` alone still selects nothing.** It never has. Only `--select` / `--select-file` do.
|
|
172
|
+
- The scripted selection also answers that section's final confirmation, so the run does not stall.
|
|
173
|
+
- `--select` is repeatable and consumed one list per prompt; `--select-file` is offered to every prompt, so
|
|
174
|
+
a line that matches nothing in a given section is reported once and skipped.
|
|
175
|
+
- Neither flag reaches a path the deletion chokepoint would otherwise refuse.
|
|
176
|
+
|
|
177
|
+
## Reading the catalogue and following progress
|
|
178
|
+
|
|
179
|
+
```powershell
|
|
180
|
+
npx windowsweep --list --json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
One stdout line: `sections[]` (`id`, `key`, `title`, `tier`, `admin`, `batch`, `dev`), `safe_batch`,
|
|
184
|
+
`safe_batch_admin`, `profiles`, `walkthrough`, `walkthrough_admin`. Read it instead of hard-coding section
|
|
185
|
+
numbers - they are frozen, but the set grows.
|
|
186
|
+
|
|
187
|
+
In `--json` mode every section brackets itself on **stderr**:
|
|
188
|
+
|
|
189
|
+
```text
|
|
190
|
+
##windowsweep section=7 event=start
|
|
191
|
+
##windowsweep section=7 event=end status=ran freed_bytes=4096
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`status` is one of `ran`, `dry-run`, `skipped`, `refused`, `failed`. Scan mode also fills `targets[]`
|
|
195
|
+
(`section`, `label`, `path`, `bytes`, `newest_write_utc`) in the final JSON line. `candidates` and `targets`
|
|
196
|
+
are always present, empty when nothing was collected.
|
|
197
|
+
|
|
198
|
+
## The read-only audits
|
|
199
|
+
|
|
200
|
+
`--profile audit` runs sections 0, 21, 22, 24 and 25 and deletes nothing in any mode: the health report, disk
|
|
201
|
+
usage, globally installed packages, installed programs not modified for `--days`+ days, and startup items.
|
|
202
|
+
Sections 22, 24 and 25 print removal commands but never execute one, and section 25 never changes a startup
|
|
203
|
+
entry. Section 24 reports "not modified", not "not used" - Windows keeps no reliable last-launched record.
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,130 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
## [1.2.0] - 2026-09-08
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **`targets[].newest_write_utc` in `--scan --json`.** ISO 8601 UTC, the newest of write, access and creation
|
|
17
|
+
time found anywhere under the target - the same rule the idle gate uses - or `null` when the target is
|
|
18
|
+
absent or holds no files. It costs no extra walk: under `--json` the size pass already enumerates every
|
|
19
|
+
file, so the timestamp comes out of that same enumeration. A human `--scan` keeps the faster path.
|
|
20
|
+
- **`protected` in `--list --json`.** `subtrees` (every protected folder, resolved for this machine) and
|
|
21
|
+
`categories` (the same four sentences `--list-targets` prints). Both readers now take the category list
|
|
22
|
+
from one constant, so the machine-readable copy cannot quietly promise less than the console does.
|
|
23
|
+
- **`excluded[]` in the `--json` summary**, naming every path an exclusion actually kept, once each.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **`--exclude-path` is honoured in every section, not only section 17.** It was parsed globally and read by
|
|
28
|
+
exactly one consumer, so someone who excluded a folder was protected in one section and silently not in the
|
|
29
|
+
other twenty-five. It is now enforced at the deletion chokepoint itself - the one place every section
|
|
30
|
+
already passes through - and an excluded path is refused, logged as `excluded: <path>` and reported in
|
|
31
|
+
`excluded[]`. The same reach applies to `excludePaths` in the config file. **No deletion behaviour widens:
|
|
32
|
+
`--exclude-path` only ever refuses more.** A path that is both protected and excluded still reports the
|
|
33
|
+
protected reason, because that is the promise no flag can lift.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- 🔴 **`--exclude-path` only ever refused the path you named, never anything inside it.** The normalised
|
|
38
|
+
prefix was built with a PowerShell literal `'\'`, which is **two** characters, so the prefix ended in a
|
|
39
|
+
doubled backslash and no child path could ever match it. Excluding a folder protected the folder and
|
|
40
|
+
nothing in it - which is the opposite of what anyone excluding a folder means. The self-test check that
|
|
41
|
+
was supposed to cover this asserted only on the excluded path itself, so it passed throughout; it now
|
|
42
|
+
asserts on a child, and the fix was watched failing on the original bug reintroduced.
|
|
43
|
+
- 🔴 **A dry-run counted files a real run would skip.** `Remove-StaleFiles` applied the protection guard
|
|
44
|
+
only in its real-run loop, so the rehearsal's estimate included protected and excluded files that the run
|
|
45
|
+
then refused - for exactly the files a person most wants the two numbers to agree about. One filter now
|
|
46
|
+
decides both, and a check proves a dry-run and a real prune report the same count and the same bytes.
|
|
47
|
+
- **`--help` said `--permanent` covers "Sections 18/19".** It reaches **18, 19 and 23**: `Send-ToRecycleBin`
|
|
48
|
+
is called from `modules/personal.ps1` (18, 19) and from `modules/orphaned_appdata.ps1` (23). Someone who
|
|
49
|
+
passed `--permanent` believing it applied to two sections would have had section 23's orphaned
|
|
50
|
+
application data deleted outright instead of recycled. The reference docs already said 18, 19 and 23;
|
|
51
|
+
only the engine's own help text - the one place a person actually reads it from - was wrong.
|
|
52
|
+
- **Section 22 declared `Dev = $true` with no behavioural branch**, so `--list --json` advertised a developer
|
|
53
|
+
flag that changed nothing. It now reads `false`, and the Dev column in `docs/sections.md` agrees.
|
|
54
|
+
- 🔴 **`--scan` parsed `--developer` and `--not-developer` and then never read them.**
|
|
55
|
+
`Resolve-DeveloperMode` ran only for the walkthrough, the menu, `--all` and `--only`, so in scan mode the
|
|
56
|
+
flag reached `DeveloperFlag` and nothing looked at it: section 0 printed `Developer mode: not decided yet`
|
|
57
|
+
whatever you passed, and `--json` returned `developer: null`. The desktop window sends those flags to
|
|
58
|
+
`--scan` and could not read back the setting it had just sent. A scan now resolves it from the flag or the
|
|
59
|
+
saved answer and stops there - it may not ask the question, may not write `config.json`, and may not invent
|
|
60
|
+
a decision you never made, so with neither a flag nor a saved answer it still reports "not decided yet",
|
|
61
|
+
which is the truth. **No scan result changes:** the scan reports what is on disk, not what a run would
|
|
62
|
+
remove, and `Show-ScanTable` never read the developer answer in the first place.
|
|
63
|
+
- **The hibernation target's one-line note contradicted the section's own explanation two lines below.** It
|
|
64
|
+
said `reduced` keeps Fast Startup "at roughly 40% of RAM", which is the size of the **whole** file; the
|
|
65
|
+
section intro says `reduced` is about half of that. The note now states the figure once, on the thing it
|
|
66
|
+
belongs to: the full file is about 40% of RAM and `reduced` keeps roughly half that.
|
|
67
|
+
|
|
68
|
+
## [1.1.0] - 2026-09-04
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
|
|
72
|
+
- **Section 22 - global packages audit.** Lists what npm, pnpm, yarn, bun and deno installed globally with
|
|
73
|
+
size and idle days, flags the ones no recent project references, and prints the exact uninstall command.
|
|
74
|
+
It never uninstalls anything and declares no deletable target: several of those roots are protected paths.
|
|
75
|
+
- **Section 23 - orphaned application data.** Top-level folders under `%APPDATA%` and `%LOCALAPPDATA%` that
|
|
76
|
+
no installed program, Store package or running process claims and that nothing has touched for `--days`+
|
|
77
|
+
days. Interactive, Recycle Bin, and it **fails closed** - an unreadable uninstall registry produces zero
|
|
78
|
+
candidates rather than treating everything as orphaned. Every vendor folder another section already cleans
|
|
79
|
+
is excluded automatically, derived from the declared target list so the exclusions cannot drift.
|
|
80
|
+
- **Section 24 - installed programs not modified for N+ days.** Report only, largest first, with
|
|
81
|
+
`winget uninstall --id` when one `winget list` call resolves the program and its own `UninstallString`
|
|
82
|
+
otherwise; Store apps listed separately. It never runs an uninstaller.
|
|
83
|
+
- **Section 25 - startup items audit.** Run and RunOnce keys, both Startup folders, logon-triggered scheduled
|
|
84
|
+
tasks and `Win32_StartupCommand` in one table with each item's enabled state. It changes nothing.
|
|
85
|
+
- **`--select L` and `--select-file P`.** Answer an interactive section's selection in advance, by index or
|
|
86
|
+
by full path. Either flag lets sections 17, 18, 19 and 23 run unattended - a person did choose - and the
|
|
87
|
+
selection answers that section's final confirmation. `--yes` alone still selects nothing.
|
|
88
|
+
- **`--notify`.** A Windows notification when a run ends: a real toast on Windows PowerShell 5.1, a tray
|
|
89
|
+
balloon on PowerShell 7. It never changes the exit code and never writes to stdout. `--install-task` adds
|
|
90
|
+
it to the weekly task, so the Sunday run reports itself.
|
|
91
|
+
- **`--json` additions.** `candidates[]` (what an interactive section offered) and `targets[]` (what scan
|
|
92
|
+
mode measured), both always present so a caller can rely on the shape, plus per-section progress lines on
|
|
93
|
+
stderr: `##windowsweep section=NN event=start|end status=<status> freed_bytes=<n>`.
|
|
94
|
+
- **`--list --json`** prints the section catalogue - sections, tiers, batch policy, the safe batch, the
|
|
95
|
+
profiles and the walkthrough order - so a front end reads it instead of hard-coding it.
|
|
96
|
+
- Section 1 gained the Hugging Face model cache (`~\.cache\huggingface\hub`, pruned by the idle gate,
|
|
97
|
+
developer-gated). Section 9 lists `wsreset.exe` as the Microsoft Store cache lever and offers it as a next
|
|
98
|
+
step rather than running it: `wsreset` has no silent mode and always opens the Store.
|
|
99
|
+
- Section 17 recognises `.nx`, `.mypy_cache`, `.ruff_cache`, `.tox`, `.eggs`, `.output` and `.serverless`,
|
|
100
|
+
and treats `.cache` as an artefact only when a Gatsby or Parcel config sits beside it. `.venv`, `venv` and
|
|
101
|
+
`.terraform` are deliberately still excluded.
|
|
102
|
+
- `docs/sections.md` records the candidate targets that are researched but **not** shipped because the
|
|
103
|
+
software is not installed on the build machine, and why `C:\Intel` was inspected and rejected.
|
|
104
|
+
|
|
105
|
+
### Fixed
|
|
106
|
+
|
|
107
|
+
- `Get-OrphanExclusions` returned its exclusion set as an unrolled array, whose `.Contains` is
|
|
108
|
+
case-sensitive, so a folder named `slack` would have slipped past the `Slack` entry. Found by a new check
|
|
109
|
+
before the section shipped.
|
|
110
|
+
- Section 24's idle measurement used the newest of write, access and creation time. Last-access is live on
|
|
111
|
+
many systems, so every install folder read as touched today and the section could never report anything;
|
|
112
|
+
it now reads last-write only, which is what "not modified" means.
|
|
113
|
+
|
|
114
|
+
### Changed
|
|
115
|
+
|
|
116
|
+
- The target table is collected from the section catalogue instead of a literal `0..21` range, so a new
|
|
117
|
+
section is reachable by `--scan`, `--list-targets` and the safety checks the moment it is declared. The
|
|
118
|
+
menu's prompt range is derived the same way.
|
|
119
|
+
- Profile `audit` is now `0, 21, 22, 24, 25`. The three new report sections are read-only and safe, but stay
|
|
120
|
+
out of `--all` so a cleanup run remains a cleanup run.
|
|
121
|
+
- Self-test: 27 more checks (151 total) cover the catalogue, section 23's fail-closed gate and derived
|
|
122
|
+
exclusions, section 22 declaring nothing deletable, the scripted-selection flags, the `--json` and
|
|
123
|
+
catalogue shapes, the progress-line format, the global-package verdict, the startup-state rule and the
|
|
124
|
+
artefact list. Each was proved red against a planted defect before it was kept.
|
|
125
|
+
- Self-test: ten more checks cover the argument parser, section lists, docker size text, the layout-guard leaf
|
|
126
|
+
test, the `--json` shape, superseded versions, the Chromium layout, workspace storage, stale artefacts and
|
|
127
|
+
the report exporters. `Test-KnownCacheLeaf` and `Get-JsonSummary` were split out of `Invoke-TargetList` and
|
|
128
|
+
`Write-JsonSummary` so the logic can be exercised directly; no behaviour changed.
|
|
129
|
+
- `AI-INTEGRATION-GUIDE.md` ships in the npm package and is mirrored on the documentation site: the contract
|
|
130
|
+
an agent or a script relies on - the safe command sequence, what `--yes` never covers, exit codes, the
|
|
131
|
+
`--json` line, output paths and the guarantees.
|
|
132
|
+
- A documentation site at `windowsweep-docs.aoneahsan.com` (Docusaurus on GitHub Pages), mirroring `docs/`.
|
|
133
|
+
|
|
10
134
|
## [1.0.1] - 2026-09-03
|
|
11
135
|
|
|
12
136
|
### Fixed
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Ahsan Mahmood
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ahsan Mahmood
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|