Skip to content

feat(web): add chat width setting for wide screens - #11594

Merged
Yash-Singh1 merged 5 commits into
pingdotgg:mainfrom
otavio:feat/chat-width-setting
Sep 26, 2026
Merged

Yash-Singh1 merged 5 commits into
pingdotgg:mainfrom
otavio:feat/chat-width-setting

Conversation

@otavio

@otavio otavio commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

The chat timeline and composer are capped at 48rem, so on a large monitor most of the window stays empty and wide content such as markdown tables has to scroll sideways.

This adds a Chat width setting under Settings → Appearance with three options: Comfortable (the current 48rem, still the default), Wide (72rem), and Full. It is a client setting, like diff colors. The root sets data-chat-width on <html>, CSS maps it to --chat-max-width, and the six chat containers that used max-w-3xl now use max-w-(--chat-max-width). The setting has a reset button, appears in settings search, and is included in "Restore defaults".

Desktop picks this up through the web app. Mobile has no fixed-width chat column, so nothing changes there.

The commits are split for review: the contracts setting and its test, the layout change, then the settings control.

Screenshots use a seeded test thread.

Before (Comfortable) After (Full)
before after

Wide:

wide

Setting:

setting

Made with Claude Opus 5 in Claude Code, running inside T3 Code.

Summary by CodeRabbit

  • New Features
    • Added a Chat width setting with Comfortable, Wide, and Full options to adjust the chat timeline and composer.
    • Added Chat width to settings search.
    • Added a not-found page with a button to return home.
  • Bug Fixes
    • Improved timeline minimap navigation at different chat widths; controls are interactive when there is enough space.
    • Updated the error page’s retry action.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Sep 13, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a persisted, user-facing chat layout feature that changes production rendering across the timeline and composer, with multiple opt-in width modes. The existing default is preserved, but the distributed implementation has no accompanying tests for the new behavior.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Sep 13, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 74d174fa-c63d-4a9e-9f09-602b320dc2cf

📥 Commits

Reviewing files that changed from the base of the PR and between 89f7d18 and c1f0f25.

📒 Files selected for processing (11)
  • apps/web/src/components/ChatView.tsx
  • apps/web/src/components/chat/ChatComposer.tsx
  • apps/web/src/components/chat/MessagesTimeline.logic.ts
  • apps/web/src/components/chat/MessagesTimeline.test.tsx
  • apps/web/src/components/chat/MessagesTimeline.tsx
  • apps/web/src/components/settings/SettingsPanels.tsx
  • apps/web/src/components/settings/settingsSearch.ts
  • apps/web/src/index.css
  • apps/web/src/routes/__root.tsx
  • packages/contracts/src/settings.test.ts
  • packages/contracts/src/settings.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/src/components/ChatView.tsx

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The change adds a chatWidth setting with Comfortable, Wide, and Full options. The setting updates a root data attribute and CSS width token. Chat containers use that token, and the timeline minimap measures rendered content width to calculate gutters and navigation interaction.

Changes

Chat width setting

Layer / File(s) Summary
Setting contract and Appearance controls
packages/contracts/src/settings.ts, packages/contracts/src/settings.test.ts, apps/web/src/components/settings/SettingsPanels.tsx, apps/web/src/components/settings/settingsSearch.ts
Defines the ChatWidth schema and adds the setting to client settings and patches. The Appearance UI supports the three values, search, validation, change tracking, and reset behavior. Tests cover defaults, supported values, patches, and invalid values.
Root width state and CSS token
apps/web/src/routes/__root.tsx, apps/web/src/index.css
Synchronizes chatWidth to the root element’s data-chat-width attribute. Defines the width token for comfortable, wide, and full modes.
Chat container widths and minimap behavior
apps/web/src/components/ChatView.tsx, apps/web/src/components/chat/ChatComposer.tsx, apps/web/src/components/chat/ComposerSurface.tsx, apps/web/src/components/chat/MessagesTimeline.tsx, apps/web/src/components/chat/MessagesTimeline.logic.ts, apps/web/src/components/chat/MessagesTimeline.test.tsx
Uses the CSS variable for chat container widths. The minimap uses rendered content width for gutter calculations, remeasures when chatWidth changes, and gates navigation-button pointer interaction by hit-strip width. Tests cover gutter, strip, and navigation-interactivity calculations.

