dotfiles: show the plan, and let it be chosen, before anything runs
setup-windows.bat used to start installing the moment it was run. It now
lists every step it and its two halves can take on this machine - grouped,
numbered, with the reason beside anything that cannot run here - and waits.
Enter runs what is ticked; numbers, ranges, step names and group letters
switch steps on and off first. -WhatIf shows the plan and stops, -Only and
-Skip set the starting selection, -Yes takes it unattended, and with no
console to ask on it stops rather than assume yes.
setup-windows-steps.ps1 is the one list of steps and the one place their
availability is decided: -X64Only, with its reason, replaces both the
:x64only subroutine and the no-uac half's $Arm64Dropped table, and -Admin
keeps machine-wide installers off an account that cannot elevate.
setup-windows-plan.ps1 presents it and hands the choice back as a scratch
.cmd of set lines. The batch file gates every install on :want / :winget;
the two halves take -Only / -Skip / -Yes, print their part of the plan, and
ask first when run by hand. The scripts check each other: a step the list
does not know is refused, and a selected step that nothing implements
fails the run rather than quietly not happening. (The no-uac WinMerge step
is now WinMergePath; the old name is still accepted.)
New steps:
- Rustup (winget), then RustToolchain, which installs stable MSVC for
this host - x86_64 or aarch64 - and pins it as both rustup's default
host and default toolchain, rather than trusting rustup's own host
detection, which an x64 rustup on ARM64 gets wrong.
- PlatformTools (adb, fastboot). The manifest calls it x64, but every
binary in the r37.0.1 zip is 32-bit x86 and there is no ARM64 build. It
stays on ARM64, like iperf3: bound by the link, not the CPU.
Claude Code now comes from Anthropic's installer, not winget, through which
recent releases are broken. That script picks its build from
$env:PROCESSOR_ARCHITECTURE alone - wrong in an emulated x64 shell on
ARM64 - so the batch file sets it from the registry for the installer's
process, and runs it through Sysnative, since it refuses a 32-bit
PowerShell. A copy left over from winget is reported, not removed.
Re-running no longer reinstalls anything at the version it already has.
winget install already only upgrades; the gaps were the installs winget
cannot see, or that never check: Claude Code (its installer always
downloads the whole release), the per-user NASM (registered nowhere, so
reinstalled on every run), the WiX tool, the rsync zip (now compared with
its published .sha256 first) and the Visual Studio passes (skipped when
vswhere -requires finds every component). setup-windows-current.ps1
answers "already current?" for the first two, and a check that cannot
decide installs as before.
The elevation launch line is rebuilt. Its "" pairs lost the script path's
closing quote - powershell.exe's parser reads them as a quote, then
nothing - which only went unnoticed because the path was the last
argument. With -Only and -Yes after it, they were swallowed into the -File
path and the elevated PowerShell refused a script that did not exist
(exit -196608) before running a line. The path and step list now travel in
environment variables, with the one quote built inside PowerShell. The
launch also stops reporting a failed elevation as success - `exit
$p.ExitCode` with no process exited 0 - and the no-log message says
"declined" only when it was (1223), otherwise the exit code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>