Skip to content

feat(shell): polish prompt rendering and recaps - #49

Merged
elkaix merged 10 commits into
mainfrom
fix/prompt-ui-login-branding
Jun 1, 2026
Merged

feat(shell): polish prompt rendering and recaps#49
elkaix merged 10 commits into
mainfrom
fix/prompt-ui-login-branding

Conversation

@elkaix

@elkaix elkaix commented Jun 1, 2026

Copy link
Copy Markdown
Member

Summary

  • Add branded browser-login result page assets and reuse it for OpenAI auth callbacks.
  • Polish shell prompt/user echo/file mention/tool output rendering, including hook output in live views.
  • Add session recap support, /recap, turn recap display controls, and tests.

Verification

  • uv run pytest tests/core/test_wire_message.py::test_wire_message_type_alias tests/hooks/test_integration.py::test_wire_resolved_callback_receives_hook_output tests/ui_and_conv/test_live_view_notifications.py::test_live_view_prints_resolved_hook_stdout -q
  • uv run pytest tests/core/test_config.py::test_default_config_dump tests/ui_and_conv/test_visualize_running_prompt.py::test_visualize_uses_prompt_live_view_when_prompt_session_and_steer_are_provided -q
  • uv run pytest tests_e2e/test_wire_protocol.py::test_initialize_handshake tests_e2e/test_wire_protocol.py::test_initialize_external_tool_conflict -q
  • make check && make test

Summary by CodeRabbit

  • New Features

    • /recap command to generate session summaries and a configurable compact "turn recap" line (enabled by default, toggleable via /settings or /config).
    • Inline two-column file‑mention completion menu.
  • Improvements

    • Branded browser-login result pages with embedded logo/favicon.
    • Hook stdout/stderr now appear in transcripts with clearer spacing and formatted previews.
    • Better prompt wrapping/alignment, user-echo layout, diff collapse/expand behavior, and safer final-text printing when piping.
  • Tests

    • Expanded coverage for recaps, UI rendering, diffs, hook outputs, and TUI behavior.

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds session-recap generation and a /recap command, propagates bounded hook stdout/stderr into wire events and UI, centralizes browser-login result HTML/branding, enhances TUI prompt/echo/completion and diff collapse/expand behavior, adds destructive-shell detection, and expands tests accordingly.

Changes

Session Recaps and Hook Outputs with Interactive UI