Priority: ⬇️ Low

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

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant ClientSettings
  participant ContrastAppearanceSync
  participant DocumentRoot
  participant ChatLayout
  ClientSettings->>ContrastAppearanceSync: provide chatWidth
  ContrastAppearanceSync->>DocumentRoot: set data-chat-width
  DocumentRoot->>ChatLayout: expose --chat-max-width
Loading

Merge Risk: ⚪ Minimal · up to c1f0f

The chat-width setting and minimap adjustments appear ready for normal checks before merge.

Security Architecture Review

Security architecture risk: 🔵 Low · up to c1f0f

The new preference is limited to three layout choices and does not appear to change access to messages or privileged operations. Compatibility with older clients and some downstream coverage remain unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The evidenced effect is the current client's chat presentation and minimap controls; the examined flow does not expand message or service authority.

Trust Boundaries and Controls

  • observed — The shared contract limits the preference to comfortable, wide, or full before the root copies it into the document attribute; CSS defines width behavior for those choices rather than interpreting an arbitrary width string.

Resilience and Maintainability Implications

  • observed — Hydration and queued patches preserve update ordering, but a failed persistence write is logged without reversing the displayed optimistic value. Older-client recovery after reading the extended contract remains unverified.
🚥 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 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 11 files. (1 skipped:… 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 clearly identifies the main change: adding a chat width setting for wide screens. It is concise and specific.
Description check ✅ Passed The description explains what changed and why, documents the UI behavior, lists the available width modes, describes desktop and mobile impact, and includes before/after screenshots. It does not repro…
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 11 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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

@cursor

cursor Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@OmarAlaaeldein

Copy link
Copy Markdown

This would fix a real pain for me too — on a wide monitor the thread/composer sits at 768px and uses less than half the available width, with no setting to change it. Wide tables/code output constantly need horizontal scroll despite all the whitespace.

Love the Comfortable / Wide / Full approach with Comfortable staying default. That matches the existing readable / wide / expanded pattern already used for workspace pages, just extended to chat where it's actually needed.

@v1b3coder

Copy link
Copy Markdown

Supporting the need — on a 3440px-wide monitor the fixed 48rem column leaves most of the pane empty and wide output still scrolls sideways. Comfortable / Wide / Full with Comfortable as the default looks like the right shape, and as a client setting it also covers desktop and remote connections.

One gap in the diff: TIMELINE_CONTENT_MAX_WIDTH = 768 in MessagesTimeline.logic.ts still drives resolveTimelineMinimapHasPersistentGutter and resolveTimelineMinimapHitStripWidth. Those assume a centered column at most 768px wide, and the comment above the hit-strip helper warns that a too-wide strip sits on top of the message text and swallows its pointer events. With full, at a 2560px viewport the helper still computes a ~896px gutter and returns the full 40px strip while the real gutter is 0, so the strip covers the first ~40px of the message column. The setting needs to feed those helpers, or they should measure the lane element.

@saphid

saphid commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

@otavio I opened otavio#1 against feat/chat-width-setting to close the minimap gap @v1b3coder described above. If you merge it, this PR picks it up.

  • The minimap gutter and hover-strip helpers now take the rendered column width instead of assuming 768px, and they re-measure when chatWidth changes.
  • The minimap's prev/next turn buttons ignore the pointer when the gutter is too narrow to hold them. Before this, they also covered message text at Full width.

I measured it in a real dev build. At Full width, the 40px strip used to overlap the column by 26px, so clicks on the text's left edge landed on the strip. It now shrinks to 14px with no overlap. Comfortable and Wide are unchanged. Focused tests and web typecheck pass. Details are in the linked PR.

Made with Claude Opus 5.5 in Claude Code, running inside T3 Code.

@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Sep 23, 2026
otavio added a commit to otavio/nix-config that referenced this pull request Sep 25, 2026
nixpkgs still ships 0.0.40, and I want the context window indicator
moved out of legacy settings (pingdotgg/t3code#12095) and the chat
width setting (pingdotgg/t3code#11594) before they are merged. Both
are rebased onto v0.0.43-preview.20260925.2240 and carried as patches.
The preview centralised the chat column on --chat-content-max-width,
so the chat width setting now overrides that variable rather than
introducing its own.

The release moved to Electron 44, and its web build fetches SPDX
license texts at build time, so the overlay seeds that cache from a
pinned license-list-data checkout to keep the sandboxed build offline.
otavio and others added 5 commits September 25, 2026 12:40
Adds a persisted chatWidth client setting with comfortable (default), wide, and full, so existing users keep the current layout.
The timeline and composer containers read --chat-max-width instead of a fixed max-w-3xl. The root sets data-chat-width from the client setting and CSS maps it to 48rem, 72rem, or 100%.
Settings → Appearance gets a Chat width selector with a reset action. It is searchable and included in Restore defaults.
The minimap gutter and hover-strip helpers assumed the chat column is
capped at 768px. With the Wide or Full chat width, the real gutter is
narrower or gone, so the 40px hover strip sat on top of the message text
and swallowed its pointer events. Measure the rendered column instead and
re-measure when the Chat width setting changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ters

The previous and next turn buttons hang above and below the minimap strip
and stayed clickable regardless of the strip's width cap. With Full chat
width and overlay scrollbars they covered the first few pixels of message
text. Make them inert to the pointer unless the gutter can hold them;
keyboard focus still reaches them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@otavio
otavio force-pushed the feat/chat-width-setting branch from 89f7d18 to c1f0f25 Compare September 25, 2026 15:53
@Yash-Singh1
Yash-Singh1 merged commit 04c15f3 into pingdotgg:main Sep 26, 2026
19 of 20 checks passed
fireboltdude1357 pushed a commit to fireboltdude1357/t3code that referenced this pull request Sep 26, 2026
Merges origin/main (a21b42c) into t3code/codex-turn-mapping so V2
carries main's fixes. A merge rather than a rebase keeps the 715 V2
commits and the stacked PRs on this branch intact.

Conflict resolutions that change V2 code:
- server.ts: keep V2's layer graph; add main's ReplayMarkers layer next to
  the other background layers.
- serverRuntimeStartup.ts: keep V2's imports plus main's flushCompileCache.
- bin.ts: keep V2's thin entry (the command list lives in binCli.ts).
- ProjectionSnapshotQuery (V1): drop the second shell-snapshot decode
  (pingdotgg#13693); do not add listThreadsWithPullRequests (V2's PR sync does
  not read the V1 table it queries).
- PullRequestSyncReactor, ThreadPullRequestService: keep V2's versions.
- CursorDriver / cursorUsageLimits: keep V2's SDK-based driver and pass
  main's cursorKeychainUsageEnabled opt-in through to usage limits.
  Main's lowercase cursorCredentialStore.ts collides by case with V2's
  CursorCredentialStore.ts, so it becomes cursorKeychainToken.ts.
- Chat width (pingdotgg#11594): keep V2's chat-content-lane markup; main's
  settings row sits next to V2's composer-context row.
- pingdotgg#13590 env-mode label: V2's thread details panel now passes envMode
  through to BranchToolbar like the composer strip does.
- Sidebar provider stack badge uses main's text-5xs token instead of
  V2's one-off 7px class (same size).
- Deleted-in-V2 V1 files that main modified stay deleted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
fireboltdude1357 pushed a commit to fireboltdude1357/t3code that referenced this pull request Sep 26, 2026
…V2's chat lane

Main's chat width setting sets --chat-max-width, which main's timeline and
composer read. V2 sizes the same surfaces (chat-content-lane, the
composer, and ChatCanvas's width probe that drives the preview layout)
with --chat-content-max-width, so after the merge the setting was saved
but changed nothing. Wide and Full now override V2's token; Comfortable
keeps V2's default (46rem, close to main's 48rem).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants