Skip to content

feat(tui): surface newly discovered updates mid-session#237

Merged
elkaix merged 3 commits into
mainfrom
feat/mid-session-update-notice
Jul 22, 2026
Merged

feat(tui): surface newly discovered updates mid-session#237
elkaix merged 3 commits into
mainfrom
feat/mid-session-update-notice

Conversation

@elkaix

@elkaix elkaix commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What

  • Toast a newly discovered release once per session when the background update check lands, instead of only surfacing it on the next launch's welcome banner.
  • Replace the one-shot startup update check with a session-lifetime loop that re-runs the mode-appropriate check every 30 minutes, so long-lived sessions notice new releases without a restart.
  • Dedupe update toasts by notice text per session so the periodic loop cannot re-toast managed-channel or restart notices every interval.

Why

After a release is tagged and promoted, a running or recently launched shell previously would not surface the update until the next restart outside the throttle window. The check bodies still re-consult the shared on-disk 30-minute throttle, so GitHub polling cadence is unchanged; dismissal and session-skip suppression apply to the toast. No mid-session install — staging remains restart-based.

Tests

  • New tests/ui_and_conv/test_mid_session_update_notice.py: toast on discovery, no toast for startup-cached/suppressed/repeat versions, toast dedup, loop cadence, loop error recovery, and scheduler-branch coverage.
  • make check-pythinker-code and full make test-pythinker-code (incl. tests_e2e) green locally.

Summary by CodeRabbit

  • New Features

    • Added update notices when a newer Pythinker version becomes available during an active session.
    • Added periodic background checks for available updates.
    • Update notifications are shown only once per version to prevent repeated alerts.
  • Bug Fixes

    • Prevented duplicate update toasts during repeated background checks.
    • Background update checks now continue after temporary errors.

elkaix added 2 commits July 22, 2026 12:02
Toast a newly discovered release once per session when the background
check lands, and re-run the mode-appropriate update check every 30
minutes for the lifetime of the shell session (previously startup-only).
The loop re-consults the shared on-disk throttle, so polling cadence is
unchanged; dismissal and session-skip suppression apply to the toast.
Address CodeRabbit review: the periodic check loop could re-toast
managed-channel and restart notices every interval, so _update_toast now
dedupes by notice text per session; add loop-recovery and toast-dedup
regression tests; replace coroutine-frame introspection in the scheduler
test with observable behavior.
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 35 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d7022a48-9a9a-4242-939c-07dc5df02318

📥 Commits

Reviewing files that changed from the base of the PR and between b28bdcf and c0a10ce.

📒 Files selected for processing (3)
  • src/pythinker_code/ui/shell/__init__.py
  • src/pythinker_code/ui/shell/update.py
  • tests/ui_and_conv/test_mid_session_update_notice.py
📝 Walkthrough

Walkthrough

The shell now performs periodic update checks during a session, refreshes update information, and displays deduplicated notices and toasts when a newer version is discovered. Startup scheduling routes notification modes through the periodic loop.

Changes

Mid-session update notices

Layer / File(s) Summary
Periodic update scheduling
src/pythinker_code/ui/shell/__init__.py
Adds an immediate-and-interval update loop and wires startup scheduling modes to periodic _auto_update or _silent_auto_update checks.
Update notice and toast deduplication
src/pythinker_code/ui/shell/__init__.py, tests/ui_and_conv/test_mid_session_update_notice.py, CHANGELOG.md
Tracks shown versions and notice text, refreshes update state, suppresses duplicate toasts, and tests discovery, suppression, recovery, timing, and scheduler wiring.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Shell
  participant UpdateLoop
  participant UpdateCache
  participant UserToast
  Shell->>UpdateLoop: start periodic update checks
  UpdateLoop->>Shell: invoke _auto_update
  Shell->>UpdateCache: refresh update cache
  UpdateCache-->>Shell: return available update target
  Shell->>UserToast: show notice when target is newly discovered
  Shell-->>Shell: deduplicate version and notice text
Loading

Possibly related PRs

Suggested labels: enhancement

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title follows conventional commit format and accurately describes the mid-session update-notice change.
Description check ✅ Passed The description covers What, Why, and Tests, but it omits the related issue link and the checklist section from the template.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/mid-session-update-notice

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


Comment @coderabbitai help to get the list of available commands.

@elkaix elkaix changed the title Feat/mid session update notice feat(tui): surface newly discovered updates mid-session Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@src/pythinker_code/ui/shell/__init__.py`:
- Around line 152-159: Update the periodic check loop around check() to enforce
an explicit timeout for each attempt, log timeout events distinctly, and
continue to the next iteration after a timeout. Preserve propagation of
asyncio.CancelledError and the existing exception logging for other failures.

In `@tests/ui_and_conv/test_mid_session_update_notice.py`:
- Around line 170-209: Refactor
test_startup_scheduler_uses_periodic_loop_in_all_scheduling_branches to avoid
mocking or asserting _periodic_update_check and _start_background_task wiring.
Instead, execute the scheduling branches and verify the observable
scheduled-check behavior, while preserving coverage for the alternate
PythinkerSoul branch and NOTIFY/DOWNLOAD modes.
🪄 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

Run ID: 69b84ac5-3246-4caf-8199-83548e3484a8

📥 Commits

Reviewing files that changed from the base of the PR and between b0a3807 and b28bdcf.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • src/pythinker_code/ui/shell/__init__.py
  • tests/ui_and_conv/test_mid_session_update_notice.py

Comment thread src/pythinker_code/ui/shell/__init__.py
Comment thread tests/ui_and_conv/test_mid_session_update_notice.py Outdated
Wrap each periodic update-check attempt in an asyncio.timeout backstop so a
non-network hang (stuck subprocess, trickle-forever stream) can no longer block
every future retry for the session; log the timeout distinctly and continue to
the next interval. The watchdog is 2x the poll interval so a genuinely slow
silent installer download (deliberately not total-timeout capped) still
completes.

Also refactor the scheduler branch test to assert the documented scheduled-coro
name at the _start_background_task seam instead of mocking the private
_periodic_update_check wiring.
@elkaix
elkaix merged commit 6385714 into main Jul 22, 2026
33 checks passed
@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

1 participant