refactor(web): context chips render through one ContextChip component - #13192
Conversation
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This refactor introduces a shared ContextChip abstraction and rewires many existing composer, markdown, attachment, citation, terminal, pull-request, and transcript surfaces. Because it changes shared DOM, styling, focus/interaction behavior, and editor selection handling across production paths, its blast radius warrants human review. You can add or adjust custom eligibility rules. Learn more. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: pingdotgg/t3code/.coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (9)
Limit details: You’ve used all 10 included reviews currently available. 📝 WalkthroughWalkthroughThis change adds shared chip components and updates composer, chat, and Markdown file-link renderers to use them. It also removes the prior chip styling constants and button variant, and adjusts chat Markdown link styles. ChangesShared inline chip migration
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Refactor Suggested reviewers: Merge Risk: ⚪ Minimal · up to Context chips in the composer, chat messages, citations, skills and Markdown file links now render through one shared chip component. The changes are presentational. Markdown file links keep their chip look rather than inheriting normal link colors. No outstanding issues block merging. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
05a145a to
3df3fe1
Compare
|
All clear Posted via Macroscope — Effect Service Conventions |
Button variant="chip" was an escape hatch: it skipped buttonVariants
entirely and let each call site assemble the chip look from exported
class-name constants (CHAT_INLINE_CHIP_CLASS_NAME, the tone maps, the
interactive and dismiss classes). Every chip surface re-derived the same
pill slightly differently.
ContextChip (components/ContextChip.tsx) now owns that look. It is a chat
feature component, not a components/ui primitive: nothing outside chat
context uses it. ContextChip takes a kind (neutral,
file, mention, terminal, skill, pull request states, …) and a state
(unresolved, invalid). Interactivity follows from what it renders as:
render={<button/>} or a link gets the hover tint, focus outline and
pointer, and media kinds zoom. ContextChipLabel truncates the text and
ContextChipAction is the in-chip icon button. The composer, sent messages, the
markdown file link, skills, terminal excerpts and citations all use it,
and variant="chip" plus the class-name exports are gone.
The markdown file link drops its own color and focus ring from
index.css so the chip's apply alone. The background worktree setup pill
is a Button ghost-muted micro now; it is a control, not context.
no-restyle findings: 624 -> 604.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
3df3fe1 to
c5cdcb6
Compare
…pingdotgg#13192) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…pingdotgg#13192) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
## What's Changed * hatch/variant functions by @juliusmarminge in pingdotgg/t3code#13191 * refactor(web): context chips render through one ContextChip component by @juliusmarminge in pingdotgg/t3code#13192 * refactor(web): ui components drop their secondary className props by @juliusmarminge in pingdotgg/t3code#13193 * refactor(web): menu triggers and items stop restyling ui/menu by @juliusmarminge in pingdotgg/t3code#13205 * refactor(web): field controls stop restyling Input, Select, Combobox and Command by @juliusmarminge in pingdotgg/t3code#13206 * refactor(web): app code stops restyling sidebar, popover, table and misc ui exports by @juliusmarminge in pingdotgg/t3code#13207 * refactor(web): Button consumers outside the composer stop restyling it by @juliusmarminge in pingdotgg/t3code#13208 * refactor(web): composer controls own their look instead of restyling ui components by @juliusmarminge in pingdotgg/t3code#13209 * chore(web): no-restyle fails lint, and the ceiling gate goes by @juliusmarminge in pingdotgg/t3code#13210 * fix(mobile): recover from screen render errors by @juliusmarminge in pingdotgg/t3code#13197 * feat(web): navigate back and forward with mod+[ and mod+] by @juliusmarminge in pingdotgg/t3code#13212 * fix(web): sort title matches by recent activity by @Yash-Singh1 in pingdotgg/t3code#13219 * test(desktop): remove redundant keyring module-load test by @t3-code[bot] in pingdotgg/t3code#13220 **Full Changelog**: pingdotgg/t3code@v0.0.43-nightly.20260923.2135...v0.0.43-nightly.20260923.2150 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.43-nightly.20260923.2150
## What Changed `markdownEditorPresentation.ts` owns the file-link chip class string instead of importing `CHAT_FILE_TAG_CHIP_CLASS_NAME`. The value is copied verbatim from the current base, so rich Markdown file links render unchanged. ## Why Upstream `266d70c` (`pingdotgg#13192`) removed `CHAT_FILE_TAG_CHIP_CLASS_NAME` in favor of a React `ContextChip`. The editor decorates raw DOM and cannot render that component, so it keeps the class itself. Syncing `v0.0.43-nightly.20260923.2150` fails web typecheck on the removed import, blocking the sync. ## Checklist - [x] This PR is small and focused - [x] I explained what changed and why - [ ] I included before/after screenshots for any UI changes - [ ] I included a video for animation/interaction changes ## Fork trailers Refs #1277 Fork-Domain: markdown-editing Fork-Tier: bugfix Fork-Upstreamable: no Co-authored-by: donjor <38745786+donjor@users.noreply.github.com>
## What Changed `markdownEditorPresentation.ts` owns the file-link chip class string instead of importing `CHAT_FILE_TAG_CHIP_CLASS_NAME`. The value is copied verbatim from the current base, so rich Markdown file links render unchanged. ## Why Upstream `266d70c` (`pingdotgg#13192`) removed `CHAT_FILE_TAG_CHIP_CLASS_NAME` in favor of a React `ContextChip`. The editor decorates raw DOM and cannot render that component, so it keeps the class itself. Syncing `v0.0.43-nightly.20260923.2150` fails web typecheck on the removed import, blocking the sync. ## Checklist - [x] This PR is small and focused - [x] I explained what changed and why - [ ] I included before/after screenshots for any UI changes - [ ] I included a video for animation/interaction changes ## Fork trailers Refs #1277 Fork-Domain: markdown-editing Fork-Tier: bugfix Fork-Upstreamable: no Co-authored-by: donjor <38745786+donjor@users.noreply.github.com>
## What Changed `markdownEditorPresentation.ts` owns the file-link chip class string instead of importing `CHAT_FILE_TAG_CHIP_CLASS_NAME`. The value is copied verbatim from the current base, so rich Markdown file links render unchanged. ## Why Upstream `266d70c` (`pingdotgg#13192`) removed `CHAT_FILE_TAG_CHIP_CLASS_NAME` in favor of a React `ContextChip`. The editor decorates raw DOM and cannot render that component, so it keeps the class itself. Syncing `v0.0.43-nightly.20260923.2150` fails web typecheck on the removed import, blocking the sync. ## Checklist - [x] This PR is small and focused - [x] I explained what changed and why - [ ] I included before/after screenshots for any UI changes - [ ] I included a video for animation/interaction changes ## Fork trailers Refs #1277 Fork-Domain: markdown-editing Fork-Tier: bugfix Fork-Upstreamable: no Co-authored-by: donjor <38745786+donjor@users.noreply.github.com>
Merges `pingdotgg/t3code` up to `78af372cf`: 27 commits on top of base `aca3c87cd`. It branches from `main`; no earlier merge PR was open. ## Resolution Six files conflicted, and each was resolved with the verdict `preflight.mjs` printed: - `AGENTS.md` (decide): the fork's Taste prose stays. Upstream's rule change is folded into it: `shadcn/no-restyle` now fails lint, and a look that belongs to one feature stays in that feature's component. - `GitActionsControl.tsx`, `ProjectScriptsControl.tsx`, `settings/ProjectActionsList.tsx`, `settings/SettingsSidebarNav.tsx` (converged): these take upstream's markup that no longer restyles `ui` components. The `FEATURES.openInEditor` gate, the `editable`/`taskScoped` gates and the personal/admin settings-nav split are re-applied at their new anchors. - `pnpm-lock.yaml` (theirs): upstream's copy, re-derived with `install.mjs`. `projectScriptEditor.tsx` merged without a conflict but had no path-policy entry, so it now has one: `project-script-editor`. **Changes needed after the merge.** Upstream pingdotgg#13210 made `shadcn/no-restyle` a lint error. That surfaced 65 violations, all in fork-only files, and I fixed them at the call sites: - `DialogPanel` in the Moatless settings dialogs keeps its own padding. - Inputs use `font="mono"`. - The sandbox tooltip uses `variant="code"`. - The repository search field uses `InputGroup`. - Muted captions in the sidebar filter are plain elements. - The task-link empty state uses the `Empty` defaults. `ui/textarea.tsx` gained the same `font` prop `Input` already has, recorded as inventory entry `textarea-mono-font`. **Visual change to review:** these panels now use the `ui` defaults for font size (13px → 14px) and dialog padding. ## Numbers - Landed: 255 files, against 239 in the upstream range. The gap of 16 is the lint fixes above plus `docs/fork/inventory.json`. - Fork delta: 787 files. ## Verification `verify.mjs` passed all 10 checks, including the full test step. The unsupported-method derivation had nothing to add or drop. ## Feature classification ### Usable as-is - Back/forward navigation with mod+[ and mod+] (pingdotgg#13212, `AppSidebarLayout.tsx`, keybindings contract). - Command palette sorts title matches by recent activity (pingdotgg#13219). - The previous worktree branch shows on a second line in the branch toolbar (pingdotgg#13314). - A context-chip component, `ui` components owning their own variants, composer chip rings no longer clip, a brain icon for the effort dropdown, and accessible switch state (pingdotgg#13192–pingdotgg#13210, pingdotgg#13301, pingdotgg#13309, pingdotgg#11580). - CSV preview keeps a final quoted empty record (pingdotgg#11425). - Mobile recovers from screen render errors (pingdotgg#13197); mobile version bump. ### Unsupported in Moatless / needs implementation - **Interactive 3D device workspace** (pingdotgg#12787, `apps/web/src/components/device/**`). It sits behind the existing `FEATURES.deviceHub` gate, and the `device.*` methods are still not dispatched. It is covered by the existing device-hub gap. - **Preview automation drives the visible browser for new agent sessions** (pingdotgg#13064, `PreviewAutomationBroker.ts`, `previewAutomation.ts`). Added to the existing preview-automation gap. - **Mobile environment and provider update management** (pingdotgg#13302). It is a paired-device surface, covered by the existing mobile gap. - Desktop-only fixes (SnapShot Dock icon pingdotgg#13286, keyring test removal): not applicable. ### Backend behavior to consider reproducing in Moatless - **Don't replay stale agent alerts after a restart** (pingdotgg#13340, `AgentAwarenessRelay.ts`). The relay publishes a completed or failed thread only if its latest turn finished after the server started. - **Normalise vendor-specific provider versions before the compatibility check** (pingdotgg#13328, `providerCompatibility.ts`, `model-manifest.json`). It strips Cursor's build hash and Antigravity's `agy_acp_server_` prefix, and restores the ranges for every harness. Both are recorded under "Runtime fixes upstream made to its own server" in `docs/fork/gaps.md`. The tracker entry is in `docs/fork/upstream-merge-log.md`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Moatless task: https://moatless.soaplabstest.com/tasks/0735cf38-d4cd-497a-87e7-ed2bc5c58ba6
## What Changed `markdownEditorPresentation.ts` owns the file-link chip class string instead of importing `CHAT_FILE_TAG_CHIP_CLASS_NAME`. The value is copied verbatim from the current base, so rich Markdown file links render unchanged. ## Why Upstream `266d70c` (`pingdotgg#13192`) removed `CHAT_FILE_TAG_CHIP_CLASS_NAME` in favor of a React `ContextChip`. The editor decorates raw DOM and cannot render that component, so it keeps the class itself. Syncing `v0.0.43-nightly.20260923.2150` fails web typecheck on the removed import, blocking the sync. ## Checklist - [x] This PR is small and focused - [x] I explained what changed and why - [ ] I included before/after screenshots for any UI changes - [ ] I included a video for animation/interaction changes ## Fork trailers Refs #1277 Fork-Domain: markdown-editing Fork-Tier: bugfix Fork-Upstreamable: no Co-authored-by: donjor <38745786+donjor@users.noreply.github.com>
## What Changed `markdownEditorPresentation.ts` owns the file-link chip class string instead of importing `CHAT_FILE_TAG_CHIP_CLASS_NAME`. The value is copied verbatim from the current base, so rich Markdown file links render unchanged. ## Why Upstream `266d70c` (`pingdotgg#13192`) removed `CHAT_FILE_TAG_CHIP_CLASS_NAME` in favor of a React `ContextChip`. The editor decorates raw DOM and cannot render that component, so it keeps the class itself. Syncing `v0.0.43-nightly.20260923.2150` fails web typecheck on the removed import, blocking the sync. ## Checklist - [x] This PR is small and focused - [x] I explained what changed and why - [ ] I included before/after screenshots for any UI changes - [ ] I included a video for animation/interaction changes ## Fork trailers Refs #1277 Fork-Domain: markdown-editing Fork-Tier: bugfix Fork-Upstreamable: no Co-authored-by: donjor <38745786+donjor@users.noreply.github.com>
## What Changed `markdownEditorPresentation.ts` owns the file-link chip class string instead of importing `CHAT_FILE_TAG_CHIP_CLASS_NAME`. The value is copied verbatim from the current base, so rich Markdown file links render unchanged. ## Why Upstream `266d70c` (`pingdotgg#13192`) removed `CHAT_FILE_TAG_CHIP_CLASS_NAME` in favor of a React `ContextChip`. The editor decorates raw DOM and cannot render that component, so it keeps the class itself. Syncing `v0.0.43-nightly.20260923.2150` fails web typecheck on the removed import, blocking the sync. ## Checklist - [x] This PR is small and focused - [x] I explained what changed and why - [ ] I included before/after screenshots for any UI changes - [ ] I included a video for animation/interaction changes ## Fork trailers Refs #1277 Fork-Domain: markdown-editing Fork-Tier: bugfix Fork-Upstreamable: no Co-authored-by: donjor <38745786+donjor@users.noreply.github.com>
## What Changed `markdownEditorPresentation.ts` owns the file-link chip class string instead of importing `CHAT_FILE_TAG_CHIP_CLASS_NAME`. The value is copied verbatim from the current base, so rich Markdown file links render unchanged. ## Why Upstream `266d70c` (`pingdotgg#13192`) removed `CHAT_FILE_TAG_CHIP_CLASS_NAME` in favor of a React `ContextChip`. The editor decorates raw DOM and cannot render that component, so it keeps the class itself. Syncing `v0.0.43-nightly.20260923.2150` fails web typecheck on the removed import, blocking the sync. ## Checklist - [x] This PR is small and focused - [x] I explained what changed and why - [ ] I included before/after screenshots for any UI changes - [ ] I included a video for animation/interaction changes ## Fork trailers Refs #1277 Fork-Domain: markdown-editing Fork-Tier: bugfix Fork-Upstreamable: no Co-authored-by: donjor <38745786+donjor@users.noreply.github.com>
## What Changed `markdownEditorPresentation.ts` owns the file-link chip class string instead of importing `CHAT_FILE_TAG_CHIP_CLASS_NAME`. The value is copied verbatim from the current base, so rich Markdown file links render unchanged. ## Why Upstream `266d70c` (`pingdotgg#13192`) removed `CHAT_FILE_TAG_CHIP_CLASS_NAME` in favor of a React `ContextChip`. The editor decorates raw DOM and cannot render that component, so it keeps the class itself. Syncing `v0.0.43-nightly.20260923.2150` fails web typecheck on the removed import, blocking the sync. ## Checklist - [x] This PR is small and focused - [x] I explained what changed and why - [ ] I included before/after screenshots for any UI changes - [ ] I included a video for animation/interaction changes ## Fork trailers Refs #1277 Fork-Domain: markdown-editing Fork-Tier: bugfix Fork-Upstreamable: no Co-authored-by: donjor <38745786+donjor@users.noreply.github.com>
Button variant="chip"skippedbuttonVariantsentirely. Each chip site then assembled the pill from exported class constants (the tone maps, the interactive classes, the dismiss class), so every chip surface re-derived the look slightly differently.ContextChip(components/ContextChip.tsx) now owns it. It is a chat feature component, not acomponents/uiprimitive: nothing outside chat context uses it, so it lives with the chat code and gets no exemption from the lint rule.ContextChiptakes akind(file, mention, terminal, skill, pull request states, …) and astate(unresolved,invalid).ContextChipLabeltruncates the label.ContextChipActionis the in-chip icon button (editing a citation comment).The composer, sent messages, the markdown file link, skills, terminal excerpts and citations all use it.
variant="chip"and the class exports are gone. The markdown file link no longer draws a second focus ring fromindex.css. The background worktree setup pill becomes aButton(ghost-muted, micro), because it is a control and not context.no-restylefindings: 623 → 603.Claude Opus 5.5 via Claude Code.
🤖 Generated with Claude Code
Summary by CodeRabbit