Layer / File(s) Summary
Browser login asset extraction
src/pythinker_code/auth/browser_login_page.py, src/pythinker_code/auth/openai.py, tests/auth/test_openai_auth.py
browser_login_page provides cached base64 data-URIs for logo/favicon and a shared HTML builder used by OpenAI callback and tests.
Session recap models and parsing
src/pythinker_code/session_recap.py, tests/test_session_recap.py
Adds RecapRange and SessionRecapItem dataclasses and parse_recap_range() to convert user strings into UTC timestamp ranges.
Session recap pipeline
src/pythinker_code/session_recap.py, tests/test_session_recap.py
build_pythinker_recap and summarize_session_for_recap scan sessions and wire records to aggregate turns, messages, tool counts, and modified files; format_recap and build_turn_recap_line render final outputs.
Session recap slash command
src/pythinker_code/soul/slash.py
Adds /recap command that invokes build_pythinker_recap and returns the generated recap or validation error via wire_send.
Hook output wire model
src/pythinker_code/wire/types.py
Introduces HookOutput model for bounded stdout/stderr, exit code, timeout/truncation flags; extends HookResolved.outputs.
Hook engine output capture
src/pythinker_code/hooks/engine.py, tests/hooks/test_integration.py
Aggregates per-hook outputs with truncation, inspects on_resolved callback signature (inspect), and conditionally supplies outputs to callbacks; integration test verifies outputs delivered.
Wire server output serialization
src/pythinker_code/wire/server.py
Validates and serializes HookOutput items when populating HookResolved.outputs sent to clients.
Turn recap accumulation and display
src/pythinker_code/ui/shell/visualize/_live_view.py
_LiveView tracks per-turn user input, assistant text parts, and tool counts; marks pending recaps and prints a compact recap line on cleanup when enabled.
Visualize recap parameter threading
src/pythinker_code/ui/shell/visualize/__init__.py, src/pythinker_code/ui/shell/visualize/_interactive.py, src/pythinker_code/ui/shell/__init__.py
Adds show_turn_recaps parameter to visualize() and threads it through live-view constructors; Shell.run_soul_command() reads config.tui.turn_recaps and forwards the flag.
Hook output transcript rendering
src/pythinker_code/ui/shell/visualize/_blocks.py
Formats resolved hook outputs (ANSI-sanitized stdout/stderr, labels, timeout/truncation notices) and inserts BLANK_ROW/bullet preview spacing in composing/thinking modes.
File mention completion menu
src/pythinker_code/ui/shell/prompt.py, tests/ui_and_conv/test_slash_completer.py
Adds LocalFileMentionMenuControl to render inline @ completions with two-column layout and counter; LocalFileMentionCompleter.should_complete detects active mention contexts; completion preselection behavior adjusted.
Prompt input continuation and margin
src/pythinker_code/ui/shell/prompt.py, tests/ui_and_conv/test_prompt_tips.py
Adds _PromptRightPaddingMargin and _INPUT_RIGHT_PADDING, wires prompt_continuation to align wrapped input, and reserves right-edge padding in the compact input window.
User input rendering
src/pythinker_code/ui/shell/echo.py, tests/ui_and_conv/test_shell_prompt_echo.py
Introduces UserEcho Rich renderable to align prompt-prefixed user transcript lines using BulletColumns; echo functions now return UserEcho.
Diff collapse/expand with hints
src/pythinker_code/ui/shell/tool_renderers/_file_diff.py, src/pythinker_code/ui/shell/tool_renderers/edit.py, src/pythinker_code/ui/shell/tool_renderers/write.py, tests/ui_and_conv/test_tui_card_tool_renderers.py
diff_frame supports collapsed view with expanded/collapsed_max_lines/state; write/edit renderers compute diff blocks and pass UI state; helper _is_existing_file_diff detects add-only existing-file changes.
Config, settings, and theme
src/pythinker_code/config.py, src/pythinker_code/ui/shell/selectors/settings.py, src/pythinker_code/ui/shell/slash.py, src/pythinker_code/ui/theme.py, tests/core/test_config.py
Adds turn_recaps: bool to TUIConfig (default True), exposes as "Turn recaps" in settings (also /config alias), and extends prompt/completion theme tokens.
Expandable payload state cache
src/pythinker_code/ui/shell/components/tool_execution.py
Renderer-state key __has_expandable_payload__ short-circuits _has_expandable_payload() to avoid expensive heuristics.
Rich wrapping and markdown list width
src/pythinker_code/utils/rich/__init__.py, src/pythinker_code/utils/rich/markdown.py
Restores word-aware wrapping by default; markdown ListItem uses cell_len to compute child widths for correct wrapping/alignment.
Print-final behavior for pipes vs TTY
src/pythinker_code/ui/print/visualize.py, tests/ui_and_conv/test_print_final_only.py
When stdout is not a terminal and no report block exists, final text is printed verbatim (pipe-safe); interactive terminals use Console rendering.
ANSI sanitization update
src/pythinker_code/ui/shell/components/render_utils.py, tests/ui_and_conv/test_tui_components.py
sanitize_ansi now strips 8-bit C1 control bytes before ANSI CSI removal; test added for C1 stripping.
Destructive shell command detection
src/pythinker_code/soul/permission.py, tests/core/test_permission_profiles.py
Adds shell_destructive_reason to classify destructive shell commands (rm -rf, dd, truncate, force git ops, opaque inline interpreters); new tests assert detection.
Tests and e2e snapshots
various tests/* modules
Adds and updates tests for HookOutput wiring, browser-login branding, session recap utilities and CLI, live-view hook output and turn-recap printing, prompt/layout, file-mention menu, diff collapsing, markdown table/wrapping contracts, and e2e handshake snapshots including the recap command.
Release notes
CHANGELOG.md
Notes interactive shell recap and rendering improvements and branded login result pages.
  • Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Suggested labels

enhancement

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/prompt-ui-login-branding

@elkaix elkaix changed the title Polish shell prompt rendering and recaps feat(shell): polish prompt rendering and recaps Jun 1, 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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/pythinker_code/ui/shell/components/tool_execution.py (1)

295-303: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Document (or clear) __has_expandable_payload__ so its lifetime matches frame expectations.

tool_execution.py pops __suppress_generic_expand_hint__ each frame, but there’s no corresponding clear for __has_expandable_payload__—it’s only set in _file_diff.py and then only read in _has_expandable_payload(). If persistence across frames is intentional, add a one-line comment explaining that; otherwise clear it alongside the suppress flag to avoid stale can_expand.

🤖 Prompt for 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.

In `@src/pythinker_code/ui/shell/components/tool_execution.py` around lines 295 -
303, The stored flag __has_expandable_payload__ is persisting across frames but
only set in _file_diff.py and read by _has_expandable_payload(), which can cause
stale can_expand state; either add a one-line comment near the flag's use in
_file_diff.py (or above _has_expandable_payload) stating that cross-frame
persistence is intentional, or clear/pop __has_expandable_payload__ in the same
place where __suppress_generic_expand_hint__ is popped each frame so both flags
share the same lifetime and avoid stale values.
src/pythinker_code/ui/shell/visualize/__init__.py (1)

120-135: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add an explicit return type to visualize.

visualize is a public function under src/**; please declare -> None.

As per coding guidelines, src/**/*.py: Flag missing type annotations on public functions and methods.

🤖 Prompt for 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.

In `@src/pythinker_code/ui/shell/visualize/__init__.py` around lines 120 - 135,
The public async function visualize should declare an explicit return type;
update the function signature of visualize to include "-> None" (i.e., async def
visualize(... ) -> None:) so the public API in
src/pythinker_code/ui/shell/visualize/__init__.py is properly annotated; keep
all existing parameters (initial_status, cancel_event, prompt_session, steer,
btw_runner, bind_running_input, unbind_running_input, on_view_ready,
on_view_closed, show_thinking_stream, show_turn_recaps) unchanged.
src/pythinker_code/ui/shell/visualize/_interactive.py (1)

242-248: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Turn recaps can be dropped in interactive mode.

TurnEnd is consumed here and never reaches _LiveView’s TurnEnd branch, so _pending_turn_recap is not set. That prevents recap emission during cleanup() for interactive runs.

Proposed fix
                 if isinstance(msg, TurnEnd):
                     self._active_turn_depth = max(0, self._active_turn_depth - 1)
                     self._turn_ended = self._active_turn_depth == 0
                     if self._turn_ended:
                         self._turn_start_time = None
+                        self._pending_turn_recap = True
                     self._flush_prompt_refresh()
                     continue
🤖 Prompt for 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.

In `@src/pythinker_code/ui/shell/visualize/_interactive.py` around lines 242 -
248, The TurnEnd message is being consumed in the interactive loop and never
reaches _LiveView, so set the pending recap flag or forward the message instead:
in the TurnEnd handling inside _interactive.py (the block that updates
_active_turn_depth, _turn_ended, clears _turn_start_time and calls
_flush_prompt_refresh), after those steps either set self._pending_turn_recap =
True (so cleanup() will emit the recap) or explicitly forward the TurnEnd to the
_LiveView handler (e.g., call the same dispatch used for other messages) so the
_LiveView TurnEnd branch still runs; ensure the chosen approach preserves the
existing depth/timing updates and does not duplicate recap emission.
🤖 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/soul/slash.py`:
- Line 60: The public async function recap in src/pythinker_code/soul/slash.py
is missing an explicit return type; update its signature from "async def
recap(soul: PythinkerSoul, args: str):" to include "-> None" (i.e., "async def
recap(soul: PythinkerSoul, args: str) -> None:") so it satisfies the project's
public typing rule for functions in src/**.

In `@src/pythinker_code/ui/shell/visualize/_blocks.py`:
- Around line 1038-1043: The timeout warning is only shown when output.timed_out
and not body.plain, hiding timeout status if partial output exists; update the
logic in the block that checks output.timed_out/output.truncated so that when
output.timed_out is true you always append a "hook timed out" warning (using
body.append and tui_rich_style("warning")), regardless of body.plain, mirroring
how output.truncated is handled, and ensure you preserve spacing/newline
behavior consistent with the existing truncation branch.

In `@tests/ui_and_conv/test_streaming_content_block.py`:
- Around line 239-243: The helper _assert_blank_line_after_activity should first
assert that the provided label appears in output and provide a clear failure
message if not; locate the activity_index by searching lines for label (as
currently done), but wrap the search in a check (or try/except around next(...))
to raise an AssertionError like f"Label '{label}' not found in output" instead
of letting StopIteration propagate, and also assert that there is a following
line before accessing lines[activity_index + 1], failing with a clear message if
the activity is the last line.

---

Outside diff comments:
In `@src/pythinker_code/ui/shell/components/tool_execution.py`:
- Around line 295-303: The stored flag __has_expandable_payload__ is persisting
across frames but only set in _file_diff.py and read by
_has_expandable_payload(), which can cause stale can_expand state; either add a
one-line comment near the flag's use in _file_diff.py (or above
_has_expandable_payload) stating that cross-frame persistence is intentional, or
clear/pop __has_expandable_payload__ in the same place where
__suppress_generic_expand_hint__ is popped each frame so both flags share the
same lifetime and avoid stale values.

In `@src/pythinker_code/ui/shell/visualize/__init__.py`:
- Around line 120-135: The public async function visualize should declare an
explicit return type; update the function signature of visualize to include "->
None" (i.e., async def visualize(... ) -> None:) so the public API in
src/pythinker_code/ui/shell/visualize/__init__.py is properly annotated; keep
all existing parameters (initial_status, cancel_event, prompt_session, steer,
btw_runner, bind_running_input, unbind_running_input, on_view_ready,
on_view_closed, show_thinking_stream, show_turn_recaps) unchanged.

In `@src/pythinker_code/ui/shell/visualize/_interactive.py`:
- Around line 242-248: The TurnEnd message is being consumed in the interactive
loop and never reaches _LiveView, so set the pending recap flag or forward the
message instead: in the TurnEnd handling inside _interactive.py (the block that
updates _active_turn_depth, _turn_ended, clears _turn_start_time and calls
_flush_prompt_refresh), after those steps either set self._pending_turn_recap =
True (so cleanup() will emit the recap) or explicitly forward the TurnEnd to the
_LiveView handler (e.g., call the same dispatch used for other messages) so the
_LiveView TurnEnd branch still runs; ensure the chosen approach preserves the
existing depth/timing updates and does not duplicate recap emission.
🪄 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: 738240ed-65c6-44a6-9aa7-08ec547f73e0

📥 Commits

Reviewing files that changed from the base of the PR and between 691cc49 and ee1c15c.

📒 Files selected for processing (37)
  • CHANGELOG.md
  • src/pythinker_code/auth/browser_login_page.py
  • src/pythinker_code/auth/openai.py
  • src/pythinker_code/config.py
  • src/pythinker_code/hooks/engine.py
  • src/pythinker_code/session_recap.py
  • src/pythinker_code/soul/slash.py
  • src/pythinker_code/ui/shell/__init__.py
  • src/pythinker_code/ui/shell/components/tool_execution.py
  • src/pythinker_code/ui/shell/echo.py
  • src/pythinker_code/ui/shell/prompt.py
  • src/pythinker_code/ui/shell/selectors/settings.py
  • src/pythinker_code/ui/shell/slash.py
  • src/pythinker_code/ui/shell/tool_renderers/_file_diff.py
  • src/pythinker_code/ui/shell/tool_renderers/edit.py
  • src/pythinker_code/ui/shell/tool_renderers/write.py
  • src/pythinker_code/ui/shell/visualize/__init__.py
  • src/pythinker_code/ui/shell/visualize/_blocks.py
  • src/pythinker_code/ui/shell/visualize/_interactive.py
  • src/pythinker_code/ui/shell/visualize/_live_view.py
  • src/pythinker_code/ui/theme.py
  • src/pythinker_code/wire/server.py
  • src/pythinker_code/wire/types.py
  • tests/auth/test_openai_auth.py
  • tests/core/test_config.py
  • tests/core/test_wire_message.py
  • tests/hooks/test_integration.py
  • tests/test_session_recap.py
  • tests/ui_and_conv/test_live_view_notifications.py
  • tests/ui_and_conv/test_md_table_contract.py
  • tests/ui_and_conv/test_prompt_tips.py
  • tests/ui_and_conv/test_shell_prompt_echo.py
  • tests/ui_and_conv/test_slash_completer.py
  • tests/ui_and_conv/test_streaming_content_block.py
  • tests/ui_and_conv/test_tui_card_tool_renderers.py
  • tests/ui_and_conv/test_visualize_running_prompt.py
  • tests_e2e/test_wire_protocol.py

Comment thread src/pythinker_code/soul/slash.py Outdated
Comment thread src/pythinker_code/ui/shell/visualize/_blocks.py Outdated
Comment thread tests/ui_and_conv/test_streaming_content_block.py
elkaix added 4 commits June 1, 2026 15:00
Apply verified fixes from the branch code-diff review:

- write/_file_diff: a brand-new file >10k lines produced a one-line diff
  summary ("removed 1 / added 1") instead of "Wrote N lines". The summary
  block's "- (0 lines)" line made preview.removed==1, so the diff path was
  taken regardless of _is_existing_file_diff. Add DiffPreview.is_new_file
  (every block's old side empty) and gate the diff path on it, fixing both
  routing clauses. Pre-existing bug; validated across new/existing × huge/small.
- render_utils.sanitize_ansi: strip 8-bit C1 controls (0x80-0x9F), incl. the
  single-byte CSI/OSC/PM/APC introducers terminals still interpret.
- _live_view: route the per-turn recap banner through sanitize_ansi.
- wire/types.HookOutput: bound stdout/stderr with max_length (12_032, headroom
  for the engine's truncation marker) so oversized payloads fail at the wire
  boundary instead of being silently accepted.
- auth/browser_login_page: cap the asset data-uri cache (lru_cache maxsize=16).
- hooks/engine: document why OnResolved stays Callable[..., None] (the runtime
  intentionally supports both 5- and 6-arg callbacks; a strict Protocol/overload
  rejects one valid arity — confirmed via the type gate).
- tests: backfill session_recap (3 -> 24 tests, incl. summarize_session via a
  fake session), huge-new-file write render, and C1 ANSI stripping.
- soul/permission: add shell_destructive_reason() to flag irreversible
  commands (recursive force-delete, force-push, hard reset, raw disk writes)
  so auto mode routes them into a deliberation turn instead of auto-approving.
  Reuses the shell_mutation_reason tokenizer (shlex split, wrapper unwrap,
  git-subcommand extraction) for wrapper/quote/chain hardening.
- CodeRabbit review fixes: annotate /recap slash command with -> None; show
  hook "timed out" status even when the hook produced output; make the
  streaming-block test helper fail loudly when the label is missing.
- tests: cover destructive classification, the recap/visualize paths, and the
  hardened test helper.

@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_live_view_notifications.py`:
- Around line 125-143: In
test_live_view_prints_hook_timeout_status_with_partial_output, the
monkeypatch.setattr for shell_console.print uses a lambda that accepts **kwargs
but doesn't use it; update the replacement callable used in monkeypatch.setattr
(in the test function
test_live_view_prints_hook_timeout_status_with_partial_output) to either remove
the unused kwargs (use lambda *args: printed.extend(args)) or rename it to
**_kwargs to silence the unused-kwargs warning so the printed list still
collects args from shell_console.print.
🪄 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: 3b58d645-3f9d-4d83-9421-29dcf08616bb

📥 Commits

Reviewing files that changed from the base of the PR and between 01f1da0 and 5b53405.

📒 Files selected for processing (11)
  • src/pythinker_code/soul/permission.py
  • src/pythinker_code/soul/slash.py
  • src/pythinker_code/ui/shell/components/tool_execution.py
  • src/pythinker_code/ui/shell/visualize/__init__.py
  • src/pythinker_code/ui/shell/visualize/_blocks.py
  • src/pythinker_code/ui/shell/visualize/_interactive.py
  • tests/core/test_permission_profiles.py
  • tests/ui_and_conv/test_live_view_notifications.py
  • tests/ui_and_conv/test_streaming_content_block.py
  • tests/ui_and_conv/test_tui_render_snapshots.py
  • tests/ui_and_conv/test_visualize_running_prompt.py

Comment thread tests/ui_and_conv/test_live_view_notifications.py

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/ui_and_conv/test_live_view_notifications.py (1)

322-322: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use **_kwargs for consistency with line 129.

Line 129 was updated to silence the unused-kwargs warning by renaming **kwargs to **_kwargs. This new test should follow the same pattern.

♻️ Proposed fix
-        live_view_module.console, "print", lambda *args, **kwargs: printed.extend(args)
+        live_view_module.console, "print", lambda *args, **_kwargs: printed.extend(args)
🤖 Prompt for 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.

