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.
Files changed (41) hide show
  1. package/AI-INTEGRATION-GUIDE.md +203 -0
  2. package/CHANGELOG.md +124 -0
  3. package/LICENSE +21 -21
  4. package/README.md +88 -49
  5. package/VERSION +1 -1
  6. package/lib/actions.ps1 +212 -209
  7. package/lib/config.ps1 +108 -99
  8. package/lib/constants.ps1 +103 -89
  9. package/lib/fs.ps1 +189 -180
  10. package/lib/log.ps1 +140 -140
  11. package/lib/safety.ps1 +541 -493
  12. package/lib/scan.ps1 +109 -94
  13. package/lib/ui.ps1 +275 -235
  14. package/modules/android_avd.ps1 +36 -36
  15. package/modules/app_caches.ps1 +58 -58
  16. package/modules/browsers.ps1 +33 -33
  17. package/modules/build_tools.ps1 +35 -35
  18. package/modules/crash_trap.ps1 +89 -89
  19. package/modules/disk_usage.ps1 +49 -49
  20. package/modules/docker.ps1 +93 -93
  21. package/modules/editors.ps1 +150 -150
  22. package/modules/globals_audit.ps1 +236 -0
  23. package/modules/health.ps1 +101 -101
  24. package/modules/installed_programs.ps1 +118 -0
  25. package/modules/menu.ps1 +63 -61
  26. package/modules/notify.ps1 +60 -0
  27. package/modules/orphaned_appdata.ps1 +189 -0
  28. package/modules/personal.ps1 +126 -124
  29. package/modules/pkg_managers.ps1 +73 -69
  30. package/modules/projects.ps1 +160 -143
  31. package/modules/release_helpers.ps1 +438 -434
  32. package/modules/reports.ps1 +212 -212
  33. package/modules/runner.ps1 +242 -190
  34. package/modules/self_test_extra.ps1 +537 -86
  35. package/modules/startup_audit.ps1 +126 -0
  36. package/modules/system_admin.ps1 +220 -220
  37. package/modules/test_runners.ps1 +24 -24
  38. package/modules/walkthrough.ps1 +80 -79
  39. package/modules/windows_user.ps1 +118 -112
  40. package/package.json +4 -3
  41. 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.