Windows installers: same existing-account gate as install.sh - #4997
Conversation
PR #4996 taught `install.sh` to detect a machine that is already linked to a ClawMetry account, report that setup, and ask before replaying the onboarding wizard. The Windows installers are the same one-liner promise on another OS, so they get the same contract: You're already connected to ClawMetry Account: founder@example.com (Pro plan) Cloud sync: Local-only (data stays on this machine) Version: 0.12.737 Node: ci-box Dashboard: http://localhost:8900 Re-run setup (account, cloud vs local-only, license)? [y/N]: Two things had to be fixed first for that to work at all on Windows: 1. Neither Windows installer ever ran `clawmetry onboard`. A Windows user was installed but never set up (no account, no daemon, no dashboard) unless they found `clawmetry connect` in the docs. Both scripts now onboard when no account is linked, exactly like macOS/Linux, and gate it behind the question when one is. 2. `install.ps1` wiped and rebuilt the venv on every run. Windows locks the files of a running process, so on the very machine this feature targets (an install whose daemon is live) `Remove-Item -Recurse` fails and the install aborts. It now upgrades in place, and only rebuilds when there is no usable venv. The pre-flight stops ClawMetry's own processes (the sync daemon, and anything running out of the install dir) before pip replaces their files and restarts the daemon on the new code afterwards; a dashboard the operator was running is reported, not silently resurrected (same as macOS/Linux). Shared contract across all three installers: - connected = an API key on this machine; a placeholder (…@clawmetry.auto / …@clawmetry.linked) account does NOT count, so that node still gets the wizard - probe prefers `clawmetry status --json`, falls back to config.json + cloud_plan.json + the nocloud marker, and degrades to "not connected" on any failure rather than breaking the install - default is keep-my-setup: empty answer, "n", or a non-interactive run changes nothing; CLAWMETRY_REONBOARD=1/0 forces it either way; CLAWMETRY_SKIP_ONBOARD=1 skips onboarding entirely; CLAWMETRY_LOCAL_ONLY=1 writes the nocloud marker - install.ps1 parses `status --json` with ConvertFrom-Json; install.cmd hands the work to one python probe that prints the summary and returns the answer in its exit code, so batch never parses JSON Verification: - tests/test_windows_installer_existing_account_gate.py — 25 tests: the PowerShell helpers driven under pwsh (fresh / local-only-no-account / placeholder / corrupt config / config-file fallback / snapshot preferred / dead dashboard / env overrides / non-interactive), the install.cmd python probe executed directly on any OS, and static parity guards across all three installers - .github/workflows/install-test.yml — real windows-latest runners now assert the gate end to end: a synthetic connected profile must be reported and left alone, and a fresh profile must still get the wizard Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
| # including 401/302 -- counts as "up". | ||
| function Get-ClawmetryDashboardUrl { | ||
| param([string]$DataDir) | ||
| $ports = @() |
There was a problem hiding this comment.
The blueprint specifies that both installer entry points shall apply the existing-setup gate at two points: the "already up to date" early exit and the post-install path. The PowerShell installer only applies the gate after a successful install/upgrade, not on an early exit for already-current installations.
| echo. | ||
|
|
||
| REM ── Existing setup: account probe + "re-onboard?" gate ────────────────── | ||
| REM Same contract as install.sh / install.ps1: this script is also the upgrade |
There was a problem hiding this comment.
The blueprint specifies that both installer entry points shall apply the existing-setup gate at two points: the "already up to date" early exit and the post-install path. The CMD installer only applies the gate after a successful install, not on an early exit for already-current installations.
CLAWMETRY_REONBOARD=0 returned from the gate without a word, so an operator who forced the skip saw the summary and then nothing — indistinguishable from the installer ignoring the variable. Caught by the new windows-latest CI gate step, which asserts the message on exactly that path. Both install.sh and install.ps1 now print the same "Keeping your current setup" + "Change it anytime: clawmetry onboard" lines they print for an interactive "no"; install.cmd already routed the forced skip through its :cm_keep label. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
| if ($LASTEXITCODE -ne 0) { | ||
| Write-Host "❌ Failed to create virtual environment." -ForegroundColor Red | ||
| exit 1 | ||
| # Upgrade the existing venv in place; only rebuild when there isn't a usable |
There was a problem hiding this comment.
The blueprint specifies that both installer entry points shall apply the existing-setup gate at the "already up to date" early exit and the post-install path. The PowerShell installer only applies the gate after a successful install/upgrade (around line 311), not on an early exit for already-current installations.
There was a problem hiding this comment.
The blueprint specifies that both installer entry points shall apply the existing-setup gate at the "already up to date" early exit and the post-install path. The CMD installer only applies the gate after a successful install (around line 73), not on an early exit for already-current installations.
|
blocked on author decision — skipping (auto-mergeability sweep) All CI check runs pass. The only blocker is the Generated by Claude Code |
…ly exit Both install.ps1 and install.cmd applied the existing-account gate only on the post-install path. The blueprint also requires it at the early-exit point where the installer detects the installed version equals the latest PyPI release and skips the pip upgrade. - install.ps1: version-check block before pip install; reuses the inline Python account probe (helper fns defined later can't be called here). - install.cmd: same logic using flat goto labels (batch can't use labels inside compound if blocks); uses importlib.metadata for reliable version extraction without needing to parse "clawmetry X.Y.Z" output. Fixes drift-bot findings on #4997. Co-Authored-By: Claude Code <noreply@anthropic.com>
|
Pushed a fix for both drift-bot findings (commit b439eb7). Both Generated by Claude Code |
|
| # Mirror of install.sh's early-exit section: if the installed version already | ||
| # equals the latest PyPI release, nothing needs to be installed. We still apply | ||
| # the existing-account gate so a re-run on an already-connected machine reports | ||
| # the current setup and offers the wizard -- same contract as the post-install |
There was a problem hiding this comment.
The blueprint specifies that PowerShell installer should "always run the install/upgrade step" and apply the existing-setup gate "once, after that step." The implementation has an early exit that skips the install step when the version is already current, applying the gate before the step instead of after.
| :cm_sweep_done | ||
|
|
||
| REM ── Early exit: already up to date ────────────────────────────────────── | ||
| REM Mirror of install.sh: if the installed version equals the latest PyPI |
There was a problem hiding this comment.
The blueprint specifies that CMD installer should "always run the install/upgrade step" and apply the existing-setup gate "once, after that step." The implementation has an early exit that skips the install step when the version is already current, applying the gate before the step instead of after.
Reverts b439eb7, which was pushed onto this branch to close a drift-bot finding. Three problems with it: 1. It runs AFTER the pre-flight that stops a live ClawMetry daemon, and returns before the restart block. On the exact machine this feature targets (an already-connected node whose daemon is up) the installer would stop the daemon and exit, leaving the node silently dead. 2. It re-implements the probe and the prompt inline instead of using the helpers a few lines below, so the same contract now had two copies that can drift — and the inline copy ignores the `status --json` snapshot, so it loses the live account email/plan. 3. It prints "already up to date" and the keep/prompt lines WITHOUT the setup summary, which is the whole point of the gate. The windows-latest CI step caught exactly that. The finding it answered was written against blueprint v4. The Installer Scripts blueprint (v5) now scopes that contract correctly: install.sh has two entry points (its early exit skips a full venv rebuild, so it is worth having), while the Windows installers have a single path — the install step is an idempotent `pip install --upgrade` that no-ops when current — and apply the gate once, after it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Note for the drift-fix automation: I reverted b439eb7 in b18e60e. That early-exit block sat after the pre-flight that stops a running ClawMetry daemon and returned before the restart block, so on an already-connected machine with a live daemon the installer would have stopped the daemon and exited, leaving the node dead. It also re-implemented the probe/prompt inline (a second copy of the same contract, and one that ignores the The finding was written against Installer Scripts blueprint v4. Blueprint v5 now scopes that contract per component: |
✅ Drift Bot (ClawMetry): no drift detectedDrift Bot analyzed the changed files against this project's blueprints and requirements and found no drift. |
Follow-up to #4996, which taught
install.shto detect an already-linked account and ask before replaying the onboarding wizard. Same contract now on Windows (install.ps1+install.cmd):Two Windows-only problems this had to fix first
clawmetry onboard. A Windows user ended up installed but not set up (no account, no daemon, no dashboard) unless they foundclawmetry connectin the docs. Both scripts now onboard when no account is linked, exactly like macOS/Linux, and gate it behind the question when one is.install.ps1wiped and rebuilt the venv on every run. Windows locks the files of a running process, so on the exact machine this feature targets (an install whose daemon is live)Remove-Item -Recursefails and the install aborts. It now upgrades in place and only rebuilds when there is no usable venv. The pre-flight stops ClawMetry's own processes (the sync daemon, plus anything running out of the install dir) before pip replaces their files, and restarts the daemon on the new code afterwards. A dashboard the operator was running is reported, not silently resurrected (same as macOS/Linux).Shared contract across all three installers
…@clawmetry.auto/…@clawmetry.linked) account does not count, so that node still gets the wizard.clawmetry status --json, falls back toconfig.json+cloud_plan.json+ thenocloudmarker, and degrades to "not connected" on any failure rather than breaking the install.n, or a non-interactive run changes nothing.CLAWMETRY_REONBOARD=1/0forces it either way,CLAWMETRY_SKIP_ONBOARD=1skips onboarding entirely,CLAWMETRY_LOCAL_ONLY=1writes the nocloud marker.install.ps1parsesstatus --jsonwithConvertFrom-Json;install.cmdhands the work to one python probe that prints the summary and returns the answer in its exit code, so batch never parses JSON.Verification
tests/test_windows_installer_existing_account_gate.py— 25 tests: the PowerShell helpers driven underpwsh(fresh / local-only-without-account / placeholder / corrupt config / config-file fallback / snapshot preferred / dead dashboard URL / env overrides / non-interactive), theinstall.cmdpython probe executed directly on any OS, and static parity guards across all three installers..github/workflows/install-test.yml— realwindows-latestrunners now assert the gate end to end: a synthetic connected profile (viaUSERPROFILE) must be reported and left alone, and a fresh profile must still get the wizard. The plain install steps run withCLAWMETRY_SKIP_ONBOARD=1so they keep testing the installer, not onboarding.pwsh 7.6.5parsesinstall.ps1clean and all three decision paths (y/n/ bare Enter /CLAWMETRY_REONBOARD/ no account) behave identically to the bash installer.🤖 Generated with Claude Code