Max Vilimpoc [Mon, 31 Aug 2026 09:20:55 +0000 (11:20 +0200)]
dotfiles: install AGI from setup-linux.sh, on Ubuntu and on CachyOS
The script died on anything without apt-get, which is most of the machines it
now has to run on, so the package layer is a two-line wrapper over apt-get and
pacman and the rsync lists gained their Arch spellings -- base-devel, pkgconf,
and the libraries without the -dev half Arch does not split out.
AGI ships a .deb and a .zip per release; Debian and Ubuntu get the .deb, Arch
and CachyOS the .zip unpacked to /opt/agi, since there is no AUR package for it
(the AUR RPC knows no agi, agi-bin or android-graphics-inspector). The .zip
route replays the .desktop and MIME files the .deb installs, so both routes
leave the same system behind, and only ever replaces a /opt/agi that carries a
build.properties.
The .deb cannot be installed as it stands. It declares "Depends:
openjdk-22-jre, libgtk-3-0, libwebkit2gtk-4.1-0" and Ubuntu has never packaged
openjdk-22 -- jammy through resolute ship 11, 17, 21 and 25 -- so apt has
nothing to resolve that against. Nothing in the package needs 22 either: it
bundles no JRE, the Go launcher settles for >= 11, and the highest class file
version in gapic.jar is 63, i.e. Java 19. openjdk-21-jre satisfies both and
exists on every release from 22.04 on, so the install picks a JRE that is
actually in the archive and rewrites that one control field to name it.
Only the control member is rebuilt, with ar; dpkg-deb -R/-b would unpack and
recompress 230MB of payload for a one-line edit. Verified against the real
84MB package: member order preserved, Depends retargeted, and dpkg-deb still
parses the result. Should any of that fail, the zip installer is the fallback,
so the .deb path can only cost time.
libgtk-3-0 became libgtk-3-0t64 in 24.04 and SWT wants webkit 4.1 rather than
the 4.0 only jammy has, so both are chosen by asking the archive rather than by
name. adb is installed too: it is not a hard dependency, but gapis carries the
string "adb could not be found from ANDROID_HOME or PATH", which is all AGI can
do without one.
--agi-only and --no-agi split the two halves; --minimal implies --no-agi.
AGI_VERSION pins a release, otherwise the version comes from the releases API
with the last-checked 3.3.3 as the offline fallback, and a re-run whose
/opt/agi/build.properties already matches skips the 85MB download. No pacman
-Sy anywhere -- refreshing the database without upgrading is how an Arch box
ends up half-broken -- so a stale database is reported rather than worked
around.
Exercised on CachyOS: every --dry-run path, the version lookup, and AGI 3.3.3
itself starting against the installed JRE with gtk3 and webkit2gtk-4.1.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PqwcPKuLX7xML2DZqHnNJY
Max Vilimpoc [Fri, 28 Aug 2026 00:05:27 +0000 (02:05 +0200)]
dotfiles: install VirtualBox with the other winget packages
The test VMs this box drives are VirtualBox ones -- it is why sshd's firewall
rule is widened to every profile, a host-only or bridged adapter being routinely
classified Public -- so the hypervisor belongs in the same list as everything
else the box is provisioned with, rather than being the one install left to do
by hand.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D4ozcQcqMSJBi2Ez4Pfxyc
Max Vilimpoc [Fri, 28 Aug 2026 00:04:08 +0000 (02:04 +0200)]
dotfiles: give git the ssh.exe that pushes at line rate
core.sshCommand pointed at the in-box System32 client, which reads its stdin
3KB at a time -- the same limit that held an rsync push to ~17MB/s, and it
applies to anything git pushes through it too. The elevated half now unpacks a
client without that limit beside rsync.exe, so prefer it and keep the in-box one
as the fallback. Same client from the same source: same ~/.ssh, same ssh-agent
named pipe, same known_hosts.
Candidates are tried by RUNNING them rather than by Test-Path. The fast build
carries no libcrypto of its own -- it links the one the OpenSSH Client
capability puts in System32 -- so on an image without that capability it is a
file that exists and a binary that will not start, and the next `git push` is a
bad place to discover it. Two traps in doing that from this script: with
$ErrorActionPreference = 'Stop' a native command's stderr becomes a terminating
error, and `ssh -V` writes its version to stderr, so the WORKING client is the
one that looks broken; and an exe that cannot start never sets $LASTEXITCODE,
leaving the stale 0 from the last native command that did run to read as
success. Hence the EAP dance and the explicit $global:LASTEXITCODE = $null.
setup-windows.bat runs the elevated half first for this: the fast ssh.exe has to
be on disk before the git config step can prefer it. The non-elevated half
still runs when the elevated one failed -- nothing in it depends on that half,
and the fallback is the client Windows already has -- and the elevated exit code
is still what the batch file exits with.
Exercised against real binaries under Windows PowerShell 5.1, with
GIT_CONFIG_GLOBAL pointed at a scratch file: fast client present picks
10.0p2, install directory empty falls back to the in-box 9.5p1, a candidate
that exits non-zero and one that cannot start at all both warn and fall back.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D4ozcQcqMSJBi2Ez4Pfxyc
Max Vilimpoc [Thu, 27 Aug 2026 23:56:49 +0000 (01:56 +0200)]
dotfiles: install the rsync release's ssh.exe beside rsync.exe
The rsync-windows release is now one zip per architecture -- rsync.exe, the
ssh.exe it runs, and the licence texts, under exactly those names -- rather
than a bare rsync.exe, so the pinned .../download/v3.5.0-g521ad8ad/rsync.exe
this script fetched no longer exists.
Fetch rsync-windows-x64.zip or rsync-windows-x86.zip by OS bitness, verify it
against the .sha256 published beside it, unpack to a scratch directory and move
out the four files we asked for -- so a future release adding a fifth cannot
quietly drop it onto the machine PATH. The two exes go in together on purpose:
rsync.exe prefers an ssh.exe in its own directory, and the release builds one
because the client Windows ships reads its stdin 3KB at a time, which holds a
transfer *from* the box at ~17MB/s however fast the link is. Nothing else
about it differs -- same ~/.ssh, same ssh-agent, same known_hosts -- and a bare
`ssh` still resolves to the in-box client, which sits ahead of C:\Tools\rsync
on the PATH.
That ssh.exe links against the libcrypto.dll the OpenSSH Client capability puts
in System32, and ships no copy of its own, so that capability is now installed
here rather than assumed: it was already the thing ssh-agent, the git
core.sshCommand in the non-elevated half, and rsync's own transport all depend
on. Where it is absent, or its LibreSSL is older than the 3.8.2 the release is
built against, the script says so and installs rsync alone.
The URL follows the releases/latest/download/ redirect rather than the API,
whose unauthenticated 60/hour per-IP limit a provisioning run behind a shared
NAT can genuinely exhaust; pin the tag in $RsyncUrl to hold a box on a build.
Verified end to end against the live release under Windows PowerShell 5.1 --
which is what the .bat launches, and which refuses to Expand-Archive anything
not named .zip, hence "download-$RsyncAsset" for the scratch file.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D4ozcQcqMSJBi2Ez4Pfxyc
Max Vilimpoc [Wed, 26 Aug 2026 10:33:18 +0000 (12:33 +0200)]
dotfiles: point git at the Windows SSH client, split out the non-elevated half
git config core.sshCommand -> %WINDIR%/System32/OpenSSH/ssh.exe, so git shares
the Windows ssh-agent that the elevated half enables. Git for Windows otherwise
prefers its bundled MSYS2 ssh.exe, which cannot reach that agent (Win32-OpenSSH
publishes it on a named pipe the MSYS2 build does not speak), leaving keys added
with `ssh-add` invisible to git.
The .bat already carried a bare version of this line, but it was inert on a fresh
box: `winget install Git.Git` runs a few lines above it, so that cmd session's
PATH predates the install and `git config` only printed "not recognized" before
carrying on. Resolve git.exe explicitly (PATH, then the standard install roots)
before configuring anything.
Move the PowerShell-driven per-user work - BinSkim, the WinMerge PATH edit, and
the git config - out of the .bat into setup-windows-no-uac.ps1, mirroring
setup-windows-with-uac.ps1. It is standalone-runnable, takes -Skip to re-run a
subset, runs each step independently (a failure warns, the rest still run, exit 1
if any did), and warns when run elevated, since every step writes per-user state
that would otherwise land in the administrator's profile. The .bat is left as
winget installs plus two script calls.
Two behaviour changes while moving that code:
- The git identity is empty strings rather than PLACEHOLDER_NAME, and is skipped
when unset instead of being written. The placeholder appeared both in the
assignment and in the check that guarded it, so a find/replace over the name -
exactly what the README told you to do - silently disabled the guard.
- The BinSkim version marker is written on the up-to-date path too. Previously it
was written only after a download, so an install predating the marker re-derived
its version from BinSkim.exe's ProductVersion on every run.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019avXmzifMt4wJnJzQDUJCU
Max Vilimpoc [Tue, 25 Aug 2026 10:45:40 +0000 (12:45 +0200)]
dotfiles: sync the Windows provisioning scripts
Three changes made in the other copy of these scripts, ported back so
the two do not drift. The scripts are now byte-identical apart from a few
naming lines and the one divergence that is deliberate: this copy keeps
the PLACEHOLDER git identity, which the README tells you to edit before
running.
OpenSSH Server. Installed from the Windows on-demand capability (10/1809
and later), set Automatic, started, and reachable on all firewall
profiles. That last part is the one worth having: the capability ships
its own inbound rule, but it is Private-only on some images, and a VM's
host-only or bridged adapter gets classified Public more often than not
-- which presents as a service that is plainly running and plainly
unreachable.
That rule is adopted rather than duplicated. OpenSSH-Server-In-TCP is the
name the capability itself uses, so a second rule beside it under another
name would leave the narrow one in place and merely work around it, while
one under the same name would collide. Widen it to all profiles if it
exists, create it if it does not. One rule either way, under the name the
platform expects.
rsync. Windows ships the SSH transport and nothing to run over it, so
`rsync host:path` has no remote end. The nuket/rsync-windows build is
downloaded to C:\Tools\rsync and added to the machine PATH. Not "Program
Files", because the fallback when PATH lookup fails is --rsync-path and a
path with spaces is painful to quote through two shells. Machine rather
than user PATH, because the remote end runs as `rsync --server ...` in a
non-interactive session with no login shell: Win32-OpenSSH composes that
environment from the registry, so a machine entry resolves there and does
so for every account on the box. sshd is restarted after the write, since
the running service holds the environment it started with.
BinSkim now checks before it fetches. The .nupkg is a self-contained .NET
build -- 141 MB at 4.4.9.11 -- and the old code downloaded it every run
before working out it had nothing to do. The flat-container index is a
few KB of JSON; take the newest non-prerelease and compare against
nupkg-version.txt beside the installed tool. The download URL now
interpolates the version we checked, rather than the v2 /package/<id>
endpoint that redirects to whatever is newest right now. The PATH append
moved out of the download branch so a lost PATH entry no longer costs
141 MB to repair.
Both new sections warn rather than throw: a box that cannot run sshd
should still finish provisioning the toolchain it came for.
README picks up the remote-access notes, including the authorized_keys
ACL requirement and the separate file that accounts in the Administrators
group need.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Max Vilimpoc [Wed, 5 Aug 2026 09:48:21 +0000 (11:48 +0200)]
dotfiles: Windows dev-box provisioning scripts
Extracted from a native Windows project so the box setup can be reused
and versioned on its own.
setup-windows.bat runs the non-elevated half (winget installs, user PATH
edits for WinMerge and BinSkim, global git config) and then launches
setup-windows-with-uac.ps1 elevated, printing its transcript when the
elevated window closes.
setup-windows-with-uac.ps1 enables ssh-agent and installs Visual Studio
2022 Community in three labelled passes (base C++ workload, Clang/LLVM,
v141 + Windows XP toolset), the WDK 10.0.26100, and the Windows
Performance Toolkit.
The global git identity is PLACEHOLDER_NAME / PLACEHOLDER_EMAIL and must
be edited before the script is run. The runtime transcript
(setup-windows-uac.log) is gitignored: it embeds local machine paths.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>