chore(lint): keep mobile theme escape-hatch allowlist honest - #13146
Conversation
The reviewed-boundary allowlist for the no-mobile-uniwind-theme-escape-hatches rule still carried ThreadTerminalRouteScreen after the shared terminal header refactor removed its theme-bridge usage, and the files screen still read the JS palette for an ordinary Android header background. Drop the stale entry, style that background with the bg-header semantic class instead, and re-verify the rule stays green: every remaining allowlisted file has a real native or third-party interop consumer (react-native-screens config, Reanimated swipeables, SVG gradients, native markdown, navigation options), and the only other grep hit is the useUniwindTheme definition file itself, which imports nothing, so no new entries were needed. Model: callstack/Apex via pi
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a small lint-hygiene cleanup that replaces two ordinary theme reads with equivalent semantic classes and removes stale lint allowlist entries. It introduces no new capability, schema, product-default, deployment, or sensitive-data change. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: 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. |
The CodeAppearancePreview read the JS palette for the line-number and keyword colors of two ordinary Text nodes. Render them with the text-icon-subtle and text-md-link semantic classes (same tokens, and the nested-Text conditional class pattern already used by thread search matches), keep only the dynamic font metrics in style, and drop AppearancePreviews.tsx from the allowUniwindTheme override so future JS palette reads in that file are linted. The allowlist now matches the actual useUniwindTheme importers 1:1. Model: callstack/Apex via pi
Dismissing prior approval to re-evaluate f27a865
|
Fixed the reviewer-audit P2: |
|
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 (3)
💤 Files with no reviewable changes (1)
Included review availability: Your plan provides up to 10 included reviews per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe Android files wrapper and appearance previews now use theme classes instead of colors read from the theme hook. The interop exception list no longer includes ChangesMobile theme class alignment
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Other Suggested reviewers: Merge Risk: ⚪ Minimal · up to The files header and appearance preview retain their theme-based colors through semantic classes. No merge-blocking risk was found; the change is ready for normal checks. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
## What's Changed * chore(mobile): drop dead nitro-markdown tgz override and @expo/metro-runtime by @juliusmarminge in pingdotgg/t3code#13148 * feat(web): show settings scope as a sentence at the top of the page by @juliusmarminge in pingdotgg/t3code#13139 * refactor(web): move settings scope pickers into breadcrumbs by @Yash-Singh1 in pingdotgg/t3code#13165 * feat(auth): share provider sign-in flows and credential bindings by @juliusmarminge in pingdotgg/t3code#12983 * refactor(mobile): git sheets use uniwind platform variants instead of className ternaries by @juliusmarminge in pingdotgg/t3code#13161 * chore(mobile): name the two project favicon caches by their job by @juliusmarminge in pingdotgg/t3code#13160 * revert(mobile): git sheets back to Platform.OS ternaries (un-guarded uniwind variants broke both platforms) by @juliusmarminge in pingdotgg/t3code#13169 * docs(mobile): document the two mobile routes that intentionally skip deep links by @juliusmarminge in pingdotgg/t3code#13164 * refactor(mobile): break module cycles with focused extractions by @juliusmarminge in pingdotgg/t3code#13151 * fix(server): generate PR diffs from branch changes by @Yash-Singh1 in pingdotgg/t3code#13170 * fix(web): preserve nested scroll behavior in chat timeline by @Yash-Singh1 in pingdotgg/t3code#13167 * test(web): cover usage model ordering without static markup by @flamboh in pingdotgg/t3code#13104 * fix(desktop): find linuxbrew node for the WSL backend by @CodyRay in pingdotgg/t3code#7827 * chore(models): use GPT-6 Luna for text generation by @extoci in pingdotgg/t3code#13115 * fix(mobile): keep ordinary offline outbox failures out of console.warn by @juliusmarminge in pingdotgg/t3code#13144 * feat(providers): check remote compatibility ranges by @juliusmarminge in pingdotgg/t3code#13130 * chore(lint): keep mobile theme escape-hatch allowlist honest by @juliusmarminge in pingdotgg/t3code#13146 * fix(web): the pull request badge reads at the meta size again by @juliusmarminge in pingdotgg/t3code#13175 * fix(mobile): uniwind platform variants stay guarded on both platforms by @juliusmarminge in pingdotgg/t3code#13172 * refactor(mobile): git sheets use uniwind platform variants instead of className ternaries by @juliusmarminge in pingdotgg/t3code#13185 * refactor(mobile): remaining className platform ternaries become class variants by @juliusmarminge in pingdotgg/t3code#13188 * fix(web): align provider emails without clipping by @Derpedyea in pingdotgg/t3code#13174 * perf(mobile): recycle the default v2 home list and scope the snooze minute tick by @juliusmarminge in pingdotgg/t3code#13149 * refactor(mobile): retire the legacy grouped thread list by @juliusmarminge in pingdotgg/t3code#13183 * fix(server): background PR checks spend less GitHub quota by @juliusmarminge in pingdotgg/t3code#13189 * fix(server): background PR sync reads summaries in batches by @juliusmarminge in pingdotgg/t3code#13198 * fix(server): GitHub PR lookups stop probing owner-qualified heads by @juliusmarminge in pingdotgg/t3code#13200 * chore(mobile): clear the legacy-list deletion fallout by @juliusmarminge in pingdotgg/t3code#13203 ## New Contributors * @CodyRay made their first contribution in pingdotgg/t3code#7827 **Full Changelog**: pingdotgg/t3code@v0.0.43-nightly.20260922.2123...v0.0.43-nightly.20260923.2135 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.43-nightly.20260923.2135
Problem
The mobile lint rule
t3code/no-mobile-uniwind-theme-escape-hatcheskeeps theme styling on semantic Uniwind classNames and only exempts reviewed native/third-party interop boundaries via anallowUniwindThemeoverride list invite.config.ts. The audit of that boundary found it had drifted:features/terminal/ThreadTerminalRouteScreen.tsxwas still allowlisted even though the shared terminal header refactor removed its last theme-bridge usage.ThreadFilesTreeScreenstill read the JS palette (useUniwindTheme()["--color-header"]) to background an ordinary Android headerView, which Uniwind handles with a semantic class.AppearancePreviews.tsxused the JS palette only for two ordinaryTextnodes (line numbers / keywords in the settings code preview) — a real ordinary-screen escape hatch, not an interop boundary.Fix
ThreadTerminalRouteScreen.tsxentry.bg-header(the same semantic token home screens already use) and delete the theme read.text-icon-subtleand a conditionaltext-md-linkon the nested keyword spans (same tokens; the nested-Textconditional class pattern already ships inthread-search-match.tsx), keep only dynamic font metrics instyle, and dropAppearancePreviews.tsxfrom the allowlist so future JS palette reads there are linted.The allowlist now matches the actual
useUniwindThemeimporters 1:1 (24 = 24).Audit claim checked: "the rule fails on a clean tree because
src/lib/useUniwindTheme.tsis missing from the allowlist"Not reproducible; no entry is needed for that file.
apps/mobile/src/lib/useUniwindTheme.tsexists; it is the hook definition, not an importer. The rule reports imports of…/useUniwindTheme,useCSSVariable,useThemeColor, anddark:/light:literals — the definition file triggers none of these (it only importsAppearancePreferencesProvider).useUniwindThemeoutside the allowlist does error, confirming the rule and its overrides are actually wired.useUniwindThemeincludes the definition file; the remaining files are exactly the allowlisted importers. Adding an allowlist entry for the definition would be dead config, so none was added.Audit claim checked: "the allowlist includes ordinary screens" (ArchivedThreadsScreen, GitOverviewSheet, NewTaskDraftScreen, ThreadSettingsSheet, thread-list items ×2, HomeHeader, SettingsEnvironmentsRouteScreen, ConnectionsNewRouteScreen)
Each of these still has a genuine JS-color consumer that cannot take a
className; verified per file against current source:ThreadSwipeable backgroundColor→ RNGH/Reanimated swipeable container styles (thread-swipe-actions.tsx); v2 routes throughgetThreadListV2RowAppearanceand also feeds the swipeableScreenstyle/ScreenStackHeaderConfigcolors,SearchBar, SVG gradient stopsT3ComposerEditornativetextStyle/fallbackColorheaderTintColor)screenOptions(contentStyle,headerStyle,headerTintColor)tintColor→NativeHeaderToolbarextractschild.props.tintColorand hands it to the native header itemPartial class migrations for the row-background reads (e.g.
bg-thread-selectedonRowPressable) were considered and skipped: those files keep their allowlist entries because of the swipeable/navigation consumers, so the change would alter high-traffic selected-row visuals (interaction class vs inline style precedence inRowPressable) without removing any escape hatch. Not safely scoped for a lint-enforcement PR.Verification (non-visual; screenshots not applicable)
vp test runinoxlint-plugin-t3code: 50/50 pass (rule behavior unchanged).vpr lint, includes--report-unused-disable-directives): exit 0 before and after; zerono-mobile-uniwind-theme-escape-hatchesdiagnostics; baseline probed with a temp importer to confirm rule + allowlist are applied.apps/mobiletsc --noEmit: clean.bg-header,text-icon-subtle, andtext-md-linkresolve to the same--color-header,--color-icon-subtle, and--color-md-linktokens the removed JS reads returned.Model: callstack/Apex via pi
Summary by CodeRabbit