Skip to content

feat(shell): faster auto-update detection, persistent update notice, compact-terminal robot - #146

Merged
elkaix merged 4 commits into
mainfrom
fix/auto-update-detection-latency
Jun 15, 2026
Merged

feat(shell): faster auto-update detection, persistent update notice, compact-terminal robot#146
elkaix merged 4 commits into
mainfrom
fix/auto-update-detection-latency

Conversation

@elkaix

@elkaix elkaix commented Jun 15, 2026

Copy link
Copy Markdown
Member

Summary

Startup/auto-update experience fixes prompted by "auto-update doesn't sense new release tags," the welcome robot disappearing in narrow terminals, and wanting the update hint to persist.

1. Faster auto-update detection (update.py, ui/shell/__init__.py)

auto_update defaults to on and silently installs new releases at startup, but two gates delayed detection:

  • 24h throttle. The background check ran at most once per 24h (AUTO_UPDATE_CHECK_INTERVAL_SECONDS), so a release published shortly after the last check went unnoticed for a full day. Lowered to 30 minutes.
  • Mark-before-run. _silent_auto_update stamped the throttle file before the network round-trip, so an offline/slow startup burned the whole window with zero work done. It now marks only after a non-FAILED run — a transient error returns FAILED and retries next launch (mirrors _refresh_update_cache).

2. Keep the welcome robot visible in compact terminals (ui/shell/__init__.py)

Below ~68 content columns the robot mark could not sit beside the welcome copy, so it was dropped entirely. It now stacks centered above the copy, staying visible at any width that can render its Unicode glyphs. ASCII-only terminals are unchanged; the boot antenna blink fires on the stacked logo too (still gated by the on-screen height guard).

3. Persistent update notice under the prompt input (ui/shell/prompt.py, ui/shell/__init__.py)

When a newer release is available the footer now renders a yellow ↑ Update available — vX · /update line directly under the input (above the separator, in both legacy and card layouts), so the hint persists instead of only flashing as a transient toast.

  • State-aware: after a release is installed in the background this session, the cache still reports a newer version — so the line switches to a restart-to-apply message (agreeing with the install toast) instead of pointing at /update, and clears once the user restarts onto the new version.
  • Sourced from welcome_update_target(), so it's suppressed for dismissed versions, disabled auto-update, and source checkouts. Cache read is memoized on a 5s TTL (mirrors the footer's git-branch TTL) to stay off the hot render path.

Design notes

  • The in-app updater hits REST /releases/latest, which excludes prereleases by design. The pipeline holds each release as prerelease: true until all assets upload and promote-release.yml promotes it — so the exclusion is the intended "assets ready" gate, not a bug (verified vs GitHub REST docs + Context7). No endpoint/fallback change.
  • The check is unauthenticated (60 req/hr/IP); at ~2 polls/hr/startup this is a wide margin, and a ClientError fails safe. (304-not-modified is only rate-limit-free when authenticated, so the ETag cache saves bandwidth, not quota.)

Tests

  • test_silent_update_marks_throttle_only_after_non_failed_run — throttle marked only after a non-FAILED run.
  • test_welcome_compact_terminal_stacks_robot_above_copy + matrix updated to expect the robot at all widths.
  • test_update_notice_* — available→/update, installed-this-session→restart, smoke-failed→fallback, none-when-up-to-date, 5s TTL memo; plus _prepend_update_notice insert/no-op tests.
  • make check-pythinker-code ✅ (ruff + format + pyright, 0 errors); focused suites green.

elkaix added 2 commits June 14, 2026 20:45
…ottle

Background startup auto-update was throttled to once per 24h, so a freshly
published release could go unnoticed for up to a day after the last check.
Lower the interval to 30 minutes.

Also stop marking the throttle before the network call in the silent path:
a transient startup error now returns FAILED and is retried on the next
launch instead of suppressing updates for the whole window (mirrors the
notice-only refresh path). Add a focused test pinning that the throttle is
marked only after a non-FAILED run.
Below ~68 content columns the robot mark could not sit beside the welcome
copy, so it was dropped entirely. Stack it centered above the copy instead,
so the mark stays visible at any width that can render its Unicode glyphs.
ASCII-only terminals are unchanged (no robot). The boot antenna blink now
fires on the stacked logo too, still gated by the existing on-screen height
guard.
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@elkaix, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 30 minutes and 51 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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6728bcc6-6d55-418b-87a6-9af44c81c3a6

📥 Commits

