Skip to content

fix: brew tap-trust recovery, antenna boot blink, export secret redaction - #120

Merged
elkaix merged 4 commits into
mainfrom
fix/brew-tap-trust-antenna-blink-export-redaction
Jun 12, 2026
Merged

fix: brew tap-trust recovery, antenna boot blink, export secret redaction#120
elkaix merged 4 commits into
mainfrom
fix/brew-tap-trust-antenna-blink-export-redaction

Conversation

@elkaix

@elkaix elkaix commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Three independent, self-contained fixes. Each ships with tests; make check-pythinker-code is green.

1. Homebrew untrusted-tap recovery

Homebrew 5.0 added HOMEBREW_REQUIRE_TAP_TRUST, which refuses to load formulas from third-party taps until brew trust <tap> is run once. The in-app updater's brew upgrade pythinker-code therefore failed for every Homebrew ≥5 user on first update, printing only a generic "try running manually" hint.

  • _homebrew_untrusted_tap() parses both the hard Refusing to load … from untrusted tap <tap> refusal and the soft Skipping <tap> because it is not trusted warning (the latter only counts when it names our tap).
  • On an interactive terminal: offer to run brew trust <tap>, then refresh and retry the upgrade once. Non-interactively (or on decline): print the exact brew trust pythoughts-labs/pythinker remediation.
  • Also covers the silent-no-op case where brew update skips the untrusted tap and brew upgrade exits 0 without advancing the version.
  • Documented in the repo README and the tap repo README.

2. Antenna boot animation

Replaces the welcome logo's infinite SGR slow-blink with a bounded boot animation: the antenna ball blinks 7 times after the banner prints, then pins steady. Gated to real terminals tall enough to keep the antenna row on screen; skipped under reduced motion and non-TTY. The e2e PTY helper now runs with PYTHINKER_REDUCED_MOTION=1 so the animation adds no latency/cursor-noise there.

3. Export secret redaction

A tool result (e.g. grep/cat over a .env) could surface a secret value into the exported transcript in plaintext (observed: an ADMIN_PASSWORD=… landing in a .md export). Adds a conservative redact_secrets() that replaces the value of secret-named keys (password/token/api_key/secret/…) with [REDACTED], wired as a single chokepoint in both the markdown and YAML export builders. Non-secret keys (token_count, usernames, ports) are left untouched.

Tests

  • tests/ui_and_conv/test_shell_update.py — 9 new untrusted-tap cases (parse, prompt+retry, decline, trust-failure, silent-no-op).
  • tests/ui_and_conv/test_shell_welcome_info.py — 7-blink contract, motion/TTY/short-terminal gating.
  • tests/utils/test_sensitive.py — redaction unit cases incl. the exact leaked patterns.
  • tests/e2e/shell_pty_helpers.py — reduced-motion env.

Not included (follow-up)

Mid-message inline /command handling and the related agent-behavior issues (whole-file rewrite, weak verification, EnterPlanMode tool-availability confusion) are deliberately left out — they belong in the test-pinned system-prompt surface and warrant a focused, agent-mediated change rather than a mechanical parser (which testing against a real GPT-5.5 prompt showed would discard the user's task).

Summary by CodeRabbit

  • New Features

    • Homebrew updater now detects untrusted taps and offers interactive remediation via brew trust
    • Session transcript exports automatically redact sensitive values (passwords, tokens, API keys, secrets) to [REDACTED]
    • Welcome logo antenna blinks seven times on startup, then stays steady; respects reduced-motion settings
  • Documentation

    • Updated installation guide with Homebrew v5 untrusted-tap guidance

elkaix added 2 commits June 11, 2026 22:27
…tion

Three independent fixes to the updater, welcome banner, and session export.

Homebrew untrusted-tap recovery:
- Homebrew 5.0's HOMEBREW_REQUIRE_TAP_TRUST refuses third-party taps until
  `brew trust <tap>` is run once, so the in-app updater's `brew upgrade`
  failed with only a generic "run manually" hint. Parse both the hard
  "Refusing to load ... from untrusted tap" refusal and the soft
  "Skipping ... not trusted" warning; on an interactive terminal, offer to
  run `brew trust` and retry the upgrade once, otherwise print the exact
  remediation. Also handles the silent-no-op case where an untrusted tap is
  skipped during `brew update`. Documented in both READMEs.

Antenna boot animation:
- Replace the welcome logo's infinite SGR slow-blink with a bounded boot
  animation: blink the antenna ball 7 times after the banner prints, then
  pin it steady. Gated to real terminals tall enough to keep the antenna
  row on screen; skipped under reduced motion and non-TTY. E2E PTY helper
  runs with reduced motion so the animation adds no latency there.

Export secret redaction:
- A tool result (grep/cat over a .env) could surface a secret value into the
  exported transcript in plaintext. Add a conservative redact_secrets() that
  replaces the value of secret-named keys (password/token/api_key/secret/...)
  with [REDACTED], wired as a chokepoint in both the markdown and YAML export
  builders. Non-secret keys (token_count, usernames, ports) are untouched.
@coderabbitai

coderabbitai Bot commented Jun 12, 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 42 minutes and 55 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ 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: 6aa3b61d-9d07-4d72-b63d-76aa1aae54f6

📥 Commits

Reviewing files that changed from the base of the PR and between 8cd2a51 and 73a026a.

📒 Files selected for processing (2)
  • tests/ui_and_conv/test_shell_update.py
  • tests/utils/test_sensitive.py
📝 Walkthrough

Walkthrough

This PR introduces three independent user-facing features: Homebrew untrusted-tap detection with interactive recovery during in-app updates; secret-value redaction from exported session transcripts; and a fixed-count antenna-blink boot animation replacing indefinite SGR blinking on interactive terminals.

Changes

Homebrew Untrusted Tap Handling

Layer / File(s) Summary
Untrusted tap detection and user consent
src/pythinker_code/ui/shell/update.py
Module-level regex patterns detect Homebrew's tap refusal and skip messages; helper functions check TTY availability and show an async dialog prompting users to run brew trust <tap>.
Output capture and Homebrew metadata refresh
src/pythinker_code/ui/shell/update.py
Captured-output buffering wraps upgrade execution so each line feeds both the console and an in-memory list; brew update --quiet is wrapped to capture its output for later parsing.
Upgrade retry loop with untrusted-tap recovery
src/pythinker_code/ui/shell/update.py
Replaces single-shot upgrade with a retry loop that detects untrusted taps in captured output, prompts once for user consent, runs brew trust, refreshes metadata, retries on success, and reports failure with tailored hints (trust remediation or stale no-op).
Untrusted tap parsing and integration tests
tests/ui_and_conv/test_shell_update.py
Unit tests validate _homebrew_untrusted_tap() parsing; end-to-end tests cover interactive consent, declined consent, trust failure, and silent no-op scenarios, each asserting correct output messages and UpdateResult.
Homebrew installation and trust documentation
README.md
Added Homebrew v5 guidance for trusting the tap and explains that the in-app updater detects refusal and offers remediation.

Secret Redaction in Exports

Layer / File(s) Summary
Secret detection and redaction regex
src/pythinker_code/utils/sensitive.py
New redact_secrets(text: str) -> str uses case-insensitive regex to detect KEY=VALUE and KEY: VALUE patterns whose keys end with secret-name hints (password, token, api_key, secret) and replaces matched values with [REDACTED].
Redaction applied to export outputs
src/pythinker_code/utils/export.py
Imports redact_secrets and wraps final joined markdown and YAML-dumped payloads in build_export_markdown and build_export_yaml to prevent secret values from leaking into shared transcripts.
Secret redaction unit and integration tests
tests/utils/test_sensitive.py
Tests validate env assignments, colon-separated secrets, grep line-prefix preservation, quoted values, and edge cases; confirms no false positives on non-secret keys and empty input.

Welcome Antenna Boot Animation

Layer / File(s) Summary
Logo text styling and animation helpers
src/pythinker_code/ui/shell/__init__.py
Imports cell_len for width measurement; antenna style changes from blinking to steady (muted under reduced motion); new internal helpers locate the antenna glyph and blink it a fixed number of times using direct cursor control.
Conditional boot animation after welcome panel
src/pythinker_code/ui/shell/__init__.py
After printing the welcome panel, conditionally triggers the blink sequence by detecting the antenna ball position, guarded by terminal-type checks and terminal-height bounds to keep animation in view.
Welcome antenna animation and blink tests
tests/ui_and_conv/test_shell_welcome_info.py
Tests verify logo never includes Rich blink spans, antenna blinks exactly _ANTENNA_BLINKS times with cursor control escapes, and skipping is enforced for reduced motion, non-terminal output, and short terminal height.
PTY test environment reduced motion
tests/e2e/shell_pty_helpers.py
Sets PYTHINKER_REDUCED_MOTION=1 in shell PTY tests to suppress boot animation and cursor-control noise not asserted by e2e tests.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Pythoughts-labs/pythinker-code#87: Modifies the Homebrew updater's brew update/brew upgrade execution and post-upgrade version validation, which this PR extends with untrusted-tap detection and retry.

Suggested labels

bug

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.86% 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
Title check ✅ Passed The title follows conventional commit format with 'fix:' prefix and clearly summarizes the three main changes (brew tap-trust, antenna blink, export redaction).
Description check ✅ Passed The PR description comprehensively covers all three fixes with detailed rationale, implementation approach, test coverage, and explicitly documents what's excluded. All required template sections are addressed.
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.

✏️ 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/brew-tap-trust-antenna-blink-export-redaction

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.

Comment thread tests/ui_and_conv/test_shell_update.py Fixed

@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/utils/test_sensitive.py`:
- Around line 45-47: Add a new unit test to cover the benign-keys edge case so
redact_secrets does not redact keys where the secret hint is followed by
additional characters (e.g., token_count or access_key_id). Create a test
function (e.g., test_redact_ignores_keys_with_suffix_after_hint) in the same
test module that passes a string like "token_count=100\naccess_key_id=AKIA..."
to redact_secrets and asserts the output equals the input; ensure the test name
and assertion reference redact_secrets so the intent and behavior are documented
and protected.
🪄 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: b7d11837-e07a-4b43-ab75-3aadc5055966

📥 Commits

Reviewing files that changed from the base of the PR and between 7caeca3 and 8cd2a51.

📒 Files selected for processing (10)
  • CHANGELOG.md
  • README.md
  • src/pythinker_code/ui/shell/__init__.py
  • src/pythinker_code/ui/shell/update.py
  • src/pythinker_code/utils/export.py
  • src/pythinker_code/utils/sensitive.py
  • tests/e2e/shell_pty_helpers.py
  • tests/ui_and_conv/test_shell_update.py
  • tests/ui_and_conv/test_shell_welcome_info.py
  • tests/utils/test_sensitive.py

Comment thread tests/utils/test_sensitive.py
@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.85106% with 18 lines in your changes missing coverage. Please review.

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

📢 Thoughts on this report? Let us know!

elkaix added 2 commits June 11, 2026 22:41
Keys where the secret hint is not immediately before the separator
(token_count, access_key_id) must not be redacted. Lock that intentional
behavior in per CodeRabbit's suggestion on #120.
GitHub code-quality flagged implicit string concatenation of adjacent
literals inside the list arguments to _homebrew_untrusted_tap (a common
missing-comma footgun). Use explicit '+' so the single-line intent is
unambiguous to readers and the scanner.
@elkaix
elkaix merged commit bff54f9 into main Jun 12, 2026
31 checks passed
@elkaix
elkaix deleted the fix/brew-tap-trust-antenna-blink-export-redaction branch July 17, 2026 20:04
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