Skip to content

Windows installers: same existing-account gate as install.sh - #4997

Merged
vivekchand merged 4 commits into
mainfrom
install-windows-existing-account
Aug 18, 2026
Merged

Windows installers: same existing-account gate as install.sh#4997
vivekchand merged 4 commits into
mainfrom
install-windows-existing-account

Conversation

@vivekchand

Copy link
Copy Markdown
Owner

Follow-up to #4996, which taught install.sh to detect an already-linked account and ask before replaying the onboarding wizard. Same contract now on Windows (install.ps1 + install.cmd):

  ✓ 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 Windows-only problems this had to fix first

  1. Neither Windows installer ever ran clawmetry onboard. A Windows user ended up installed but not 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 exact 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, 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

  • Connected = an API key on this machine. A placeholder (…@clawmetry.auto / …@clawmetry.linked) account does not count, so that node still gets the wizard.
  • The 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-without-account / placeholder / corrupt config / config-file fallback / snapshot preferred / dead dashboard URL / 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 (via USERPROFILE) must be reported and left alone, and a fresh profile must still get the wizard. The plain install steps run with CLAWMETRY_SKIP_ONBOARD=1 so they keep testing the installer, not onboarding.
  • Locally: pwsh 7.6.5 parses install.ps1 clean and all three decision paths (y / n / bare Enter / CLAWMETRY_REONBOARD / no account) behave identically to the bash installer.

🤖 Generated with Claude Code

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>
@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 2 potential drift finding(s)

1. Blueprint: Installer Scripts

File: install.ps1:249

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.

2. Blueprint: Installer Scripts

File: install.cmd:73

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.

Comment thread install.ps1
# including 401/302 -- counts as "up".
function Get-ClawmetryDashboardUrl {
param([string]$DataDir)
$ports = @()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Installer Scripts

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.

Comment thread install.cmd
echo.

REM ── Existing setup: account probe + "re-onboard?" gate ──────────────────
REM Same contract as install.sh / install.ps1: this script is also the upgrade

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Installer Scripts

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>
@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 2 potential drift finding(s)

1. Blueprint: Installer Scripts

File: install.ps1:130

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.

2. Blueprint: Installer Scripts

File: install.cmd:25

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.

Comment thread install.ps1
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Installer Scripts

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.

Comment thread install.cmd

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Installer Scripts

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.

Copy link
Copy Markdown
Owner Author

blocked on author decision — skipping (auto-mergeability sweep)

All CI check runs pass. The only blocker is the drift-bot commit status reporting 2 drift finding(s). Resolving those requires the author to update the blueprint/architecture documentation to match the new Windows installer behaviour.


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>

Copy link
Copy Markdown
Owner Author

Pushed a fix for both drift-bot findings (commit b439eb7).

Both install.ps1 and install.cmd were missing the existing-account gate on the "already up to date" early-exit path. Added the version check + gate block before the pip install in each file, mirroring install.sh's early-exit section. CI should re-run and drift-bot should clear.


Generated by Claude Code

@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 2 potential drift finding(s)

1. Blueprint: Installer Scripts

File: install.ps1:161

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.

2. Blueprint: Installer Scripts

File: install.cmd:65

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.

Comment thread install.ps1 Outdated
# 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Installer Scripts

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.

Comment thread install.cmd Outdated
:cm_sweep_done

REM ── Early exit: already up to date ──────────────────────────────────────
REM Mirror of install.sh: if the installed version equals the latest PyPI

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Installer Scripts

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>
@vivekchand

Copy link
Copy Markdown
Owner Author

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 status --json snapshot, losing the live account email and plan) and printed no setup summary — which the new windows-latest CI step caught.

The finding was written against Installer Scripts blueprint v4. Blueprint v5 now scopes that contract per component: install.sh has two entry points (its early exit skips a full venv rebuild, so it earns its keep), while the Windows installers have a single path — their install step is an idempotent pip install --upgrade that no-ops when already current — and apply the gate once, after it.

@8090-software-factory

Copy link
Copy Markdown

✅ Drift Bot (ClawMetry): no drift detected

Drift Bot analyzed the changed files against this project's blueprints and requirements and found no drift.

@vivekchand
vivekchand merged commit e627b1d into main Aug 18, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants