Skip to content

fix(ui): boot context pill markdown + modal fixes#352

Open
dimakis wants to merge 2 commits into
mainfrom
fix/boot-context-pill-ux
Open

fix(ui): boot context pill markdown + modal fixes#352
dimakis wants to merge 2 commits into
mainfrom
fix/boot-context-pill-ux

Conversation

@dimakis
Copy link
Copy Markdown
Owner

@dimakis dimakis commented May 22, 2026

Summary

  • Markdown rendering: Section expansion and full markdown modal now render proper markdown (headings, tables, code blocks, lists) instead of raw <pre> text
  • Modal z-index: Portal modal to document.body so it renders above the command strip (was trapped in sticky pill stacking context)
  • Persistence: Preserve bootContext across switchSession() so the pill doesn't flash away during session switches

Test plan

  • Open a session, verify boot context pill renders with proper markdown in expanded sections
  • Tap the ⧉ button — modal should render above command strip with formatted markdown
  • Switch sessions — pill should persist until new session's boot context arrives
  • Verify build passes (npm run build)
  • Verify messages-slice tests pass

🤖 Generated with Claude Code

…ence

- Replace <pre> with ReactMarkdown in SectionRow and full markdown modal
- Portal modal to document.body to escape sticky stacking context
- Add proper markdown styles for headings, tables, code, lists
- Preserve bootContext across switchSession() state resets

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Owner Author

@dimakis dimakis left a comment

Choose a reason for hiding this comment

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

Centaur Review

Found 3 issue(s) (2 warning).

packages/client/src/store.ts

Solid UX improvement — markdown rendering and portal-based modal are clean. Main concern is preserving session-scoped bootContext across session switches, which could briefly show stale data for multi-repo setups.

  • 🟡 regressions (L254): bootContext is session-scoped (sent per-session in startChat via boot_context event), but is now preserved across switchSession(). If a user switches to a session started with a different cwd/repo, the stale boot context from the previous session will be shown until the new session's boot_context event arrives. newSession() correctly resets to INITIAL_MESSAGES_STATE (bootContext: null), so only switchSession has this inconsistency. Consider also clearing bootContext here and letting the RESTORE flow or a fresh boot_context event repopulate it. [fixable]
  • 🟡 missing_tests (L254): No test covers the new bootContext-preservation behavior in switchSession(). The packages/client directory has protocol-parser tests but no store tests. A unit test verifying that switchSession resets other state but preserves bootContext (and that newSession clears it) would document and protect this intentional asymmetry. [fixable]

frontend/src/styles/global.css

Solid UX improvement — markdown rendering and portal-based modal are clean. Main concern is preserving session-scoped bootContext across session switches, which could briefly show stale data for multi-repo setups.

  • 🔵 style: The markdown element styles for .boot-context-pill-section-content and .boot-context-modal-content are largely duplicated (headings, p, ul/ol, code, pre, pre code, table, th/td). Consider extracting a shared class or using a common parent selector to reduce ~50 lines of near-identical CSS. [fixable]

Comment thread packages/client/src/store.ts Outdated
set((s) => ({
sessions: { ...s.sessions, active: id },
messages: INITIAL_MESSAGES_STATE,
messages: { ...INITIAL_MESSAGES_STATE, bootContext: s.messages.bootContext },
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

🟡 regressions: bootContext is session-scoped (sent per-session in startChat via boot_context event), but is now preserved across switchSession(). If a user switches to a session started with a different cwd/repo, the stale boot context from the previous session will be shown until the new session's boot_context event arrives. newSession() correctly resets to INITIAL_MESSAGES_STATE (bootContext: null), so only switchSession has this inconsistency. Consider also clearing bootContext here and letting the RESTORE flow or a fresh boot_context event repopulate it. [fixable]

Comment thread packages/client/src/store.ts Outdated
set((s) => ({
sessions: { ...s.sessions, active: id },
messages: INITIAL_MESSAGES_STATE,
messages: { ...INITIAL_MESSAGES_STATE, bootContext: s.messages.bootContext },
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

🟡 missing_tests: No test covers the new bootContext-preservation behavior in switchSession(). The packages/client directory has protocol-parser tests but no store tests. A unit test verifying that switchSession resets other state but preserves bootContext (and that newSession clears it) would document and protect this intentional asymmetry. [fixable]

…d CSS

- Revert switchSession() bootContext preservation (stale data risk)
- Extract shared .boot-context-md class for markdown element styles
- Keep container-specific size overrides (compact vs modal)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Owner Author

@dimakis dimakis left a comment

Choose a reason for hiding this comment

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

Centaur Review

Found 3 issue(s) (1 warning).

frontend/src/components/BootContextPill.tsx

Clean UI fix: portal solves z-index stacking, markdown rendering replaces raw pre-formatted text. No bugs or regressions — minor suggestions around syntax highlighting parity and missing link styles.

  • 🔵 style (L38): MessageBubble uses rehypeHighlight for syntax-highlighted code blocks. BootContextPill renders CLAUDE.md content which contains fenced code blocks (bash commands, TS snippets), but omits rehypeHighlight — code blocks will render as plain monospace text without highlighting. Consider adding it for visual consistency. [fixable]
  • 🟡 missing_tests: No test file exists for BootContextPill. This PR adds two new behaviors — markdown rendering (ReactMarkdown) and portal-based modal — neither of which is covered. The project enforces TDD; while the missing tests predate this PR, the new code paths (markdown parsing, portal rendering) increase the risk surface. [fixable]

frontend/src/styles/global.css

Clean UI fix: portal solves z-index stacking, markdown rendering replaces raw pre-formatted text. No bugs or regressions — minor suggestions around syntax highlighting parity and missing link styles.

  • 🔵 style: The .boot-context-md class styles headings, tables, lists, code, hr, and strong — but omits anchor/link styling. If the rendered markdown contains links, they'll inherit browser defaults (blue/purple) which will look out of place against the dark theme. Consider adding .boot-context-md a { color: var(--text-secondary); text-decoration: underline; }. [fixable]

{open && section.content && (
<pre className="boot-context-pill-section-content">{section.content}</pre>
<div className="boot-context-pill-section-content boot-context-md">
<ReactMarkdown remarkPlugins={[remarkGfm]}>{section.content}</ReactMarkdown>
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

🔵 style: MessageBubble uses rehypeHighlight for syntax-highlighted code blocks. BootContextPill renders CLAUDE.md content which contains fenced code blocks (bash commands, TS snippets), but omits rehypeHighlight — code blocks will render as plain monospace text without highlighting. Consider adding it for visual consistency. [fixable]

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