Reviewing files that changed from the base of the PR and between 891847a and 71e074b.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • src/pythinker_code/ui/shell/__init__.py
  • src/pythinker_code/ui/shell/prompt.py
  • tests/ui_and_conv/test_prompt_tips.py
  • tests/ui_and_conv/test_shell_welcome_info.py
  • tests/ui_and_conv/test_silent_auto_update.py
📝 Walkthrough

Walkthrough

Two startup UX fixes: AUTO_UPDATE_CHECK_INTERVAL_SECONDS is reduced from 24 hours to 30 minutes, and _mark_auto_update_check_attempt() is now called only after a non-FAILED update result. The welcome banner gains a logo_beside_copy branch that stacks the robot logo centered above copy in terminals narrower than ~68 columns.

Changes

Startup UX: auto-update throttle and compact welcome banner

Layer / File(s) Summary
Auto-update throttle interval and mark-on-success logic
src/pythinker_code/ui/shell/update.py, src/pythinker_code/ui/shell/__init__.py, tests/ui_and_conv/test_silent_auto_update.py, CHANGELOG.md
AUTO_UPDATE_CHECK_INTERVAL_SECONDS set to 30 * 60; _mark_auto_update_check_attempt() moved to execute only after _run_silent_update_job() returns a non-FAILED result; new parametrized async test spies on mark call count across FAILED, UP_TO_DATE, and UPDATED outcomes; CHANGELOG updated.
Welcome banner robot stacking in compact terminals
src/pythinker_code/ui/shell/__init__.py, tests/ui_and_conv/test_shell_welcome_info.py
logo_beside_copy variable separates the beside-copy rendering case from the general show_logo flag; single-panel layout adds elif show_logo branch to center-stack the robot above copy; width-matrix test unconditionally asserts robot mark presence; new test verifies robot line precedes welcome copy at width 58.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

bug

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 70.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description check ✅ Passed Description is comprehensive and covers all required sections with detailed context on changes, design notes, and test coverage.
Title check ✅ Passed The title follows conventional commits format with type(scope) and clearly describes the main changes: faster auto-update detection, persistent update notice, and compact-terminal robot visibility improvements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/auto-update-detection-latency

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.

❤️ Share

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

@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: 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_welcome_info.py`:
- Around line 158-160: The assertion at line 160 checks for the Unicode glyph
"▛" but the test does not pin the ascii_glyphs_enabled() setting, causing the
test to flake when running in ASCII mode. Ensure the test deterministically uses
Unicode glyph rendering by either pinning ascii_glyphs_enabled() to return False
before the assertion, or by making the assertion conditional based on the glyph
rendering mode (checking ascii_glyphs_enabled() and asserting the appropriate
character for that mode).
🪄 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: 9279d6c7-37ab-4042-9012-0904ad8a39be

📥 Commits

Reviewing files that changed from the base of the PR and between 4845610 and 891847a.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • src/pythinker_code/ui/shell/__init__.py
  • src/pythinker_code/ui/shell/update.py
  • tests/ui_and_conv/test_shell_welcome_info.py
  • tests/ui_and_conv/test_silent_auto_update.py

Comment thread tests/ui_and_conv/test_shell_welcome_info.py
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.23529% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/pythinker_code/ui/shell/prompt.py 87.50% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

When a newer release is available the footer now renders a yellow
"↑ Update available — vX · /update" line directly under the input, so the
hint persists instead of only flashing as a transient toast. It renders
above the separator in both the legacy and card footer layouts.

The text is state-aware: after a release is installed in the background this
session the cache still reports a newer version, so the line switches to the
restart-to-apply message (agreeing with the install toast) instead of
pointing at /update, and clears once the user restarts onto the new version.
Sourced from welcome_update_target(), so it is suppressed for dismissed
versions, disabled auto-update, and source checkouts. The cache read is
memoized on a 5s TTL to keep it off the hot toolbar render path.
@elkaix elkaix changed the title fix(update,shell): faster auto-update detection + keep robot visible in compact terminals Auto-update UX: faster detection, persistent update notice, robot in compact terminals Jun 15, 2026
@elkaix elkaix changed the title Auto-update UX: faster detection, persistent update notice, robot in compact terminals feat(shell): faster auto-update detection, persistent update notice, compact-terminal robot Jun 15, 2026
The matrix test asserts the robot mark ("▛") renders at every width but
relied on the ambient glyph mode; pin ascii_glyphs_enabled to False so the
assertion is deterministic regardless of locale/stdout encoding, matching
test_welcome_two_column_layout_when_wide.
@elkaix
elkaix merged commit 95f4619 into main Jun 15, 2026
31 checks passed
@elkaix
elkaix deleted the fix/auto-update-detection-latency branch June 15, 2026 01:30
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