fix(update): resolve Windows installer update race; drop dead pip/uv detach - #135
Conversation
The old design specs were moved to docs/archive/ (now gitignored). Remove the stale tracked copies under docs/superpowers/specs/ so the working tree is clean.
… detach The native Windows installer's Restart Manager scan raced the launching pythinker.exe teardown, finding _internal still locked and showing a spurious "could not close the program" dialog even though the update succeeded. Pass the launcher PID via /PID and wait for it to exit in InitializeSetup before the scan. Also remove the now-unreachable Windows pip/uv/pipx detached-upgrade helper: every shipped Windows install updates via the native installer, so that path only remained for source checkouts, which now run the upgrade inline like POSIX.
|
Warning Review limit reached
More reviews will be available in 48 minutes and 37 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughRemoves the ChangesWindows Update Race Fix and Inline Upgrade
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/ui_and_conv/test_shell_update.py`:
- Around line 696-727: The test is overfitting to private implementation details
instead of testing observable public behavior, making it brittle to benign
internal refactors. In tests/ui_and_conv/test_shell_update.py lines 696-727,
reduce mocking of private functions like _get_latest_version,
_update_candidate_unavailable_reason, _is_windows, _detect_upgrade_command, and
_run_upgrade_command. Instead, set up the test context via public inputs
(platform and source-checkout conditions) to naturally drive the code path, and
assert only on observable outputs from the public do_update function. Similarly,
in tests/ui_and_conv/test_native_update_parity.py lines 132-168, keep any
helper-level checks narrow and move the main update flow assertions to test
through the public do_update entrypoint rather than patching internal routing
helpers.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 21ec94c2-2969-44c5-8870-94b54eb75c88
⛔ Files ignored due to path filters (23)
docs/superpowers/specs/2026-05-05-openai-codex-auth-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-05-opencode-go-auth-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-06-anthropic-direct-auth-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-06-deepseek-auth-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-06-minimax-auth-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-06-openrouter-auth-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-07-codex-terminal-ui-followup-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-07-compact-terminal-input-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-07-readable-terminal-reports-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-07-selector-family-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-07-terminal-work-log-refresh-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-20-pythinker-review-foundation-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-21-tui-spacing-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-22-blackbox-src-tui-port-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-22-windows-native-installer-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-24-install-downloads-counter-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-24-tui-brand-rebrand-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-26-agent-live-tool-stream-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-29-tui-renderer-contract-hardening-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-31-release-orchestration-design.mdis excluded by!docs/**docs/superpowers/specs/2026-05-31-welcome-banner-redesign-design.mdis excluded by!docs/**docs/superpowers/specs/2026-06-01-shimmer-traveling-waves-design.mdis excluded by!docs/**docs/superpowers/specs/2026-06-03-pythinker-scope-config-design.mdis excluded by!docs/**
📒 Files selected for processing (6)
.gitignoreCHANGELOG.mdpackages/windows-installer/installer.isssrc/pythinker_code/ui/shell/update.pytests/ui_and_conv/test_native_update_parity.pytests/ui_and_conv/test_shell_update.py
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Make the no-detach contract observable: fail the test if subprocess.Popen is invoked, so a regression that reintroduces the detached Windows upgrade is caught via behavior rather than internal mocks alone.
Summary
Fixes the Windows in-app update showing a spurious "could not close the program, close it and retry" dialog even though the update succeeded.
Root cause: the native installer's Restart Manager scan (
CloseApplications) runs at the start of the actual install — afterInitializeSetup(confirmed via Inno Setup's Installation Order). It raced the launchingpythinker.exeteardown, found the onedir_internal/DLLs still locked by the not-yet-exited console app (which RM can't gracefully close), and showed the Abort/Retry/Ignore dialog. By the time the user reacted, the launcher had exited and the install completed — hence "scary error, but it updated."Fix: pass the launcher PID via
/PIDand wait for that process to fully exit inInitializeSetup(bounded 15s;OpenProcess(SYNCHRONIZE)+WaitForSingleObject) before the scan runs. On timeout or a manual run with no PID, it falls through to today's behavior — strictly no regression.CloseApplications=yesstays, so other open instances are still handled correctly.Also in this PR
_detect_upgrade_command), the detach only remained reachable for a Windows source checkout — where the running executable is the interpreter, not a file the upgrade replaces, so there's no lock to dodge. That case now runs the upgrade inline like POSIX, surfacing real command output/errors instead of a fire-and-forget process. Deletes_spawn_detached_windows_upgradeand its two tests; the Windows do_update test is rewritten to assert the inline contract.docs/superpowers/specs/*.md(moved to the now-gitignoreddocs/archive/).Verification
make check-pythinker-code(ruff + format + pyright) — passes.tests/ui_and_conv/test_shell_update.py+test_native_update_parity.py— 94 passed..iss[Code]change cannot be verified on macOS — Inno Setup is Windows-only and the Restart Manager behavior only reproduces on Windows. Full validation needs a Windows build viawindows-installer.ymlor a manual Windows/updaterun. Python-side, a unit test asserts the spawn args include/PID=<pid>.Scope note
This targets the in-app
/updatepath (pythinker hands the installer its PID). A user who manually runs the downloaded installer while pythinker is open has no PID hand-off, and "please close it" is legitimate there.Summary by CodeRabbit