In `@tests/ui_and_conv/test_live_view_notifications.py` at line 322, The lambda
used in the monkeypatch calling live_view_module.console.print should rename its
kwargs parameter to _kwargs for consistency with the change on line 129; update
the lambda signature from "lambda *args, **kwargs: printed.extend(args)" to use
"lambda *args, **_kwargs: printed.extend(args)" so the unused-kwargs warning is
silenced while keeping behavior identical.
🤖 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.

Outside diff comments:
In `@tests/ui_and_conv/test_live_view_notifications.py`:
- Line 322: The lambda used in the monkeypatch calling
live_view_module.console.print should rename its kwargs parameter to _kwargs for
consistency with the change on line 129; update the lambda signature from
"lambda *args, **kwargs: printed.extend(args)" to use "lambda *args, **_kwargs:
printed.extend(args)" so the unused-kwargs warning is silenced while keeping
behavior identical.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d4992c14-590e-4840-a215-712df277e0bb

📥 Commits

Reviewing files that changed from the base of the PR and between 5b53405 and 522a920.

📒 Files selected for processing (1)
  • tests/ui_and_conv/test_live_view_notifications.py

elkaix added 3 commits June 1, 2026 16:19
icon.svg and favicon.ico under web/static/brand are read at runtime by
auth/browser_login_page to embed branding in the OAuth callback HTML, but the
whole web/static tree is gitignored — so CI's clean checkout lacked them and
test_openai_callback_html_* failed with FileNotFoundError (passed locally only
because the files exist on disk). Force-add the two required assets so the
feature and its tests work from a fresh clone.
Committing the brand assets makes web/static/ exist in CI for the first time,
which previously un-skipped test_index_html_has_no_cache_header — but the built
frontend (index.html, assets/) still isn't present, so GET / would 404. Guard
on index.html existence instead, matching the 'web static assets not built'
intent: runs where the app is built (local/prod), skips where only brand assets
exist (CI).
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