Repository navigation
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR introduces mobile light/dark theme support with persisted app-theme preferences, runtime theme context hooks, and cached themed style factories. Existing mobile screens and components are migrated from static color/style imports to active theme values. Terminal theme selections gain local persistence and WebView synchronization through app-chrome CSS variables. Built-in terminal palettes move into shared catalog modules consumed by both mobile and renderer code. Extensive tests cover theme resolution, style factories, palette invariants, storage behavior, terminal selection, and WebView rendering. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
mobile/src/components/pr-sidebar/MermaidDiagram.tsx (1)
105-119: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse
theme: 'base'so Mermaid applies the app palette colors.The resolved theme can be light, but Mermaid
themeVariablesonly customize thebasetheme; withtheme: 'dark'the injectedbackground,primaryColor,textColor, and related palette entries won’t reliably affect the diagram. Switch totheme: 'base'and keepdarkModedriven by the resolved mode if dark-mode behavior is still needed.🎨 Suggested fix
mermaid.initialize({ startOnLoad: false, - theme: 'dark', + theme: 'base', securityLevel: 'strict', darkMode: true, themeVariables: { background: '${colors.bgRaised}',mobile/app/h/[hostId]/tasks.tsx (1)
8427-8447: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winMissing
colorsdependency indisplayedEntriesmemo.
taskRepositoryMeta(item, reposById, colors)is called inside thisuseMemo(line 8434, a newly-added/changed call site), but the dependency array only lists[reposById, sortedItems, taskSort]—colorsis omitted. ThesortedItemsmemo directly above it, andlinearIssueSections/linearBoardSectionsfurther down, all correctly includecolorsin their deps for the same kind of call. Currently the reachable branches oftaskRepositoryMetafor non-Linear items don't usecolors, so the practical impact is limited today, but this is exactly the kind of stale-memo gap this PR is otherwise closing everywhere else, and it will silently produce stale section colors iftaskRepositoryMeta's fallback branch ever becomes reachable here (e.g. via future provider/type changes).🎨 Proposed fix
}, [reposById, sortedItems, taskSort])→
- }, [reposById, sortedItems, taskSort]) + }, [colors, reposById, sortedItems, taskSort])
🧹 Nitpick comments (8)
mobile/src/theme/theme-context.test.ts (1)
23-33: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the duplicated
suppressReactTestRendererDeprecationWarninghelper into a shared test utility.The same 10-line console.error-filtering helper is copy-pasted verbatim across two test files; the shared root cause is the lack of a common
react-test-renderertest utility for this migration's test suites.
mobile/src/theme/theme-context.test.ts#L23-L33: import the helper from a new shared test-utils module instead of defining it locally.mobile/src/terminal/TerminalWebView.test.ts#L41-L51: same — import instead of redefining.mobile/app/troubleshoot.tsx (1)
62-62: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winMemoize
getTroubleshootCommonIssues(colors)oncolors.This rebuilds the whole section list and its icon elements on every render, and this screen re-renders repeatedly during a diagnostics run (each
setChecks([...results])).useThemedStylesalready caches per palette; mirror that here.♻️ Proposed refactor
- const troubleshootCommonIssues = getTroubleshootCommonIssues(colors) + const troubleshootCommonIssues = useMemo(() => getTroubleshootCommonIssues(colors), [colors])Add
useMemoto the existingreactimport if it isn't already there.mobile/src/components/ConfirmModal.tsx (1)
109-113: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRoute
destructiveTextthrough a palette token.
'#fff'is the only non-token color left in this factory. White-on-statusRedis legible in both palettes so nothing breaks, but the codebase already has an on-color convention for this —colors.onMergeGreeninmobile/src/components/pr-sidebar/PRActionsSection.tsx— and using a token keeps the literal guard clean.♻️ Proposed refactor
destructiveText: { fontSize: typography.bodySize, fontWeight: '600', - color: '`#fff`' + color: colors.onStatusRed }Requires adding
onStatusRedto both palettes inmobile/src/theme/mobile-theme.ts.mobile/src/components/terminal-shortcut-settings-styles.ts (1)
93-103: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDelete button tint is a raw literal, not derived from theme.
deleteButton/deleteButtonPresseduse hardcodedrgba(239, 68, 68, ...)literals instead ofcolors.statusRed. Since this file is now theme-aware, tying the danger-button tint to the theme's red token would keep it consistent (and correctly contrasted) across light/dark palettes rather than a fixed value carried over from the pre-theming version.♻️ Suggested refactor
deleteButton: { width: 32, height: 32, borderRadius: 16, alignItems: 'center', justifyContent: 'center', - backgroundColor: 'rgba(239, 68, 68, 0.1)' + backgroundColor: colors.statusRed + '1A' // ~10% opacity }, deleteButtonPressed: { - backgroundColor: 'rgba(239, 68, 68, 0.2)' + backgroundColor: colors.statusRed + '33' // ~20% opacity }mobile/src/host/host-worktree-list-styles.ts (1)
132-136: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLast remaining color literal — route it through the palette.
Every other value here is tokenized;
'#fff'bypasses the palette contract (and the unapproved-literal guard the PR adds).colors.statusRedstays red in both palettes, so a token likecolors.onAccentpreserves output while keeping the file palette-driven.mobile/src/session/MobileNativeChatComposer.tsx (1)
360-361: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueStale comment after theming.
The circle is now
colors.textPrimary, which is dark in the light palette — "white … light circle" no longer describes the output. Rephrasing as an inverted pair (foreground-on-background) keeps it accurate for both palettes.♻️ Suggested comment update
- // White send affordance per design — dark arrow on a light circle. + // Inverted send affordance: bgBase arrow on a textPrimary circle. backgroundColor: colors.textPrimarymobile/src/session/MobileSessionHeaderIconButton.tsx (1)
3-4: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove the session style factories out of the route tree.
mobile/src/session/MobileSessionHeaderIconButton.tsximportscreateMobileSessionStylesfromapp/h/[hostId]/session/mobile-session-styles.ts, andmobile-session-styles.tsbundles app-side session style factories. Relocating the merged factory plus its component-owned sub-styless tomobile/src/session/keepsapp/route-only.mobile/src/tasks/tasks-screen-misc-styles.ts (1)
1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueFile name uses the vague term "misc".
This factory's implementation is fine, but the filename itself conflicts with the naming guideline for files/modules.
As per coding guidelines: "Do not use vague names such as
helpers,utils,common,misc, orshared-stufffor files, folders, or modules; use concrete domain names and split responsibilities when necessary."Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 83c83407-2ae3-4178-8ae1-7e7c35170562
📥 Commits
Reviewing files that changed from the base of the PR and between cafa958 and ae8e584f68c6cecaefae0dc5005235e2f281d40e.
📒 Files selected for processing (222)
mobile/app/_layout.tsxmobile/app/about.tsxmobile/app/browser-settings.tsxmobile/app/connection-log.tsxmobile/app/h/[hostId]/accounts-screen-styles.tsmobile/app/h/[hostId]/accounts.tsxmobile/app/h/[hostId]/edit.tsxmobile/app/h/[hostId]/index.tsxmobile/app/h/[hostId]/session/QuickCommandsTabButton.tsxmobile/app/h/[hostId]/session/[worktreeId].tsxmobile/app/h/[hostId]/session/mobile-session-command-input-styles.tsmobile/app/h/[hostId]/session/mobile-session-frame-styles.tsmobile/app/h/[hostId]/session/mobile-session-reader-styles.tsmobile/app/h/[hostId]/session/mobile-session-review-comment-styles.tsmobile/app/h/[hostId]/session/mobile-session-styles.tsmobile/app/h/[hostId]/tasks.tsxmobile/app/h/_layout.tsxmobile/app/index.tsxmobile/app/mobile-onboarding.tsxmobile/app/native-chat-settings.tsxmobile/app/notifications.tsxmobile/app/pair-confirm.tsxmobile/app/pair-scan.tsxmobile/app/pair.tsxmobile/app/settings.tsxmobile/app/terminal-settings.tsxmobile/app/troubleshoot.tsxmobile/app/voice-settings.tsxmobile/src/agent-history/MobileAgentSessionHistoryList.tsxmobile/src/agent-history/MobileAgentSessionHistoryPanel.tsxmobile/src/agent-history/agent-history-styles.tsmobile/src/agent-history/worktree-navigation-actions.tsmobile/src/browser/MobileBrowserKeyRow.tsxmobile/src/browser/MobileBrowserPane.tsxmobile/src/browser/MobileBrowserPointerModifiers.tsxmobile/src/browser/MobileBrowserToolbarIconButton.tsxmobile/src/browser/MobileBrowserViewModeSwitch.tsxmobile/src/components/AccountUsage.tsxmobile/src/components/ActionSheetModal.tsxmobile/src/components/AgentIcons.tsxmobile/src/components/AuthFailedBanner.tsxmobile/src/components/CodexResetCreditAction.tsxmobile/src/components/ConfirmModal.tsxmobile/src/components/ConnectionLog.tsxmobile/src/components/CustomKeyModal.tsxmobile/src/components/DragReorderList.tsxmobile/src/components/HostProtocolGate.tsxmobile/src/components/MobileAgentIcon.tsxmobile/src/components/MobileDictationSetupSheet.tsxmobile/src/components/MobileDiffReviewBody.tsxmobile/src/components/MobileDiffReviewDrawers.tsxmobile/src/components/MobileDiffReviewFileSummary.tsxmobile/src/components/MobileDiffReviewFooter.tsxmobile/src/components/MobileDiffReviewHeader.tsxmobile/src/components/MobileDiffReviewLine.tsxmobile/src/components/MobileDiffReviewScreenView.tsxmobile/src/components/MobileHostCard.tsxmobile/src/components/MobileHtmlPreview.tsxmobile/src/components/MobileMarkdown.tsxmobile/src/components/MobilePRSidebar.tsxmobile/src/components/MobilePrBasePicker.tsxmobile/src/components/MobileRepoIcon.tsxmobile/src/components/MobileRichMarkdownEditor.tsxmobile/src/components/MobileSearchField.tsxmobile/src/components/MobileSyntaxSegments.tsxmobile/src/components/NewWorkspaceFab.tsxmobile/src/components/NewWorktreeModal.tsxmobile/src/components/OrcaLogo.tsxmobile/src/components/PickerListDrawer.tsxmobile/src/components/PickerModal.tsxmobile/src/components/ProtocolBlockScreen.tsxmobile/src/components/RightDrawer.tsxmobile/src/components/SetupHookTrustDrawer.tsxmobile/src/components/SmartWorkspaceAdvancedFields.tsxmobile/src/components/SmartWorkspaceSourceDrawer.tsxmobile/src/components/SmartWorkspaceSourceField.tsxmobile/src/components/SmartWorkspaceSourceRow.tsxmobile/src/components/StatusDot.tsxmobile/src/components/TerminalShortcutSettings.tsxmobile/src/components/TextInputModal.tsxmobile/src/components/VoiceModelList.tsxmobile/src/components/WorkspaceDetailPlaceholder.tsxmobile/src/components/WorktreeAgentRow.tsxmobile/src/components/WorktreeListRow.tsxmobile/src/components/WorktreeMetaGlyphs.tsxmobile/src/components/bottom-drawer-styles.tsmobile/src/components/custom-key-modal-styles.tsmobile/src/components/mobile-diff-review-control-styles.tsmobile/src/components/mobile-diff-review-layout-styles.tsmobile/src/components/mobile-diff-review-screen-styles.tsmobile/src/components/mobile-markdown-styles.tsmobile/src/components/mobile-rich-markdown-editor-html.test.tsmobile/src/components/mobile-rich-markdown-editor-html.tsmobile/src/components/mounted-bottom-drawer.tsxmobile/src/components/pr-sidebar/CommentMarkdown.tsxmobile/src/components/pr-sidebar/MermaidDiagram.tsxmobile/src/components/pr-sidebar/MobileLinkPrForm.tsxmobile/src/components/pr-sidebar/MobilePrComposeForm.tsxmobile/src/components/pr-sidebar/MobilePrViewPanel.tsxmobile/src/components/pr-sidebar/PRActionsSection.tsxmobile/src/components/pr-sidebar/PRCheckDetail.tsxmobile/src/components/pr-sidebar/PRChecksSection.tsxmobile/src/components/pr-sidebar/PRCommentCard.tsxmobile/src/components/pr-sidebar/PRCommentComposer.tsxmobile/src/components/pr-sidebar/PRCommentsSection.test.tsmobile/src/components/pr-sidebar/PRCommentsSection.tsxmobile/src/components/pr-sidebar/PRConflictingFilesSection.tsxmobile/src/components/pr-sidebar/PRReviewersSection.tsxmobile/src/components/pr-sidebar/PRSection.tsxmobile/src/components/pr-sidebar/PRSidebarHeader.tsxmobile/src/components/pr-sidebar/PrSidebarCreateEmptyState.tsxmobile/src/components/pr-sidebar/ReviewerPickerDrawer.tsxmobile/src/components/pr-sidebar/mobile-pr-compose-form-styles.tsmobile/src/components/pr-sidebar/mobile-pr-sidebar-styles.tsmobile/src/components/pr-sidebar/pr-actions-styles.tsmobile/src/components/pr-sidebar/pr-ai-triage-styles.tsmobile/src/components/pr-sidebar/pr-comment-composer-styles.tsmobile/src/components/pr-sidebar/pr-comments-styles.tsmobile/src/components/pr-sidebar/pr-conflict-styles.tsmobile/src/components/pr-sidebar/pr-create-empty-state-styles.tsmobile/src/components/pr-sidebar/pr-sidebar-status-color.tsmobile/src/components/pr-state-token.test.tsmobile/src/components/smart-workspace-source-drawer-styles.tsmobile/src/components/terminal-shortcut-settings-styles.tsmobile/src/diagnostics/troubleshoot-common-issues.tsxmobile/src/dictation/voice-settings-styles.tsmobile/src/files/MobileFileExplorerPanel.tsxmobile/src/files/MobileFileMarkdownPreview.test.tsmobile/src/files/MobileFileMarkdownPreview.tsxmobile/src/files/MobileFilePreviewBody.tsxmobile/src/files/MobileFilePreviewEditableSource.tsxmobile/src/files/MobileFilePreviewScreen.tsxmobile/src/files/MobileFilePreviewSourceText.tsxmobile/src/files/mobile-file-explorer-row.tsxmobile/src/files/mobile-file-explorer-styles.tsmobile/src/files/mobile-file-preview-styles.tsmobile/src/host/host-screen-chrome-styles.tsmobile/src/host/host-screen-styles.tsmobile/src/host/host-worktree-list-styles.tsmobile/src/onboarding/MobileOnboardingPage.tsxmobile/src/onboarding/mobile-onboarding-screen.test.tsmobile/src/onboarding/mobile-onboarding-styles.tsmobile/src/session/MobileAgentWorkingIndicator.tsxmobile/src/session/MobileNativeChatAsk.tsxmobile/src/session/MobileNativeChatComposer.tsxmobile/src/session/MobileNativeChatMessage.tsxmobile/src/session/MobileNativeChatPermission.tsxmobile/src/session/MobileNativeChatQuestion.tsxmobile/src/session/MobileNativeChatView.tsxmobile/src/session/MobileSessionHeaderIconButton.tsxmobile/src/session/MobileSessionHeaderMoreActionsSheet.tsxmobile/src/session/MobileTerminalInputActions.tsxmobile/src/session/MobileTerminalLiveInputStatus.tsxmobile/src/session/QuickCommandEditorForm.tsxmobile/src/session/QuickCommandsList.tsxmobile/src/session/QuickCommandsSheet.tsxmobile/src/session/SessionDockColumn.tsxmobile/src/session/TerminalPaneView.test.tsmobile/src/session/TerminalPaneView.tsxmobile/src/session/mobile-native-chat-message-styles.tsmobile/src/session/mobile-native-chat-view-styles.tsmobile/src/source-control/MobileBranchDiffPreviewDrawer.tsxmobile/src/source-control/MobileCommitFailurePanel.tsxmobile/src/source-control/MobileGitHistoryList.tsxmobile/src/source-control/MobileSourceControlBranchCard.tsxmobile/src/source-control/MobileSourceControlContent.tsxmobile/src/source-control/MobileSourceControlCreatePrEntry.tsxmobile/src/source-control/MobileSourceControlFileRows.tsxmobile/src/source-control/MobileSourceControlHeader.tsxmobile/src/source-control/MobileSourceControlPanel.tsxmobile/src/source-control/MobileSourceControlPrChip.tsxmobile/src/source-control/MobileSourceControlSegments.tsxmobile/src/source-control/mobile-source-control-diff-styles.tsmobile/src/source-control/mobile-source-control-hub-styles.tsmobile/src/source-control/mobile-source-control-list-styles.tsmobile/src/source-control/mobile-source-control-screen-state.tsmobile/src/source-control/mobile-source-control-styles.tsmobile/src/storage/preferences.test.tsmobile/src/storage/preferences.tsmobile/src/storage/terminal-theme-preference.test.tsmobile/src/storage/terminal-theme-preference.tsmobile/src/tasks/tasks-screen-chrome-styles.tsmobile/src/tasks/tasks-screen-detail-styles.tsmobile/src/tasks/tasks-screen-form-styles.tsmobile/src/tasks/tasks-screen-list-styles.tsmobile/src/tasks/tasks-screen-misc-styles.tsmobile/src/tasks/tasks-screen-panel-styles.tsmobile/src/tasks/tasks-screen-styles.tsmobile/src/terminal/TerminalWebView.test.tsmobile/src/terminal/TerminalWebView.tsxmobile/src/terminal/terminal-theme-slot-selection.test.tsmobile/src/terminal/terminal-theme-slot-selection.tsmobile/src/terminal/terminal-webview-engine-error-state.tsxmobile/src/terminal/terminal-webview-frame-styles.tsmobile/src/terminal/terminal-webview-html-app-chrome.test.tsmobile/src/terminal/terminal-webview-html.tsmobile/src/terminal/terminal-webview-messages.tsmobile/src/terminal/terminal-webview-theme-injected.test.tsmobile/src/terminal/terminal-webview-theme-injected.tsmobile/src/terminal/use-mobile-terminal-theme.test.tsmobile/src/terminal/use-mobile-terminal-theme.tsmobile/src/theme/app-shell-theme.test.tsmobile/src/theme/mobile-theme-palette.test.tsmobile/src/theme/mobile-theme.tsmobile/src/theme/theme-context.test.tsmobile/src/theme/theme-context.tsxmobile/src/theme/themed-style-factories.test.tsmobile/src/theme/unthemed-color-imports.test.tssrc/renderer/src/lib/terminal-contrast-correction.test.tssrc/renderer/src/lib/terminal-theme.tssrc/renderer/src/lib/terminal-themes-data.tssrc/renderer/src/lib/terminal-themes/types.tssrc/shared/terminal-themes/catalog-merge.tssrc/shared/terminal-themes/classic.tssrc/shared/terminal-themes/defaults.tssrc/shared/terminal-themes/index.tssrc/shared/terminal-themes/popular-dark-core.tssrc/shared/terminal-themes/popular-dark-extended.tssrc/shared/terminal-themes/popular-dark.tssrc/shared/terminal-themes/popular-light.tssrc/shared/terminal-themes/terminal-theme-catalog.test.tssrc/shared/terminal-themes/types.ts
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
mobile/src/components/pr-sidebar/MermaidDiagram.tsx (1)
105-119: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse
theme: 'base'so Mermaid applies the app palette colors.The resolved theme can be light, but Mermaid
themeVariablesonly customize thebasetheme; withtheme: 'dark'the injectedbackground,primaryColor,textColor, and related palette entries won’t reliably affect the diagram. Switch totheme: 'base'and keepdarkModedriven by the resolved mode if dark-mode behavior is still needed.🎨 Suggested fix
mermaid.initialize({ startOnLoad: false, - theme: 'dark', + theme: 'base', securityLevel: 'strict', darkMode: true, themeVariables: { background: '${colors.bgRaised}',mobile/app/h/[hostId]/tasks.tsx (1)
8427-8447: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winMissing
colorsdependency indisplayedEntriesmemo.
taskRepositoryMeta(item, reposById, colors)is called inside thisuseMemo(line 8434, a newly-added/changed call site), but the dependency array only lists[reposById, sortedItems, taskSort]—colorsis omitted. ThesortedItemsmemo directly above it, andlinearIssueSections/linearBoardSectionsfurther down, all correctly includecolorsin their deps for the same kind of call. Currently the reachable branches oftaskRepositoryMetafor non-Linear items don't usecolors, so the practical impact is limited today, but this is exactly the kind of stale-memo gap this PR is otherwise closing everywhere else, and it will silently produce stale section colors iftaskRepositoryMeta's fallback branch ever becomes reachable here (e.g. via future provider/type changes).🎨 Proposed fix
}, [reposById, sortedItems, taskSort])→
- }, [reposById, sortedItems, taskSort]) + }, [colors, reposById, sortedItems, taskSort])
🧹 Nitpick comments (8)
mobile/src/theme/theme-context.test.ts (1)
23-33: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the duplicated
suppressReactTestRendererDeprecationWarninghelper into a shared test utility.The same 10-line console.error-filtering helper is copy-pasted verbatim across two test files; the shared root cause is the lack of a common
react-test-renderertest utility for this migration's test suites.
mobile/src/theme/theme-context.test.ts#L23-L33: import the helper from a new shared test-utils module instead of defining it locally.mobile/src/terminal/TerminalWebView.test.ts#L41-L51: same — import instead of redefining.mobile/app/troubleshoot.tsx (1)
62-62: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winMemoize
getTroubleshootCommonIssues(colors)oncolors.This rebuilds the whole section list and its icon elements on every render, and this screen re-renders repeatedly during a diagnostics run (each
setChecks([...results])).useThemedStylesalready caches per palette; mirror that here.♻️ Proposed refactor
- const troubleshootCommonIssues = getTroubleshootCommonIssues(colors) + const troubleshootCommonIssues = useMemo(() => getTroubleshootCommonIssues(colors), [colors])Add
useMemoto the existingreactimport if it isn't already there.mobile/src/components/ConfirmModal.tsx (1)
109-113: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRoute
destructiveTextthrough a palette token.
'#fff'is the only non-token color left in this factory. White-on-statusRedis legible in both palettes so nothing breaks, but the codebase already has an on-color convention for this —colors.onMergeGreeninmobile/src/components/pr-sidebar/PRActionsSection.tsx— and using a token keeps the literal guard clean.♻️ Proposed refactor
destructiveText: { fontSize: typography.bodySize, fontWeight: '600', - color: '`#fff`' + color: colors.onStatusRed }Requires adding
onStatusRedto both palettes inmobile/src/theme/mobile-theme.ts.mobile/src/components/terminal-shortcut-settings-styles.ts (1)
93-103: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDelete button tint is a raw literal, not derived from theme.
deleteButton/deleteButtonPresseduse hardcodedrgba(239, 68, 68, ...)literals instead ofcolors.statusRed. Since this file is now theme-aware, tying the danger-button tint to the theme's red token would keep it consistent (and correctly contrasted) across light/dark palettes rather than a fixed value carried over from the pre-theming version.♻️ Suggested refactor
deleteButton: { width: 32, height: 32, borderRadius: 16, alignItems: 'center', justifyContent: 'center', - backgroundColor: 'rgba(239, 68, 68, 0.1)' + backgroundColor: colors.statusRed + '1A' // ~10% opacity }, deleteButtonPressed: { - backgroundColor: 'rgba(239, 68, 68, 0.2)' + backgroundColor: colors.statusRed + '33' // ~20% opacity }mobile/src/host/host-worktree-list-styles.ts (1)
132-136: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLast remaining color literal — route it through the palette.
Every other value here is tokenized;
'#fff'bypasses the palette contract (and the unapproved-literal guard the PR adds).colors.statusRedstays red in both palettes, so a token likecolors.onAccentpreserves output while keeping the file palette-driven.mobile/src/session/MobileNativeChatComposer.tsx (1)
360-361: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueStale comment after theming.
The circle is now
colors.textPrimary, which is dark in the light palette — "white … light circle" no longer describes the output. Rephrasing as an inverted pair (foreground-on-background) keeps it accurate for both palettes.♻️ Suggested comment update
- // White send affordance per design — dark arrow on a light circle. + // Inverted send affordance: bgBase arrow on a textPrimary circle. backgroundColor: colors.textPrimarymobile/src/session/MobileSessionHeaderIconButton.tsx (1)
3-4: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove the session style factories out of the route tree.
mobile/src/session/MobileSessionHeaderIconButton.tsximportscreateMobileSessionStylesfromapp/h/[hostId]/session/mobile-session-styles.ts, andmobile-session-styles.tsbundles app-side session style factories. Relocating the merged factory plus its component-owned sub-styless tomobile/src/session/keepsapp/route-only.mobile/src/tasks/tasks-screen-misc-styles.ts (1)
1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueFile name uses the vague term "misc".
This factory's implementation is fine, but the filename itself conflicts with the naming guideline for files/modules.
As per coding guidelines: "Do not use vague names such as
helpers,utils,common,misc, orshared-stufffor files, folders, or modules; use concrete domain names and split responsibilities when necessary."Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 83c83407-2ae3-4178-8ae1-7e7c35170562
📥 Commits
Reviewing files that changed from the base of the PR and between cafa958 and ae8e584f68c6cecaefae0dc5005235e2f281d40e.
📒 Files selected for processing (222)
mobile/app/_layout.tsxmobile/app/about.tsxmobile/app/browser-settings.tsxmobile/app/connection-log.tsxmobile/app/h/[hostId]/accounts-screen-styles.tsmobile/app/h/[hostId]/accounts.tsxmobile/app/h/[hostId]/edit.tsxmobile/app/h/[hostId]/index.tsxmobile/app/h/[hostId]/session/QuickCommandsTabButton.tsxmobile/app/h/[hostId]/session/[worktreeId].tsxmobile/app/h/[hostId]/session/mobile-session-command-input-styles.tsmobile/app/h/[hostId]/session/mobile-session-frame-styles.tsmobile/app/h/[hostId]/session/mobile-session-reader-styles.tsmobile/app/h/[hostId]/session/mobile-session-review-comment-styles.tsmobile/app/h/[hostId]/session/mobile-session-styles.tsmobile/app/h/[hostId]/tasks.tsxmobile/app/h/_layout.tsxmobile/app/index.tsxmobile/app/mobile-onboarding.tsxmobile/app/native-chat-settings.tsxmobile/app/notifications.tsxmobile/app/pair-confirm.tsxmobile/app/pair-scan.tsxmobile/app/pair.tsxmobile/app/settings.tsxmobile/app/terminal-settings.tsxmobile/app/troubleshoot.tsxmobile/app/voice-settings.tsxmobile/src/agent-history/MobileAgentSessionHistoryList.tsxmobile/src/agent-history/MobileAgentSessionHistoryPanel.tsxmobile/src/agent-history/agent-history-styles.tsmobile/src/agent-history/worktree-navigation-actions.tsmobile/src/browser/MobileBrowserKeyRow.tsxmobile/src/browser/MobileBrowserPane.tsxmobile/src/browser/MobileBrowserPointerModifiers.tsxmobile/src/browser/MobileBrowserToolbarIconButton.tsxmobile/src/browser/MobileBrowserViewModeSwitch.tsxmobile/src/components/AccountUsage.tsxmobile/src/components/ActionSheetModal.tsxmobile/src/components/AgentIcons.tsxmobile/src/components/AuthFailedBanner.tsxmobile/src/components/CodexResetCreditAction.tsxmobile/src/components/ConfirmModal.tsxmobile/src/components/ConnectionLog.tsxmobile/src/components/CustomKeyModal.tsxmobile/src/components/DragReorderList.tsxmobile/src/components/HostProtocolGate.tsxmobile/src/components/MobileAgentIcon.tsxmobile/src/components/MobileDictationSetupSheet.tsxmobile/src/components/MobileDiffReviewBody.tsxmobile/src/components/MobileDiffReviewDrawers.tsxmobile/src/components/MobileDiffReviewFileSummary.tsxmobile/src/components/MobileDiffReviewFooter.tsxmobile/src/components/MobileDiffReviewHeader.tsxmobile/src/components/MobileDiffReviewLine.tsxmobile/src/components/MobileDiffReviewScreenView.tsxmobile/src/components/MobileHostCard.tsxmobile/src/components/MobileHtmlPreview.tsxmobile/src/components/MobileMarkdown.tsxmobile/src/components/MobilePRSidebar.tsxmobile/src/components/MobilePrBasePicker.tsxmobile/src/components/MobileRepoIcon.tsxmobile/src/components/MobileRichMarkdownEditor.tsxmobile/src/components/MobileSearchField.tsxmobile/src/components/MobileSyntaxSegments.tsxmobile/src/components/NewWorkspaceFab.tsxmobile/src/components/NewWorktreeModal.tsxmobile/src/components/OrcaLogo.tsxmobile/src/components/PickerListDrawer.tsxmobile/src/components/PickerModal.tsxmobile/src/components/ProtocolBlockScreen.tsxmobile/src/components/RightDrawer.tsxmobile/src/components/SetupHookTrustDrawer.tsxmobile/src/components/SmartWorkspaceAdvancedFields.tsxmobile/src/components/SmartWorkspaceSourceDrawer.tsxmobile/src/components/SmartWorkspaceSourceField.tsxmobile/src/components/SmartWorkspaceSourceRow.tsxmobile/src/components/StatusDot.tsxmobile/src/components/TerminalShortcutSettings.tsxmobile/src/components/TextInputModal.tsxmobile/src/components/VoiceModelList.tsxmobile/src/components/WorkspaceDetailPlaceholder.tsxmobile/src/components/WorktreeAgentRow.tsxmobile/src/components/WorktreeListRow.tsxmobile/src/components/WorktreeMetaGlyphs.tsxmobile/src/components/bottom-drawer-styles.tsmobile/src/components/custom-key-modal-styles.tsmobile/src/components/mobile-diff-review-control-styles.tsmobile/src/components/mobile-diff-review-layout-styles.tsmobile/src/components/mobile-diff-review-screen-styles.tsmobile/src/components/mobile-markdown-styles.tsmobile/src/components/mobile-rich-markdown-editor-html.test.tsmobile/src/components/mobile-rich-markdown-editor-html.tsmobile/src/components/mounted-bottom-drawer.tsxmobile/src/components/pr-sidebar/CommentMarkdown.tsxmobile/src/components/pr-sidebar/MermaidDiagram.tsxmobile/src/components/pr-sidebar/MobileLinkPrForm.tsxmobile/src/components/pr-sidebar/MobilePrComposeForm.tsxmobile/src/components/pr-sidebar/MobilePrViewPanel.tsxmobile/src/components/pr-sidebar/PRActionsSection.tsxmobile/src/components/pr-sidebar/PRCheckDetail.tsxmobile/src/components/pr-sidebar/PRChecksSection.tsxmobile/src/components/pr-sidebar/PRCommentCard.tsxmobile/src/components/pr-sidebar/PRCommentComposer.tsxmobile/src/components/pr-sidebar/PRCommentsSection.test.tsmobile/src/components/pr-sidebar/PRCommentsSection.tsxmobile/src/components/pr-sidebar/PRConflictingFilesSection.tsxmobile/src/components/pr-sidebar/PRReviewersSection.tsxmobile/src/components/pr-sidebar/PRSection.tsxmobile/src/components/pr-sidebar/PRSidebarHeader.tsxmobile/src/components/pr-sidebar/PrSidebarCreateEmptyState.tsxmobile/src/components/pr-sidebar/ReviewerPickerDrawer.tsxmobile/src/components/pr-sidebar/mobile-pr-compose-form-styles.tsmobile/src/components/pr-sidebar/mobile-pr-sidebar-styles.tsmobile/src/components/pr-sidebar/pr-actions-styles.tsmobile/src/components/pr-sidebar/pr-ai-triage-styles.tsmobile/src/components/pr-sidebar/pr-comment-composer-styles.tsmobile/src/components/pr-sidebar/pr-comments-styles.tsmobile/src/components/pr-sidebar/pr-conflict-styles.tsmobile/src/components/pr-sidebar/pr-create-empty-state-styles.tsmobile/src/components/pr-sidebar/pr-sidebar-status-color.tsmobile/src/components/pr-state-token.test.tsmobile/src/components/smart-workspace-source-drawer-styles.tsmobile/src/components/terminal-shortcut-settings-styles.tsmobile/src/diagnostics/troubleshoot-common-issues.tsxmobile/src/dictation/voice-settings-styles.tsmobile/src/files/MobileFileExplorerPanel.tsxmobile/src/files/MobileFileMarkdownPreview.test.tsmobile/src/files/MobileFileMarkdownPreview.tsxmobile/src/files/MobileFilePreviewBody.tsxmobile/src/files/MobileFilePreviewEditableSource.tsxmobile/src/files/MobileFilePreviewScreen.tsxmobile/src/files/MobileFilePreviewSourceText.tsxmobile/src/files/mobile-file-explorer-row.tsxmobile/src/files/mobile-file-explorer-styles.tsmobile/src/files/mobile-file-preview-styles.tsmobile/src/host/host-screen-chrome-styles.tsmobile/src/host/host-screen-styles.tsmobile/src/host/host-worktree-list-styles.tsmobile/src/onboarding/MobileOnboardingPage.tsxmobile/src/onboarding/mobile-onboarding-screen.test.tsmobile/src/onboarding/mobile-onboarding-styles.tsmobile/src/session/MobileAgentWorkingIndicator.tsxmobile/src/session/MobileNativeChatAsk.tsxmobile/src/session/MobileNativeChatComposer.tsxmobile/src/session/MobileNativeChatMessage.tsxmobile/src/session/MobileNativeChatPermission.tsxmobile/src/session/MobileNativeChatQuestion.tsxmobile/src/session/MobileNativeChatView.tsxmobile/src/session/MobileSessionHeaderIconButton.tsxmobile/src/session/MobileSessionHeaderMoreActionsSheet.tsxmobile/src/session/MobileTerminalInputActions.tsxmobile/src/session/MobileTerminalLiveInputStatus.tsxmobile/src/session/QuickCommandEditorForm.tsxmobile/src/session/QuickCommandsList.tsxmobile/src/session/QuickCommandsSheet.tsxmobile/src/session/SessionDockColumn.tsxmobile/src/session/TerminalPaneView.test.tsmobile/src/session/TerminalPaneView.tsxmobile/src/session/mobile-native-chat-message-styles.tsmobile/src/session/mobile-native-chat-view-styles.tsmobile/src/source-control/MobileBranchDiffPreviewDrawer.tsxmobile/src/source-control/MobileCommitFailurePanel.tsxmobile/src/source-control/MobileGitHistoryList.tsxmobile/src/source-control/MobileSourceControlBranchCard.tsxmobile/src/source-control/MobileSourceControlContent.tsxmobile/src/source-control/MobileSourceControlCreatePrEntry.tsxmobile/src/source-control/MobileSourceControlFileRows.tsxmobile/src/source-control/MobileSourceControlHeader.tsxmobile/src/source-control/MobileSourceControlPanel.tsxmobile/src/source-control/MobileSourceControlPrChip.tsxmobile/src/source-control/MobileSourceControlSegments.tsxmobile/src/source-control/mobile-source-control-diff-styles.tsmobile/src/source-control/mobile-source-control-hub-styles.tsmobile/src/source-control/mobile-source-control-list-styles.tsmobile/src/source-control/mobile-source-control-screen-state.tsmobile/src/source-control/mobile-source-control-styles.tsmobile/src/storage/preferences.test.tsmobile/src/storage/preferences.tsmobile/src/storage/terminal-theme-preference.test.tsmobile/src/storage/terminal-theme-preference.tsmobile/src/tasks/tasks-screen-chrome-styles.tsmobile/src/tasks/tasks-screen-detail-styles.tsmobile/src/tasks/tasks-screen-form-styles.tsmobile/src/tasks/tasks-screen-list-styles.tsmobile/src/tasks/tasks-screen-misc-styles.tsmobile/src/tasks/tasks-screen-panel-styles.tsmobile/src/tasks/tasks-screen-styles.tsmobile/src/terminal/TerminalWebView.test.tsmobile/src/terminal/TerminalWebView.tsxmobile/src/terminal/terminal-theme-slot-selection.test.tsmobile/src/terminal/terminal-theme-slot-selection.tsmobile/src/terminal/terminal-webview-engine-error-state.tsxmobile/src/terminal/terminal-webview-frame-styles.tsmobile/src/terminal/terminal-webview-html-app-chrome.test.tsmobile/src/terminal/terminal-webview-html.tsmobile/src/terminal/terminal-webview-messages.tsmobile/src/terminal/terminal-webview-theme-injected.test.tsmobile/src/terminal/terminal-webview-theme-injected.tsmobile/src/terminal/use-mobile-terminal-theme.test.tsmobile/src/terminal/use-mobile-terminal-theme.tsmobile/src/theme/app-shell-theme.test.tsmobile/src/theme/mobile-theme-palette.test.tsmobile/src/theme/mobile-theme.tsmobile/src/theme/theme-context.test.tsmobile/src/theme/theme-context.tsxmobile/src/theme/themed-style-factories.test.tsmobile/src/theme/unthemed-color-imports.test.tssrc/renderer/src/lib/terminal-contrast-correction.test.tssrc/renderer/src/lib/terminal-theme.tssrc/renderer/src/lib/terminal-themes-data.tssrc/renderer/src/lib/terminal-themes/types.tssrc/shared/terminal-themes/catalog-merge.tssrc/shared/terminal-themes/classic.tssrc/shared/terminal-themes/defaults.tssrc/shared/terminal-themes/index.tssrc/shared/terminal-themes/popular-dark-core.tssrc/shared/terminal-themes/popular-dark-extended.tssrc/shared/terminal-themes/popular-dark.tssrc/shared/terminal-themes/popular-light.tssrc/shared/terminal-themes/terminal-theme-catalog.test.tssrc/shared/terminal-themes/types.ts
🛑 Comments failed to post (7)
mobile/app/index.tsx (1)
1346-1353: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Dark-only white-alpha overlays survived the palette migration in
createHomeScreenStyles. Two chip surfaces still hardcodergba(255,255,255,0.04), which is effectively invisible over a lightbgPanel/bgBase, so both lose their surface separation in light mode — the same class of contrast defect this PR fixed forstatCardviacolors.statTileSurface.
mobile/app/index.tsx#L1346-L1353: replacequickActionIcon.backgroundColorwithcolors.bgRaisedto match the siblingresumeIcon/taskHomeIconchips.mobile/app/index.tsx#L1419-L1429: replacestepNum.backgroundColorwith the same palette token so onboarding step chips stay visible.📍 Affects 1 file
mobile/app/index.tsx#L1346-L1353(this comment)mobile/app/index.tsx#L1419-L1429mobile/src/browser/MobileBrowserPane.tsx (1)
1561-1588: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Hardcoded dark scrims won't follow the light palette.
overlayanddialogOverlaykeeprgba(13, 15, 24, …)inside a now theme-parameterized factory, so the busy/error overlay and dialog backdrop stay dark-tinted in light mode. Consider a palette-provided scrim token.mobile/src/components/mobile-rich-markdown-editor-html.ts (1)
8-8: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Pass the resolved color scheme into the HTML builder.
The builder now accepts light palettes, but Line 16 still hardcodes
color-scheme: dark; WebView user-agent controls and scrollbars can remain dark in light mode. Accept the resolved app scheme and interpolate it here.Proposed fix
-export function buildMobileRichMarkdownEditorHtml(colors: ThemeColors): string { +export function buildMobileRichMarkdownEditorHtml( + colors: ThemeColors, + colorScheme: 'light' | 'dark' +): string { ... - color-scheme: dark; + color-scheme: ${colorScheme};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.export function buildMobileRichMarkdownEditorHtml( colors: ThemeColors, colorScheme: 'light' | 'dark' ): string {mobile/src/components/MobileRichMarkdownEditor.tsx (1)
117-123: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== locate file ==" fd -a 'MobileRichMarkdownEditor\.tsx$' . || true echo "== file outline/size ==" if [ -f mobile/src/components/MobileRichMarkdownEditor.tsx ]; then wc -l mobile/src/components/MobileRichMarkdownEditor.tsx ast-grep outline mobile/src/components/MobileRichMarkdownEditor.tsx || true fi echo "== relevant snippets ==" sed -n '1,180p' mobile/src/components/MobileRichMarkdownEditor.tsx echo "---- 230-295 ----" sed -n '230,295p' mobile/src/components/MobileRichMarkdownEditor.tsx echo "== related helpers/colors/theme usage ==" rg -n "buildMobileRichMarkdownEditorHtml|mobileRichMarkdownEditorStyles|useThemedStyles|useTheme|MobileRichMarkdownEditorStyles|EDITOR_DOCUMENT_URL|applyContent|change" mobile/src -S || trueRepository: stablyai/orca
Length of output: 50369
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== editor HTML change/message handlers ==" sed -n '480,575p' mobile/src/components/mobile-rich-markdown-editor-html.ts echo "== terminal theme/live approach snippets ==" sed -n '40,65p' mobile/src/terminal/TerminalWebView.tsx echo "---- TerminalWebView live text style/theme sections ----" sed -n '220,285p' mobile/src/terminal/TerminalWebView.tsx echo "== inspect handle/change implementation and generation tracking ----" sed -n '170,225p' mobile/src/components/MobileRichMarkdownEditor.tsx sed -n '540,572p' mobile/src/components/mobile-rich-markdown-editor-html.ts echo "== diff for relevant changed files/stat ----" git diff --stat HEAD~1..HEAD mobile/src/components/MobileRichMarkdownEditor.tsx mobile/src/components/mobile-rich-markdown-editor-html.ts 2>/dev/null || git diff --name-only HEAD 2>/dev/null | rg 'MobileRichMarkdownEditor|mobile-rich-markdown-editor' || trueRepository: stablyai/orca
Length of output: 11653
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== check dependency versions/comments for react-native-webview behavior context ==" fd -a -i 'package.json$' . | head -20 | xargs -r -n1 sh -c 'echo "--- $0"; rg -n "react-native-webview|react-native" "$0" || true' echo "== AST-style read-only probe: does html useMemo depend only on colors? ==" python3 - <<'PY' from pathlib import Path import re p = Path('mobile/src/components/MobileRichMarkdownEditor.tsx') s = p.read_text() m = re.search(r'const\s+html\s*=\s*useMemo\s*\(\s*\(\)\s*=>\s*buildMobileRichMarkdownEditorHtml\(colors\),\s*\[([^\]]+)\]\)', s) print(f'html_useMemo_match={bool(m)}') if m: print(f'html_dependencies={m.group(1).strip()}') source_html = re.search(r'<WebView[\s\S]*?source=\{\{\s*html[,\s\}]*', s) print(f'webview_source_uses_html={bool(source_html)}') change_handle = re.search(r"editorMessage\.type === 'change' &&\s*([^}]+)}", re.search(r'if \(message', s).group(0) if re.search(r'if \(message', s) else '') print(f'sample_change_handler={change_handle.group(1).strip() if change_handle else change_handle}') handleMessage_idx = s.find('const handleMessage = useCallback') print(f'has_handleMessage={handleMessage_idx >= 0}') print(f'handles_change_type={s[handleMessage_idx:handleMessage_idx+1400].find(\"editorMessage.type === 'change'\") >= 0}') PYRepository: stablyai/orca
Length of output: 1367
🌐 Web query:
react-native-webview 13 source prop html source source.html prop reload source change documentation💡 Result:
In the react-native-webview library, the source prop is the standard way to provide content to the WebView [1][2]. It accepts an object that can contain either a uri (for remote or local web pages) or html (for static content) [1][3]. When using static HTML, the source object structure is: source={{ html: '...', baseUrl: '...' }} Using static HTML requires setting the originWhitelist prop to ['*'] [1][4]. Regarding source changes and reloading: 1. Standard Behavior: Passing a new source object (e.g., changing the uri or html string) typically triggers the WebView to update and reload the new content [5]. 2. Reloading the Same Source: If you need to reload the WebView while keeping the same uri or html content, simply updating the source prop may not trigger a reload, as the component may perform a shallow prop comparison and determine that no meaningful change occurred [6][7]. 3. Forcing a Reload: A common pattern used by the community to force a reload of the same content is to add a dummy or "fictive" property to the source object, such as forceReload: Math.random [6][7]. When this property changes, React Native detects a change in the source prop, which triggers the underlying native setSource method to re-evaluate the source, effectively reloading the view [6][7]. Note that the standalone html prop is deprecated; the source prop should be used instead [2][8].
Citations:
- 1: https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md
- 2: https://github.com/react-native-webview/react-native-webview/blob/74872a1f02c43e425f19739b1b25f5fbe614ba1f/docs/Reference.md
- 3: https://deepwiki.com/react-native-webview/react-native-webview/3.1-props-reference
- 4: https://github.com/react-native-webview/react-native-webview/blob/HEAD/docs/Guide.md
- 5: https://github.com/react-native-webview/react-native-webview/blob/v10.1.0/docs/Guide.md
- 6: react-native-webview/react-native-webview#350
- 7: https://stackoverflow.com/questions/54738360/how-to-refresh-react-native-webview-to-initial-url
- 8: https://archive.reactnative.dev/docs/webview
🌐 Web query:
react-native-webview 13.16 source html change injectJavaScript contentEditable race💡 Result:
In react-native-webview, race conditions involving injectJavaScript, injectedJavaScriptBeforeContentLoaded, and the initial rendering of contentEditable fields are common, especially on Android or when using the New Architecture [1][2]. The root cause is typically that the WebView's HTML content may begin loading and executing its own scripts before the WebView's injection props have completed or even initialized [1][3]. When you attempt to set focus or manipulate a contentEditable field via injectJavaScript or beforeContentLoaded, the target DOM element may not yet exist, or the bridge required for the injection may not be ready [1]. Recommended strategies to resolve these race conditions include: 1. Inline Script Injection: For critical initialization, embedding JavaScript directly into the source HTML string (e.g., using a useMemo hook to generate the HTML) is the most reliable method [1]. Inline scripts execute synchronously during HTML parsing, guaranteeing they run before deferred web scripts [1]. 2. Polling with an Interval: If you must use injection props, implement a polling mechanism in your injected JavaScript that waits for the necessary DOM elements (like your contentEditable field) or specific flags to exist before executing your logic [4]. 3. InjectedJavaScriptObject: Use the injectedJavaScriptObject prop instead of beforeContentLoaded when passing configuration data to the webview, as it is designed to be more reliable for sharing data prior to page load completion [5][6]. 4. Avoid Reliance on Timing: Ensure your web-side code is designed to handle "late" injection. For example, rather than the React Native side trying to force an initialization, have the web-side code poll for a signal from React Native or wait for a custom window event that indicates the environment is ready [1][7]. If you are experiencing issues specifically with contentEditable focus, ensure the WebView is fully loaded (via onLoadEnd) before triggering a focus-related injectJavaScript call, as focus attempts on an unmounted or unready element will fail silently [8][4].
Citations:
- 1: 10play/10tap-editor#343
- 2: https://github.com/react-native-webview/react-native-webview/pull/3929/changes
- 3: react-native-webview/react-native-webview#1609
- 4: https://stackoverflow.com/questions/33818641/inject-javascript-or-css-into-react-native-webview-before-page-renders
- 5: https://github.com/react-native-webview/react-native-webview/blob/master/docs/Guide.md
- 6: https://deepwiki.com/react-native-webview/react-native-webview/4.2-communication-guide
- 7: react-native-webview/react-native-webview#3377
- 8: https://github.com/react-native-webview/react-native-webview/blob/74872a1f02c43e425f19739b1b25f5fbe614ba1f/docs/Reference.md
🌐 Web query:
github react-native-async webview source props didUpdate sourceDidUpdate html💡 Result:
In react-native-webview, there is no internal "sourceDidUpdate" lifecycle method or event explicitly exposed to users for handling source prop updates [1][2]. When the
sourceprop changes, theWebViewcomponent handles the update by triggering a re-render and re-loading the content [3]. Key technical points regarding source updates and HTML: 1. How it works: When you update thesourceprop (whether switching from a URI to HTML, or updating the HTML string itself), the underlying native WebView is instructed to navigate to the new URI or load the new HTML string [1][3]. Passing a new static HTML source to thesourceprop will cause the WebView to re-render [3]. 2. No "sourceDidUpdate" event: There is no native or JS-level "sourceDidUpdate" callback [2]. If you need to perform actions after a source change, you should rely on existing loading events: -onLoadingStart: Fired when the WebView begins loading content [2][4]. -onLoadingFinish: Fired when the WebView completes the load [2][4]. 3. HTML Source Requirements: When loading static HTML via thesourceprop, you must set theoriginWhitelistprop to['*']to ensure the content loads correctly [1][3]. 4. Implementation Note: If you encounter issues where the WebView does not seem to update correctly or if you are facing navigation inconsistencies (a common report when using HTML sources), ensure your component structure is using React state correctly to pass the updatedsourceobject [5][6]. You do not need to manually trigger native updates; updating the state that feeds thesourceprop is the standard, authoritative approach [5][3]. Top results: [1][2][3]Citations:
- 1: https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md
- 2: https://github.com/react-native-webview/react-native-webview/blob/1ddfe705/src/WebViewTypes.ts
- 3: https://github.com/react-native-webview/react-native-webview/blob/master/docs/Guide.md
- 4: https://github.com/react-native-webview/react-native-webview/blob/1ddfe705/src/RNCWebViewNativeComponent.ts
- 5: https://github.com/react-native-webview/react-native-webview/blob/HEAD/docs/Guide.md
- 6: react-native-webview/react-native-webview#3551
Avoid rebuilding the editor HTML for theme changes.
htmlis recreated whenevercolorschanges and passed throughsource, so React Native WebView reloads the document. A theme toggle during editing can reset the contentEditable surface and repaint it from the last-knowncontentonready, losing keystrokes not yet committed throughchange. Keep the WebView mounted and push theme colors via messages/injectJavaScript like the terminal WebView does.mobile/src/host/host-screen-chrome-styles.ts (1)
4-5: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Remove migration-history comments.
They do not document runtime behavior and are unnecessary here. As per coding guidelines, comments must be concise, limited to non-obvious information, and preferably one line.
Source: Coding guidelines
mobile/src/source-control/MobileSourceControlFileRows.tsx (1)
29-31: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash set -eu ast-grep outline mobile/src/source-control/MobileSourceControlFileRows.tsx --items all rg -n -C 6 'makeRenderFileRow|return function FileRow|useTheme\(|useThemedStyles\(' \ mobile/src/source-control/MobileSourceControlFileRows.tsxRepository: stablyai/orca
Length of output: 2357
🏁 Script executed:
#!/bin/bash set -eu echo "== Relevant MobileSourceControlFileRows sections ==" sed -n '21,130p' mobile/src/source-control/MobileSourceControlFileRows.tsx printf '\n' rg -n -C 4 'SectionList|makeRenderFileRow|SectionListRenderItem<function renderItem|renderItem=' mobile/src/source-control -S echo echo "== React Native SectionList renderItem docs/source in package metadata if present ==" fd -a 'node_modules/react-native' . | head -5 || true if [ -d node_modules/react-native ]; then rg -n "renderItem|type SectionListRenderItem" node_modules/react-native -S | head -40 else echo "node_modules/react-native not present" fiRepository: stablyai/orca
Length of output: 11899
Render the row from a JSX component.
SectionListcallsrenderItemwith each item as a callback, soFileRowis not mounted as a function component. Calling hooks there can throw an invalid-hook-call error when rows render. Return<ThemedFileRow item={item} />frommakeRenderFileRow, and moveuseTheme/useThemedStylesplus the row JSX intoThemedFileRow.src/shared/terminal-themes/catalog-merge.ts (1)
6-13: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Handle prototype-sensitive theme IDs consistently.
Both boundaries treat ordinary-object prototype properties as catalog data, which can silently drop or incorrectly accept IDs such as
__proto__,constructor, andtoString.
src/shared/terminal-themes/catalog-merge.ts#L6-L13: build the merged catalog withObject.create(null)so every string key is stored as data.src/shared/terminal-themes/index.ts#L24-L25: return a palette only when the catalog has the requested key as an own property.📍 Affects 2 files
src/shared/terminal-themes/catalog-merge.ts#L6-L13(this comment)src/shared/terminal-themes/index.ts#L24-L25
ae8e584 to
566a3fe
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (8)
mobile/src/terminal/terminal-webview-html-app-chrome.test.ts (1)
7-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winLine 8 is a tautology.
expect(X).toBe(X)on the same binding always passes and proves nothing about module-constant stability. To actually assert stable identity, re-import the module and compare references.♻️ Suggested change
expect(XTERM_WEBVIEW_SOURCE).toEqual({ html: XTERM_HTML }) - expect(XTERM_WEBVIEW_SOURCE).toBe(XTERM_WEBVIEW_SOURCE) + const reimported = await import('./terminal-webview-html') + expect(reimported.XTERM_WEBVIEW_SOURCE).toBe(XTERM_WEBVIEW_SOURCE)mobile/src/theme/themed-style-factories.test.ts (3)
111-249: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftPositional destructuring of 70 modules is a silent-drift hazard. Adding an import without inserting the matching binding at the same index shifts every subsequent name, and the registry would then assert the wrong factory under a correct-looking name (or
undefined, failing opaquely). Consider keying modules by path instead, e.g. build an object ofimport()promises and readmods['../components/RightDrawer'].createRightDrawerStyles, so position no longer matters.
522-531: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winThe coverage ratchet only detects
export constfactories. A factory declared asexport function createFooStyles(colors: ThemeColors)(or re-exported) is invisible tolistDeclaredFactories, so it can land without appearing in the registry or either allowlist — exactly the silent gap the comment at Line 461 guards against. Broaden the pattern.🛡️ Suggested change
- ...fs.readFileSync(file, 'utf8').matchAll(/export const (create[A-Za-z0-9]*Styles)\s*=/g) + ...fs + .readFileSync(file, 'utf8') + .matchAll(/export (?:const|function) (create[A-Za-z0-9]*Styles)\s*[=(]/g)Same pattern is used by
FACTORY_DECLinmobile/src/theme/unthemed-color-imports.test.ts; keep the two in sync.
554-562: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
not.toEqual(lightSheet)bakes in "every factory must be theme-sensitive." A legitimately mode-independent factory (pure layout/spacing) would fail this suite with no way to opt out. Worth an explicit allowlist escape hatch, similar toCOVERED_BY_A_REGISTERED_MERGE, before that case arrives.mobile/src/theme/unthemed-color-imports.test.ts (2)
38-38: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLiteral detection misses
hsl()/hsla()and CSS named colors. A factory using'white','black', orhsl(...)slips past this guard entirely. Addinghsla?\(to the pattern is cheap; named colors are harder and probably not worth chasing.
75-92: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueParen counting is string- and comment-blind. An unbalanced
(or)inside a string literal, comment, or regex within the sheet truncates or over-extends the extracted body. Fine as a heuristic today given the codebase, but worth a short note so a future confusing failure is diagnosable.mobile/src/session/TerminalPaneView.test.ts (2)
48-53: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueOptional: make the prop accessor fail as an assertion, not a TypeError.
.at(-1)?.[0]is optional-chained but the result is dereferenced unguarded, so a zero-render regression surfaces asCannot read properties of undefined.♻️ Proposed tweak
- const props = terminalWebViewRender.mock.calls.at(-1)?.[0] as { - terminalTheme?: MobileTerminalTheme - } - return props.terminalTheme + const props = terminalWebViewRender.mock.calls.at(-1)?.[0] as + | { terminalTheme?: MobileTerminalTheme } + | undefined + return props?.terminalTheme
29-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffMigrate this test off deprecated
react-test-renderer.This still uses
react-test-rendererwith React 19 and only silences the runtime deprecation warning at collection time. Move it to@testing-library/react-nativeand removesuppressReactTestRendererDeprecationWarning().
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: f19664f6-c7a1-4506-bb44-d9fbe004198c
📥 Commits
Reviewing files that changed from the base of the PR and between ae8e584f68c6cecaefae0dc5005235e2f281d40e and c3959714bd60e859b7b565666c0ecacb6cb93d96.
📒 Files selected for processing (223)
mobile/app/_layout.tsxmobile/app/about.tsxmobile/app/browser-settings.tsxmobile/app/connection-log.tsxmobile/app/h/[hostId]/accounts-screen-styles.tsmobile/app/h/[hostId]/accounts.tsxmobile/app/h/[hostId]/edit.tsxmobile/app/h/[hostId]/index.tsxmobile/app/h/[hostId]/session/QuickCommandsTabButton.tsxmobile/app/h/[hostId]/session/[worktreeId].tsxmobile/app/h/[hostId]/session/mobile-session-command-input-styles.tsmobile/app/h/[hostId]/session/mobile-session-frame-styles.tsmobile/app/h/[hostId]/session/mobile-session-reader-styles.tsmobile/app/h/[hostId]/session/mobile-session-review-comment-styles.tsmobile/app/h/[hostId]/session/mobile-session-styles.tsmobile/app/h/[hostId]/tasks.tsxmobile/app/h/_layout.tsxmobile/app/index.tsxmobile/app/mobile-onboarding.tsxmobile/app/native-chat-settings.tsxmobile/app/notifications.tsxmobile/app/pair-confirm.tsxmobile/app/pair-scan.tsxmobile/app/pair.tsxmobile/app/settings.tsxmobile/app/terminal-settings.tsxmobile/app/troubleshoot.tsxmobile/app/voice-settings.tsxmobile/src/agent-history/MobileAgentSessionHistoryList.tsxmobile/src/agent-history/MobileAgentSessionHistoryPanel.tsxmobile/src/agent-history/agent-history-styles.tsmobile/src/agent-history/worktree-navigation-actions.tsmobile/src/browser/MobileBrowserKeyRow.tsxmobile/src/browser/MobileBrowserPane.tsxmobile/src/browser/MobileBrowserPointerModifiers.tsxmobile/src/browser/MobileBrowserToolbarIconButton.tsxmobile/src/browser/MobileBrowserViewModeSwitch.tsxmobile/src/components/AccountUsage.tsxmobile/src/components/ActionSheetModal.tsxmobile/src/components/AgentIcons.tsxmobile/src/components/AuthFailedBanner.tsxmobile/src/components/CodexResetCreditAction.tsxmobile/src/components/ConfirmModal.tsxmobile/src/components/ConnectionLog.tsxmobile/src/components/CustomKeyModal.tsxmobile/src/components/DragReorderList.tsxmobile/src/components/HostProtocolGate.tsxmobile/src/components/MobileAgentIcon.tsxmobile/src/components/MobileDictationSetupSheet.tsxmobile/src/components/MobileDiffReviewBody.tsxmobile/src/components/MobileDiffReviewDrawers.tsxmobile/src/components/MobileDiffReviewFileSummary.tsxmobile/src/components/MobileDiffReviewFooter.tsxmobile/src/components/MobileDiffReviewHeader.tsxmobile/src/components/MobileDiffReviewLine.tsxmobile/src/components/MobileDiffReviewScreenView.tsxmobile/src/components/MobileHostCard.tsxmobile/src/components/MobileHtmlPreview.tsxmobile/src/components/MobileMarkdown.tsxmobile/src/components/MobilePRSidebar.tsxmobile/src/components/MobilePrBasePicker.tsxmobile/src/components/MobileRepoIcon.tsxmobile/src/components/MobileRichMarkdownEditor.tsxmobile/src/components/MobileSearchField.tsxmobile/src/components/MobileSyntaxSegments.tsxmobile/src/components/NewWorkspaceFab.tsxmobile/src/components/NewWorktreeModal.tsxmobile/src/components/OrcaLogo.tsxmobile/src/components/PickerListDrawer.tsxmobile/src/components/PickerModal.tsxmobile/src/components/ProtocolBlockScreen.tsxmobile/src/components/RightDrawer.tsxmobile/src/components/SetupHookTrustDrawer.tsxmobile/src/components/SmartWorkspaceAdvancedFields.tsxmobile/src/components/SmartWorkspaceSourceDrawer.tsxmobile/src/components/SmartWorkspaceSourceField.tsxmobile/src/components/SmartWorkspaceSourceRow.tsxmobile/src/components/StatusDot.tsxmobile/src/components/TerminalShortcutSettings.tsxmobile/src/components/TextInputModal.tsxmobile/src/components/VoiceModelList.tsxmobile/src/components/WorkspaceDetailPlaceholder.tsxmobile/src/components/WorktreeAgentRow.tsxmobile/src/components/WorktreeListRow.tsxmobile/src/components/WorktreeMetaGlyphs.tsxmobile/src/components/bottom-drawer-styles.tsmobile/src/components/custom-key-modal-styles.tsmobile/src/components/mobile-diff-review-control-styles.tsmobile/src/components/mobile-diff-review-layout-styles.tsmobile/src/components/mobile-diff-review-screen-styles.tsmobile/src/components/mobile-markdown-styles.tsmobile/src/components/mobile-rich-markdown-editor-html.test.tsmobile/src/components/mobile-rich-markdown-editor-html.tsmobile/src/components/mobile-rich-markdown-editor-theme.tsmobile/src/components/mounted-bottom-drawer.tsxmobile/src/components/pr-sidebar/CommentMarkdown.tsxmobile/src/components/pr-sidebar/MermaidDiagram.tsxmobile/src/components/pr-sidebar/MobileLinkPrForm.tsxmobile/src/components/pr-sidebar/MobilePrComposeForm.tsxmobile/src/components/pr-sidebar/MobilePrViewPanel.tsxmobile/src/components/pr-sidebar/PRActionsSection.tsxmobile/src/components/pr-sidebar/PRCheckDetail.tsxmobile/src/components/pr-sidebar/PRChecksSection.tsxmobile/src/components/pr-sidebar/PRCommentCard.tsxmobile/src/components/pr-sidebar/PRCommentComposer.tsxmobile/src/components/pr-sidebar/PRCommentsSection.test.tsmobile/src/components/pr-sidebar/PRCommentsSection.tsxmobile/src/components/pr-sidebar/PRConflictingFilesSection.tsxmobile/src/components/pr-sidebar/PRReviewersSection.tsxmobile/src/components/pr-sidebar/PRSection.tsxmobile/src/components/pr-sidebar/PRSidebarHeader.tsxmobile/src/components/pr-sidebar/PrSidebarCreateEmptyState.tsxmobile/src/components/pr-sidebar/ReviewerPickerDrawer.tsxmobile/src/components/pr-sidebar/mobile-pr-compose-form-styles.tsmobile/src/components/pr-sidebar/mobile-pr-sidebar-styles.tsmobile/src/components/pr-sidebar/pr-actions-styles.tsmobile/src/components/pr-sidebar/pr-ai-triage-styles.tsmobile/src/components/pr-sidebar/pr-comment-composer-styles.tsmobile/src/components/pr-sidebar/pr-comments-styles.tsmobile/src/components/pr-sidebar/pr-conflict-styles.tsmobile/src/components/pr-sidebar/pr-create-empty-state-styles.tsmobile/src/components/pr-sidebar/pr-sidebar-status-color.tsmobile/src/components/pr-state-token.test.tsmobile/src/components/smart-workspace-source-drawer-styles.tsmobile/src/components/terminal-shortcut-settings-styles.tsmobile/src/diagnostics/troubleshoot-common-issues.tsxmobile/src/dictation/voice-settings-styles.tsmobile/src/files/MobileFileExplorerPanel.tsxmobile/src/files/MobileFileMarkdownPreview.test.tsmobile/src/files/MobileFileMarkdownPreview.tsxmobile/src/files/MobileFilePreviewBody.tsxmobile/src/files/MobileFilePreviewEditableSource.tsxmobile/src/files/MobileFilePreviewScreen.tsxmobile/src/files/MobileFilePreviewSourceText.tsxmobile/src/files/mobile-file-explorer-row.tsxmobile/src/files/mobile-file-explorer-styles.tsmobile/src/files/mobile-file-preview-styles.tsmobile/src/host/host-screen-chrome-styles.tsmobile/src/host/host-screen-styles.tsmobile/src/host/host-worktree-list-styles.tsmobile/src/onboarding/MobileOnboardingPage.tsxmobile/src/onboarding/mobile-onboarding-screen.test.tsmobile/src/onboarding/mobile-onboarding-styles.tsmobile/src/session/MobileAgentWorkingIndicator.tsxmobile/src/session/MobileNativeChatAsk.tsxmobile/src/session/MobileNativeChatComposer.tsxmobile/src/session/MobileNativeChatMessage.tsxmobile/src/session/MobileNativeChatPermission.tsxmobile/src/session/MobileNativeChatQuestion.tsxmobile/src/session/MobileNativeChatView.tsxmobile/src/session/MobileSessionHeaderIconButton.tsxmobile/src/session/MobileSessionHeaderMoreActionsSheet.tsxmobile/src/session/MobileTerminalInputActions.tsxmobile/src/session/MobileTerminalLiveInputStatus.tsxmobile/src/session/QuickCommandEditorForm.tsxmobile/src/session/QuickCommandsList.tsxmobile/src/session/QuickCommandsSheet.tsxmobile/src/session/SessionDockColumn.tsxmobile/src/session/TerminalPaneView.test.tsmobile/src/session/TerminalPaneView.tsxmobile/src/session/mobile-native-chat-message-styles.tsmobile/src/session/mobile-native-chat-view-styles.tsmobile/src/source-control/MobileBranchDiffPreviewDrawer.tsxmobile/src/source-control/MobileCommitFailurePanel.tsxmobile/src/source-control/MobileGitHistoryList.tsxmobile/src/source-control/MobileSourceControlBranchCard.tsxmobile/src/source-control/MobileSourceControlContent.tsxmobile/src/source-control/MobileSourceControlCreatePrEntry.tsxmobile/src/source-control/MobileSourceControlFileRows.tsxmobile/src/source-control/MobileSourceControlHeader.tsxmobile/src/source-control/MobileSourceControlPanel.tsxmobile/src/source-control/MobileSourceControlPrChip.tsxmobile/src/source-control/MobileSourceControlSegments.tsxmobile/src/source-control/mobile-source-control-diff-styles.tsmobile/src/source-control/mobile-source-control-hub-styles.tsmobile/src/source-control/mobile-source-control-list-styles.tsmobile/src/source-control/mobile-source-control-screen-state.tsmobile/src/source-control/mobile-source-control-styles.tsmobile/src/storage/preferences.test.tsmobile/src/storage/preferences.tsmobile/src/storage/terminal-theme-preference.test.tsmobile/src/storage/terminal-theme-preference.tsmobile/src/tasks/tasks-screen-chrome-styles.tsmobile/src/tasks/tasks-screen-detail-styles.tsmobile/src/tasks/tasks-screen-form-styles.tsmobile/src/tasks/tasks-screen-list-styles.tsmobile/src/tasks/tasks-screen-misc-styles.tsmobile/src/tasks/tasks-screen-panel-styles.tsmobile/src/tasks/tasks-screen-styles.tsmobile/src/terminal/TerminalWebView.test.tsmobile/src/terminal/TerminalWebView.tsxmobile/src/terminal/terminal-theme-slot-selection.test.tsmobile/src/terminal/terminal-theme-slot-selection.tsmobile/src/terminal/terminal-webview-engine-error-state.tsxmobile/src/terminal/terminal-webview-frame-styles.tsmobile/src/terminal/terminal-webview-html-app-chrome.test.tsmobile/src/terminal/terminal-webview-html.tsmobile/src/terminal/terminal-webview-messages.tsmobile/src/terminal/terminal-webview-theme-injected.test.tsmobile/src/terminal/terminal-webview-theme-injected.tsmobile/src/terminal/use-mobile-terminal-theme.test.tsmobile/src/terminal/use-mobile-terminal-theme.tsmobile/src/theme/app-shell-theme.test.tsmobile/src/theme/mobile-theme-palette.test.tsmobile/src/theme/mobile-theme.tsmobile/src/theme/theme-context.test.tsmobile/src/theme/theme-context.tsxmobile/src/theme/themed-style-factories.test.tsmobile/src/theme/unthemed-color-imports.test.tssrc/renderer/src/lib/terminal-contrast-correction.test.tssrc/renderer/src/lib/terminal-theme.tssrc/renderer/src/lib/terminal-themes-data.tssrc/renderer/src/lib/terminal-themes/types.tssrc/shared/terminal-themes/catalog-merge.tssrc/shared/terminal-themes/classic.tssrc/shared/terminal-themes/defaults.tssrc/shared/terminal-themes/index.tssrc/shared/terminal-themes/popular-dark-core.tssrc/shared/terminal-themes/popular-dark-extended.tssrc/shared/terminal-themes/popular-dark.tssrc/shared/terminal-themes/popular-light.tssrc/shared/terminal-themes/terminal-theme-catalog.test.tssrc/shared/terminal-themes/types.ts
🚧 Files skipped from review as they are similar to previous changes (193)
- src/shared/terminal-themes/classic.ts
- src/shared/terminal-themes/types.ts
- mobile/src/components/pr-sidebar/pr-sidebar-status-color.ts
- src/shared/terminal-themes/popular-light.ts
- src/shared/terminal-themes/defaults.ts
- src/renderer/src/lib/terminal-contrast-correction.test.ts
- mobile/src/components/mobile-diff-review-control-styles.ts
- mobile/src/host/host-screen-styles.ts
- mobile/src/components/mobile-diff-review-screen-styles.ts
- mobile/app/mobile-onboarding.tsx
- mobile/src/session/MobileTerminalInputActions.tsx
- mobile/src/session/mobile-native-chat-view-styles.ts
- mobile/app/h/[hostId]/session/mobile-session-styles.ts
- mobile/src/dictation/voice-settings-styles.ts
- mobile/src/components/pr-state-token.test.ts
- src/shared/terminal-themes/catalog-merge.ts
- mobile/src/files/mobile-file-explorer-row.tsx
- mobile/src/components/MobileDiffReviewHeader.tsx
- mobile/src/components/pr-sidebar/PRConflictingFilesSection.tsx
- mobile/app/h/[hostId]/session/mobile-session-review-comment-styles.ts
- mobile/src/host/host-screen-chrome-styles.ts
- mobile/app/h/[hostId]/session/mobile-session-frame-styles.ts
- mobile/src/components/mobile-rich-markdown-editor-html.ts
- mobile/src/session/MobileSessionHeaderIconButton.tsx
- mobile/src/components/AgentIcons.tsx
- mobile/src/components/pr-sidebar/PRCommentsSection.test.ts
- mobile/app/native-chat-settings.tsx
- mobile/src/components/mobile-rich-markdown-editor-html.test.ts
- mobile/app/h/[hostId]/session/QuickCommandsTabButton.tsx
- mobile/src/terminal/use-mobile-terminal-theme.ts
- mobile/src/components/pr-sidebar/pr-ai-triage-styles.ts
- mobile/src/session/MobileSessionHeaderMoreActionsSheet.tsx
- mobile/src/terminal/terminal-theme-slot-selection.ts
- mobile/app/connection-log.tsx
- mobile/src/agent-history/agent-history-styles.ts
- mobile/src/source-control/MobileSourceControlCreatePrEntry.tsx
- mobile/src/components/OrcaLogo.tsx
- src/shared/terminal-themes/terminal-theme-catalog.test.ts
- mobile/src/storage/preferences.test.ts
- mobile/src/host/host-worktree-list-styles.ts
- mobile/src/components/pr-sidebar/pr-comments-styles.ts
- src/shared/terminal-themes/popular-dark.ts
- mobile/src/files/MobileFileMarkdownPreview.tsx
- mobile/src/onboarding/mobile-onboarding-screen.test.ts
- src/shared/terminal-themes/index.ts
- mobile/src/tasks/tasks-screen-chrome-styles.ts
- mobile/app/h/[hostId]/session/mobile-session-command-input-styles.ts
- mobile/src/source-control/MobileSourceControlHeader.tsx
- mobile/src/components/MobileDiffReviewScreenView.tsx
- mobile/src/files/MobileFileMarkdownPreview.test.ts
- mobile/src/session/MobileNativeChatView.tsx
- mobile/app/_layout.tsx
- mobile/src/storage/terminal-theme-preference.test.ts
- mobile/src/browser/MobileBrowserKeyRow.tsx
- mobile/src/components/bottom-drawer-styles.ts
- src/shared/terminal-themes/popular-dark-extended.ts
- mobile/src/source-control/MobileSourceControlContent.tsx
- mobile/src/components/ActionSheetModal.tsx
- mobile/src/source-control/mobile-source-control-hub-styles.ts
- mobile/app/pair-confirm.tsx
- mobile/src/components/WorkspaceDetailPlaceholder.tsx
- mobile/src/components/custom-key-modal-styles.ts
- mobile/app/settings.tsx
- mobile/app/notifications.tsx
- mobile/src/source-control/MobileSourceControlBranchCard.tsx
- mobile/src/session/mobile-native-chat-message-styles.ts
- mobile/src/components/CodexResetCreditAction.tsx
- mobile/src/components/PickerModal.tsx
- mobile/src/session/QuickCommandsSheet.tsx
- mobile/src/components/TextInputModal.tsx
- mobile/src/components/MobileRepoIcon.tsx
- mobile/src/source-control/MobileSourceControlPanel.tsx
- mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx
- mobile/app/voice-settings.tsx
- mobile/src/components/pr-sidebar/pr-comment-composer-styles.ts
- mobile/src/terminal/terminal-webview-frame-styles.ts
- mobile/src/components/MobileSyntaxSegments.tsx
- mobile/src/theme/mobile-theme.ts
- mobile/src/tasks/tasks-screen-styles.ts
- mobile/src/components/ConfirmModal.tsx
- mobile/src/components/MobileMarkdown.tsx
- mobile/src/components/MobileSearchField.tsx
- mobile/src/components/SmartWorkspaceSourceDrawer.tsx
- mobile/src/components/pr-sidebar/pr-actions-styles.ts
- mobile/src/components/HostProtocolGate.tsx
- mobile/src/source-control/mobile-source-control-styles.ts
- mobile/src/tasks/tasks-screen-panel-styles.ts
- mobile/src/files/MobileFilePreviewBody.tsx
- mobile/src/files/MobileFilePreviewEditableSource.tsx
- mobile/src/storage/terminal-theme-preference.ts
- mobile/src/components/pr-sidebar/MobileLinkPrForm.tsx
- mobile/src/components/mobile-diff-review-layout-styles.ts
- mobile/src/files/mobile-file-explorer-styles.ts
- mobile/src/source-control/mobile-source-control-screen-state.ts
- mobile/src/source-control/mobile-source-control-list-styles.ts
- src/shared/terminal-themes/popular-dark-core.ts
- mobile/src/source-control/MobileCommitFailurePanel.tsx
- mobile/src/session/MobileTerminalLiveInputStatus.tsx
- mobile/src/components/MobileDiffReviewFileSummary.tsx
- mobile/src/components/terminal-shortcut-settings-styles.ts
- mobile/src/components/ConnectionLog.tsx
- mobile/src/components/MobileDiffReviewDrawers.tsx
- mobile/src/components/MobileDictationSetupSheet.tsx
- mobile/app/pair-scan.tsx
- mobile/src/components/pr-sidebar/pr-conflict-styles.ts
- mobile/src/components/MobileHostCard.tsx
- mobile/src/components/NewWorktreeModal.tsx
- mobile/src/components/SetupHookTrustDrawer.tsx
- mobile/src/components/StatusDot.tsx
- mobile/src/onboarding/MobileOnboardingPage.tsx
- mobile/src/components/pr-sidebar/pr-create-empty-state-styles.ts
- mobile/src/agent-history/MobileAgentSessionHistoryList.tsx
- mobile/src/diagnostics/troubleshoot-common-issues.tsx
- mobile/src/session/MobileNativeChatQuestion.tsx
- mobile/src/components/MobileAgentIcon.tsx
- mobile/src/components/MobileDiffReviewFooter.tsx
- mobile/src/components/NewWorkspaceFab.tsx
- mobile/src/components/VoiceModelList.tsx
- mobile/src/tasks/tasks-screen-list-styles.ts
- mobile/src/terminal/terminal-webview-theme-injected.ts
- mobile/src/source-control/MobileSourceControlFileRows.tsx
- mobile/src/components/pr-sidebar/MermaidDiagram.tsx
- mobile/src/tasks/tasks-screen-form-styles.ts
- mobile/src/source-control/MobileGitHistoryList.tsx
- mobile/app/h/[hostId]/session/mobile-session-reader-styles.ts
- mobile/src/components/DragReorderList.tsx
- mobile/src/files/MobileFilePreviewScreen.tsx
- mobile/src/components/pr-sidebar/PRChecksSection.tsx
- mobile/src/session/MobileNativeChatComposer.tsx
- mobile/src/components/AuthFailedBanner.tsx
- mobile/src/components/CustomKeyModal.tsx
- mobile/src/components/MobilePrBasePicker.tsx
- mobile/src/components/pr-sidebar/PRSidebarHeader.tsx
- mobile/src/session/TerminalPaneView.tsx
- mobile/src/components/mounted-bottom-drawer.tsx
- mobile/src/source-control/mobile-source-control-diff-styles.ts
- mobile/src/components/pr-sidebar/PRCommentComposer.tsx
- mobile/src/tasks/tasks-screen-misc-styles.ts
- mobile/src/components/ProtocolBlockScreen.tsx
- mobile/src/components/pr-sidebar/MobilePrComposeForm.tsx
- mobile/src/theme/theme-context.tsx
- mobile/src/theme/theme-context.test.ts
- mobile/src/browser/MobileBrowserViewModeSwitch.tsx
- mobile/app/h/[hostId]/edit.tsx
- mobile/src/session/MobileNativeChatAsk.tsx
- mobile/src/components/pr-sidebar/PrSidebarCreateEmptyState.tsx
- mobile/src/components/AccountUsage.tsx
- mobile/src/terminal/terminal-webview-html.ts
- mobile/src/terminal/use-mobile-terminal-theme.test.ts
- mobile/src/components/pr-sidebar/PRCheckDetail.tsx
- mobile/src/components/pr-sidebar/PRCommentsSection.tsx
- mobile/src/storage/preferences.ts
- mobile/src/components/mobile-markdown-styles.ts
- mobile/src/components/pr-sidebar/PRSection.tsx
- mobile/src/components/WorktreeAgentRow.tsx
- mobile/app/troubleshoot.tsx
- mobile/src/components/pr-sidebar/ReviewerPickerDrawer.tsx
- mobile/src/components/pr-sidebar/PRCommentCard.tsx
- mobile/src/terminal/TerminalWebView.test.ts
- mobile/src/components/pr-sidebar/CommentMarkdown.tsx
- mobile/src/session/MobileNativeChatPermission.tsx
- mobile/src/browser/MobileBrowserToolbarIconButton.tsx
- mobile/src/components/SmartWorkspaceSourceField.tsx
- mobile/src/session/SessionDockColumn.tsx
- mobile/src/files/mobile-file-preview-styles.ts
- mobile/src/components/pr-sidebar/mobile-pr-sidebar-styles.ts
- mobile/src/components/SmartWorkspaceAdvancedFields.tsx
- mobile/src/terminal/terminal-theme-slot-selection.test.ts
- mobile/src/components/MobileDiffReviewLine.tsx
- mobile/src/components/pr-sidebar/mobile-pr-compose-form-styles.ts
- mobile/src/browser/MobileBrowserPane.tsx
- mobile/app/h/_layout.tsx
- mobile/src/files/MobileFilePreviewSourceText.tsx
- mobile/src/session/QuickCommandEditorForm.tsx
- mobile/src/components/TerminalShortcutSettings.tsx
- mobile/src/components/WorktreeMetaGlyphs.tsx
- mobile/src/components/pr-sidebar/MobilePrViewPanel.tsx
- mobile/src/components/MobileHtmlPreview.tsx
- mobile/src/components/SmartWorkspaceSourceRow.tsx
- mobile/src/session/MobileNativeChatMessage.tsx
- mobile/src/source-control/MobileSourceControlPrChip.tsx
- mobile/src/components/smart-workspace-source-drawer-styles.ts
- mobile/app/h/[hostId]/session/[worktreeId].tsx
- mobile/app/terminal-settings.tsx
- mobile/app/h/[hostId]/index.tsx
- src/renderer/src/lib/terminal-theme.ts
- mobile/src/components/MobilePRSidebar.tsx
- mobile/app/index.tsx
- mobile/src/components/PickerListDrawer.tsx
- mobile/src/session/QuickCommandsList.tsx
- mobile/src/terminal/terminal-webview-theme-injected.test.ts
- mobile/src/terminal/TerminalWebView.tsx
- mobile/app/h/[hostId]/tasks.tsx
|
Rebased onto current
Verified: palette/factories/unthemed/theme-context/rich-markdown (31/31); oxlint clean on key files. |
c395971 to
86ff3b9
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (3)
mobile/src/terminal/terminal-webview-html-app-chrome.test.ts (1)
7-8: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winLine 8 is a tautology.
expect(X).toBe(X)compares one reference with itself and can never fail, so the "stable module constant" intent isn't actually tested. Re-import the module and compare identity instead.♻️ Suggested change
expect(XTERM_WEBVIEW_SOURCE).toEqual({ html: XTERM_HTML }) - expect(XTERM_WEBVIEW_SOURCE).toBe(XTERM_WEBVIEW_SOURCE) + const reimported = await import('./terminal-webview-html') + expect(reimported.XTERM_WEBVIEW_SOURCE).toBe(XTERM_WEBVIEW_SOURCE)mobile/src/theme/themed-style-factories.test.ts (1)
111-249: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift68-slot positional destructuring is a silent-misbinding hazard. Any insertion or reordering in the
Promise.allarray shifts every later binding; because most of these modules export similarly shapedcreate*Styles, TypeScript won't reliably catch the swap and the registry would then assert against the wrong factory. Bind each module to its factory name at the import site instead.♻️ Sketch
- const mods = await Promise.all([ - import('../components/bottom-drawer-styles'), - … - ]) - const [bottomDrawer, pickerModal, …] = mods - return [ - { name: 'createBottomDrawerStyles', factory: bottomDrawer.createBottomDrawerStyles }, - … - ] + const specs: readonly (readonly [string, () => Promise<Record<string, unknown>>])[] = [ + ['createBottomDrawerStyles', () => import('../components/bottom-drawer-styles')], + ['createPickerModalStyles', () => import('../components/PickerModal')] + // … + ] + return Promise.all( + specs.map(async ([name, load]) => ({ + name, + factory: (await load())[name] as StyleFactory['factory'] + })) + )mobile/src/theme/unthemed-color-imports.test.ts (1)
38-71: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSource-scan primitives are re-implemented in every theme guard test. The file walker, the
create*Stylesdeclaration regex, and the bare-colorsimport regex each exist in multiple copies; if one copy drifts (e.g. a new excluded directory or a changed palette export shape), a factory or an unthemed import can slip past one ratchet while still passing the others. Extract them once into a concrete module such asmobile/src/theme/theme-source-scan.ts.
mobile/src/theme/unthemed-color-imports.test.ts#L38-L71: moveCOLOUR_LITERAL,FACTORY_DECL,BARE_COLORS_IMPORT, andwalkSourceFilesinto the shared module and import them here.mobile/src/theme/themed-style-factories.test.ts#L507-L531: deletewalkSourcesand the inlinecreate[A-Za-z0-9]*Stylesregex; use the shared walker andFACTORY_DECL.mobile/src/theme/app-shell-theme.test.ts#L20-L21: assert with the sharedBARE_COLORS_IMPORTinstead of an inline copy.mobile/src/terminal/terminal-webview-html-app-chrome.test.ts#L13-L13: same — use the sharedBARE_COLORS_IMPORT.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5791906b-8b87-4a2d-b6e0-db2c55e0e12b
📥 Commits
Reviewing files that changed from the base of the PR and between c3959714bd60e859b7b565666c0ecacb6cb93d96 and 86ff3b9.
📒 Files selected for processing (214)
mobile/app/_layout.tsxmobile/app/about.tsxmobile/app/browser-settings.tsxmobile/app/connection-log.tsxmobile/app/h/[hostId]/accounts-screen-styles.tsmobile/app/h/[hostId]/accounts.tsxmobile/app/h/[hostId]/edit.tsxmobile/app/h/[hostId]/index.tsxmobile/app/h/[hostId]/session/QuickCommandsTabButton.tsxmobile/app/h/[hostId]/session/[worktreeId].tsxmobile/app/h/[hostId]/session/mobile-session-command-input-styles.tsmobile/app/h/[hostId]/session/mobile-session-frame-styles.tsmobile/app/h/[hostId]/session/mobile-session-reader-styles.tsmobile/app/h/[hostId]/session/mobile-session-review-comment-styles.tsmobile/app/h/[hostId]/session/mobile-session-styles.tsmobile/app/h/[hostId]/tasks.tsxmobile/app/h/_layout.tsxmobile/app/index.tsxmobile/app/mobile-onboarding.tsxmobile/app/native-chat-settings.tsxmobile/app/notifications.tsxmobile/app/pair-confirm.tsxmobile/app/pair-scan.tsxmobile/app/pair.tsxmobile/app/settings.tsxmobile/app/terminal-settings.tsxmobile/app/troubleshoot.tsxmobile/app/voice-settings.tsxmobile/src/agent-history/MobileAgentSessionHistoryList.tsxmobile/src/agent-history/MobileAgentSessionHistoryPanel.tsxmobile/src/agent-history/agent-history-styles.tsmobile/src/agent-history/worktree-navigation-actions.tsmobile/src/browser/MobileBrowserKeyRow.tsxmobile/src/browser/MobileBrowserPane.tsxmobile/src/browser/MobileBrowserPointerModifiers.tsxmobile/src/browser/MobileBrowserToolbarIconButton.tsxmobile/src/browser/MobileBrowserViewModeSwitch.tsxmobile/src/components/AccountUsage.tsxmobile/src/components/ActionSheetModal.tsxmobile/src/components/AgentIcons.tsxmobile/src/components/AuthFailedBanner.tsxmobile/src/components/CodexResetCreditAction.tsxmobile/src/components/ConfirmModal.tsxmobile/src/components/ConnectionLog.tsxmobile/src/components/CustomKeyModal.tsxmobile/src/components/DragReorderList.tsxmobile/src/components/HostProtocolGate.tsxmobile/src/components/MobileAgentIcon.tsxmobile/src/components/MobileDictationSetupSheet.tsxmobile/src/components/MobileDiffReviewBody.tsxmobile/src/components/MobileDiffReviewDrawers.tsxmobile/src/components/MobileDiffReviewFileSummary.tsxmobile/src/components/MobileDiffReviewFooter.tsxmobile/src/components/MobileDiffReviewHeader.tsxmobile/src/components/MobileDiffReviewLine.tsxmobile/src/components/MobileDiffReviewScreenView.tsxmobile/src/components/MobileHostCard.tsxmobile/src/components/MobileHtmlPreview.tsxmobile/src/components/MobileMarkdown.tsxmobile/src/components/MobilePRSidebar.tsxmobile/src/components/MobilePrBasePicker.tsxmobile/src/components/MobileRepoIcon.tsxmobile/src/components/MobileRichMarkdownEditor.tsxmobile/src/components/MobileSearchField.tsxmobile/src/components/MobileSyntaxSegments.tsxmobile/src/components/NewWorkspaceFab.tsxmobile/src/components/NewWorktreeModal.tsxmobile/src/components/OrcaLogo.tsxmobile/src/components/PickerListDrawer.tsxmobile/src/components/PickerModal.tsxmobile/src/components/ProtocolBlockScreen.tsxmobile/src/components/RightDrawer.tsxmobile/src/components/SetupHookTrustDrawer.tsxmobile/src/components/SmartWorkspaceAdvancedFields.tsxmobile/src/components/SmartWorkspaceSourceDrawer.tsxmobile/src/components/SmartWorkspaceSourceField.tsxmobile/src/components/SmartWorkspaceSourceRow.tsxmobile/src/components/StatusDot.tsxmobile/src/components/TerminalShortcutSettings.tsxmobile/src/components/TextInputModal.tsxmobile/src/components/VoiceModelList.tsxmobile/src/components/WorkspaceDetailPlaceholder.tsxmobile/src/components/WorktreeAgentRow.tsxmobile/src/components/WorktreeListRow.tsxmobile/src/components/WorktreeMetaGlyphs.tsxmobile/src/components/bottom-drawer-styles.tsmobile/src/components/custom-key-modal-styles.tsmobile/src/components/mobile-diff-review-control-styles.tsmobile/src/components/mobile-diff-review-layout-styles.tsmobile/src/components/mobile-diff-review-screen-styles.tsmobile/src/components/mobile-markdown-styles.tsmobile/src/components/mobile-rich-markdown-editor-html.test.tsmobile/src/components/mobile-rich-markdown-editor-html.tsmobile/src/components/mobile-rich-markdown-editor-theme.tsmobile/src/components/mounted-bottom-drawer.tsxmobile/src/components/pr-sidebar/CommentMarkdown.tsxmobile/src/components/pr-sidebar/MermaidDiagram.tsxmobile/src/components/pr-sidebar/MobileLinkPrForm.tsxmobile/src/components/pr-sidebar/MobilePrComposeForm.tsxmobile/src/components/pr-sidebar/MobilePrViewPanel.tsxmobile/src/components/pr-sidebar/PRActionsSection.tsxmobile/src/components/pr-sidebar/PRCheckDetail.tsxmobile/src/components/pr-sidebar/PRChecksSection.tsxmobile/src/components/pr-sidebar/PRCommentCard.tsxmobile/src/components/pr-sidebar/PRCommentComposer.tsxmobile/src/components/pr-sidebar/PRCommentsSection.test.tsmobile/src/components/pr-sidebar/PRCommentsSection.tsxmobile/src/components/pr-sidebar/PRConflictingFilesSection.tsxmobile/src/components/pr-sidebar/PRReviewersSection.tsxmobile/src/components/pr-sidebar/PRSection.tsxmobile/src/components/pr-sidebar/PRSidebarHeader.tsxmobile/src/components/pr-sidebar/PrSidebarCreateEmptyState.tsxmobile/src/components/pr-sidebar/ReviewerPickerDrawer.tsxmobile/src/components/pr-sidebar/mobile-pr-compose-form-styles.tsmobile/src/components/pr-sidebar/mobile-pr-sidebar-styles.tsmobile/src/components/pr-sidebar/pr-actions-styles.tsmobile/src/components/pr-sidebar/pr-ai-triage-styles.tsmobile/src/components/pr-sidebar/pr-comment-composer-styles.tsmobile/src/components/pr-sidebar/pr-comments-styles.tsmobile/src/components/pr-sidebar/pr-conflict-styles.tsmobile/src/components/pr-sidebar/pr-create-empty-state-styles.tsmobile/src/components/pr-sidebar/pr-sidebar-status-color.tsmobile/src/components/pr-state-token.test.tsmobile/src/components/smart-workspace-source-drawer-styles.tsmobile/src/components/terminal-shortcut-settings-styles.tsmobile/src/diagnostics/troubleshoot-common-issues.tsxmobile/src/dictation/voice-settings-styles.tsmobile/src/files/MobileFileExplorerPanel.tsxmobile/src/files/MobileFileMarkdownPreview.test.tsmobile/src/files/MobileFileMarkdownPreview.tsxmobile/src/files/MobileFilePreviewBody.tsxmobile/src/files/MobileFilePreviewEditableSource.tsxmobile/src/files/MobileFilePreviewScreen.tsxmobile/src/files/MobileFilePreviewSourceText.tsxmobile/src/files/mobile-file-explorer-row.tsxmobile/src/files/mobile-file-explorer-styles.tsmobile/src/files/mobile-file-preview-styles.tsmobile/src/host/host-screen-chrome-styles.tsmobile/src/host/host-screen-styles.tsmobile/src/host/host-worktree-list-styles.tsmobile/src/onboarding/MobileOnboardingPage.tsxmobile/src/onboarding/mobile-onboarding-screen.test.tsmobile/src/onboarding/mobile-onboarding-styles.tsmobile/src/session/MobileAgentWorkingIndicator.tsxmobile/src/session/MobileNativeChatAsk.tsxmobile/src/session/MobileNativeChatComposer.tsxmobile/src/session/MobileNativeChatMessage.tsxmobile/src/session/MobileNativeChatPermission.tsxmobile/src/session/MobileNativeChatQuestion.tsxmobile/src/session/MobileNativeChatView.tsxmobile/src/session/MobileSessionHeaderIconButton.tsxmobile/src/session/MobileSessionHeaderMoreActionsSheet.tsxmobile/src/session/MobileTerminalInputActions.tsxmobile/src/session/MobileTerminalLiveInputStatus.tsxmobile/src/session/QuickCommandEditorForm.tsxmobile/src/session/QuickCommandsList.tsxmobile/src/session/QuickCommandsSheet.tsxmobile/src/session/SessionDockColumn.tsxmobile/src/session/TerminalPaneView.test.tsmobile/src/session/TerminalPaneView.tsxmobile/src/session/mobile-native-chat-message-styles.tsmobile/src/session/mobile-native-chat-view-styles.tsmobile/src/source-control/MobileBranchDiffPreviewDrawer.tsxmobile/src/source-control/MobileCommitFailurePanel.tsxmobile/src/source-control/MobileGitHistoryList.tsxmobile/src/source-control/MobileSourceControlBranchCard.tsxmobile/src/source-control/MobileSourceControlContent.tsxmobile/src/source-control/MobileSourceControlCreatePrEntry.tsxmobile/src/source-control/MobileSourceControlFileRows.tsxmobile/src/source-control/MobileSourceControlHeader.tsxmobile/src/source-control/MobileSourceControlPanel.tsxmobile/src/source-control/MobileSourceControlPrChip.tsxmobile/src/source-control/MobileSourceControlSegments.tsxmobile/src/source-control/mobile-source-control-diff-styles.tsmobile/src/source-control/mobile-source-control-hub-styles.tsmobile/src/source-control/mobile-source-control-list-styles.tsmobile/src/source-control/mobile-source-control-screen-state.tsmobile/src/source-control/mobile-source-control-styles.tsmobile/src/storage/preferences.test.tsmobile/src/storage/preferences.tsmobile/src/storage/terminal-theme-preference.test.tsmobile/src/storage/terminal-theme-preference.tsmobile/src/tasks/tasks-screen-chrome-styles.tsmobile/src/tasks/tasks-screen-detail-styles.tsmobile/src/tasks/tasks-screen-form-styles.tsmobile/src/tasks/tasks-screen-list-styles.tsmobile/src/tasks/tasks-screen-misc-styles.tsmobile/src/tasks/tasks-screen-panel-styles.tsmobile/src/tasks/tasks-screen-styles.tsmobile/src/terminal/TerminalWebView.test.tsmobile/src/terminal/TerminalWebView.tsxmobile/src/terminal/terminal-theme-slot-selection.test.tsmobile/src/terminal/terminal-theme-slot-selection.tsmobile/src/terminal/terminal-webview-engine-error-state.tsxmobile/src/terminal/terminal-webview-frame-styles.tsmobile/src/terminal/terminal-webview-html-app-chrome.test.tsmobile/src/terminal/terminal-webview-html.tsmobile/src/terminal/terminal-webview-messages.tsmobile/src/terminal/terminal-webview-theme-injected.test.tsmobile/src/terminal/terminal-webview-theme-injected.tsmobile/src/terminal/use-mobile-terminal-theme.test.tsmobile/src/terminal/use-mobile-terminal-theme.tsmobile/src/theme/app-shell-theme.test.tsmobile/src/theme/mobile-theme-palette.test.tsmobile/src/theme/mobile-theme.tsmobile/src/theme/theme-context.test.tsmobile/src/theme/theme-context.tsxmobile/src/theme/themed-style-factories.test.tsmobile/src/theme/unthemed-color-imports.test.tssrc/renderer/src/lib/terminal-contrast-correction.test.tssrc/renderer/src/lib/terminal-theme.tssrc/renderer/src/lib/terminal-themes-data.tssrc/renderer/src/lib/terminal-themes/index.tssrc/renderer/src/lib/terminal-themes/types.ts
🚧 Files skipped from review as they are similar to previous changes (179)
- mobile/src/components/mobile-rich-markdown-editor-theme.ts
- mobile/src/components/pr-sidebar/pr-actions-styles.ts
- mobile/src/components/mobile-diff-review-screen-styles.ts
- mobile/src/terminal/use-mobile-terminal-theme.ts
- mobile/src/components/pr-sidebar/pr-comment-composer-styles.ts
- mobile/src/terminal/TerminalWebView.test.ts
- mobile/src/components/pr-sidebar/mobile-pr-compose-form-styles.ts
- mobile/app/native-chat-settings.tsx
- mobile/src/dictation/voice-settings-styles.ts
- mobile/src/session/mobile-native-chat-view-styles.ts
- mobile/app/connection-log.tsx
- mobile/src/tasks/tasks-screen-detail-styles.ts
- mobile/app/h/[hostId]/session/mobile-session-review-comment-styles.ts
- mobile/src/session/MobileAgentWorkingIndicator.tsx
- mobile/src/source-control/mobile-source-control-diff-styles.ts
- mobile/src/agent-history/agent-history-styles.ts
- mobile/app/h/[hostId]/session/mobile-session-styles.ts
- mobile/src/terminal/terminal-theme-slot-selection.ts
- mobile/src/onboarding/mobile-onboarding-styles.ts
- mobile/src/components/terminal-shortcut-settings-styles.ts
- mobile/src/components/pr-sidebar/PRCommentsSection.test.ts
- mobile/src/components/custom-key-modal-styles.ts
- mobile/src/onboarding/mobile-onboarding-screen.test.ts
- mobile/app/settings.tsx
- mobile/src/components/pr-sidebar/mobile-pr-sidebar-styles.ts
- mobile/src/components/OrcaLogo.tsx
- mobile/src/components/pr-state-token.test.ts
- mobile/src/terminal/terminal-webview-messages.ts
- mobile/src/components/mobile-rich-markdown-editor-html.test.ts
- mobile/src/components/mobile-markdown-styles.ts
- mobile/src/session/QuickCommandsSheet.tsx
- mobile/src/components/pr-sidebar/pr-comments-styles.ts
- mobile/src/components/pr-sidebar/pr-create-empty-state-styles.ts
- mobile/src/tasks/tasks-screen-chrome-styles.ts
- mobile/app/h/[hostId]/session/QuickCommandsTabButton.tsx
- mobile/src/files/MobileFileMarkdownPreview.test.ts
- mobile/src/components/AgentIcons.tsx
- mobile/src/components/smart-workspace-source-drawer-styles.ts
- mobile/src/files/MobileFilePreviewBody.tsx
- mobile/app/pair.tsx
- mobile/src/components/SmartWorkspaceSourceDrawer.tsx
- mobile/src/files/mobile-file-explorer-styles.ts
- mobile/src/components/MobileSyntaxSegments.tsx
- mobile/src/session/TerminalPaneView.tsx
- mobile/src/diagnostics/troubleshoot-common-issues.tsx
- mobile/src/source-control/MobileSourceControlCreatePrEntry.tsx
- mobile/src/session/MobileSessionHeaderIconButton.tsx
- mobile/src/terminal/terminal-webview-theme-injected.ts
- mobile/src/session/MobileTerminalInputActions.tsx
- mobile/src/components/pr-sidebar/ReviewerPickerDrawer.tsx
- mobile/src/terminal/terminal-webview-frame-styles.ts
- mobile/src/components/ConfirmModal.tsx
- mobile/src/theme/theme-context.test.ts
- mobile/src/files/MobileFilePreviewScreen.tsx
- mobile/src/components/pr-sidebar/PRCheckDetail.tsx
- mobile/src/source-control/mobile-source-control-list-styles.ts
- mobile/src/components/CodexResetCreditAction.tsx
- mobile/src/components/MobileDiffReviewScreenView.tsx
- mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx
- mobile/src/tasks/tasks-screen-form-styles.ts
- mobile/src/source-control/MobileSourceControlPanel.tsx
- mobile/src/tasks/tasks-screen-panel-styles.ts
- mobile/src/components/pr-sidebar/pr-sidebar-status-color.ts
- mobile/src/host/host-screen-styles.ts
- mobile/src/storage/preferences.ts
- mobile/src/components/WorkspaceDetailPlaceholder.tsx
- mobile/src/browser/MobileBrowserPointerModifiers.tsx
- mobile/src/components/MobileDiffReviewHeader.tsx
- mobile/src/terminal/terminal-webview-engine-error-state.tsx
- mobile/src/components/pr-sidebar/PRReviewersSection.tsx
- mobile/src/components/TextInputModal.tsx
- mobile/src/components/MobileHtmlPreview.tsx
- mobile/src/components/CustomKeyModal.tsx
- mobile/src/components/ActionSheetModal.tsx
- mobile/src/components/MobileDictationSetupSheet.tsx
- mobile/src/files/MobileFileMarkdownPreview.tsx
- mobile/src/components/pr-sidebar/PRCommentComposer.tsx
- mobile/src/host/host-screen-chrome-styles.ts
- mobile/src/components/SetupHookTrustDrawer.tsx
- mobile/src/source-control/MobileSourceControlSegments.tsx
- mobile/src/components/AccountUsage.tsx
- mobile/src/storage/preferences.test.ts
- mobile/src/components/pr-sidebar/PRSection.tsx
- mobile/src/components/MobileDiffReviewFileSummary.tsx
- mobile/src/components/ConnectionLog.tsx
- mobile/app/h/[hostId]/accounts-screen-styles.ts
- src/renderer/src/lib/terminal-theme.ts
- mobile/src/tasks/tasks-screen-styles.ts
- mobile/app/about.tsx
- mobile/src/files/MobileFileExplorerPanel.tsx
- mobile/src/components/mobile-diff-review-layout-styles.ts
- mobile/src/agent-history/MobileAgentSessionHistoryPanel.tsx
- mobile/src/components/MobileDiffReviewBody.tsx
- mobile/src/session/MobileNativeChatView.tsx
- mobile/src/source-control/mobile-source-control-styles.ts
- mobile/src/components/RightDrawer.tsx
- mobile/src/components/pr-sidebar/MobilePrViewPanel.tsx
- mobile/src/session/QuickCommandEditorForm.tsx
- mobile/src/files/mobile-file-preview-styles.ts
- mobile/src/session/MobileTerminalLiveInputStatus.tsx
- mobile/src/storage/terminal-theme-preference.test.ts
- mobile/src/components/MobileAgentIcon.tsx
- mobile/src/components/mounted-bottom-drawer.tsx
- mobile/app/h/[hostId]/session/mobile-session-reader-styles.ts
- mobile/src/session/mobile-native-chat-message-styles.ts
- mobile/src/tasks/tasks-screen-list-styles.ts
- mobile/src/components/MobileDiffReviewLine.tsx
- mobile/src/components/StatusDot.tsx
- mobile/app/pair-confirm.tsx
- mobile/src/components/pr-sidebar/PRCommentsSection.tsx
- mobile/src/host/host-worktree-list-styles.ts
- mobile/src/components/pr-sidebar/pr-ai-triage-styles.ts
- mobile/src/source-control/MobileGitHistoryList.tsx
- mobile/src/components/AuthFailedBanner.tsx
- mobile/src/components/pr-sidebar/PRCommentCard.tsx
- mobile/src/components/WorktreeListRow.tsx
- mobile/src/source-control/mobile-source-control-hub-styles.ts
- mobile/src/theme/theme-context.tsx
- mobile/src/components/bottom-drawer-styles.ts
- mobile/src/components/NewWorkspaceFab.tsx
- mobile/src/source-control/MobileCommitFailurePanel.tsx
- mobile/src/browser/MobileBrowserToolbarIconButton.tsx
- mobile/src/files/mobile-file-explorer-row.tsx
- mobile/src/components/MobileHostCard.tsx
- mobile/src/components/pr-sidebar/pr-conflict-styles.ts
- mobile/src/components/WorktreeMetaGlyphs.tsx
- mobile/src/components/SmartWorkspaceSourceField.tsx
- mobile/app/h/[hostId]/accounts.tsx
- mobile/src/agent-history/MobileAgentSessionHistoryList.tsx
- mobile/app/voice-settings.tsx
- mobile/src/session/TerminalPaneView.test.ts
- mobile/src/components/MobileMarkdown.tsx
- mobile/app/h/[hostId]/session/[worktreeId].tsx
- mobile/src/components/MobileDiffReviewDrawers.tsx
- mobile/app/h/[hostId]/session/mobile-session-frame-styles.ts
- mobile/src/source-control/MobileSourceControlPrChip.tsx
- mobile/src/browser/MobileBrowserViewModeSwitch.tsx
- mobile/src/source-control/MobileSourceControlBranchCard.tsx
- mobile/src/components/mobile-diff-review-control-styles.ts
- mobile/src/components/pr-sidebar/PRSidebarHeader.tsx
- mobile/app/index.tsx
- mobile/src/components/VoiceModelList.tsx
- mobile/app/h/[hostId]/session/mobile-session-command-input-styles.ts
- mobile/src/components/pr-sidebar/MermaidDiagram.tsx
- mobile/app/_layout.tsx
- mobile/src/terminal/terminal-webview-theme-injected.test.ts
- mobile/src/theme/mobile-theme.ts
- mobile/src/components/pr-sidebar/PRActionsSection.tsx
- mobile/src/session/MobileNativeChatPermission.tsx
- mobile/src/session/MobileNativeChatAsk.tsx
- mobile/src/tasks/tasks-screen-misc-styles.ts
- mobile/app/h/_layout.tsx
- mobile/src/components/pr-sidebar/PrSidebarCreateEmptyState.tsx
- mobile/src/components/pr-sidebar/MobilePrComposeForm.tsx
- mobile/src/components/pr-sidebar/CommentMarkdown.tsx
- mobile/src/components/pr-sidebar/PRChecksSection.tsx
- mobile/app/troubleshoot.tsx
- mobile/src/storage/terminal-theme-preference.ts
- mobile/src/components/mobile-rich-markdown-editor-html.ts
- mobile/app/pair-scan.tsx
- mobile/src/components/pr-sidebar/MobileLinkPrForm.tsx
- mobile/src/agent-history/worktree-navigation-actions.ts
- mobile/src/components/SmartWorkspaceAdvancedFields.tsx
- mobile/src/terminal/terminal-webview-html.ts
- mobile/src/components/PickerModal.tsx
- mobile/src/session/MobileNativeChatMessage.tsx
- mobile/app/h/[hostId]/index.tsx
- mobile/src/session/QuickCommandsList.tsx
- mobile/src/browser/MobileBrowserPane.tsx
- mobile/src/source-control/MobileSourceControlFileRows.tsx
- mobile/src/terminal/TerminalWebView.tsx
- mobile/src/session/MobileNativeChatComposer.tsx
- mobile/src/components/DragReorderList.tsx
- mobile/src/terminal/terminal-theme-slot-selection.test.ts
- mobile/src/components/TerminalShortcutSettings.tsx
- mobile/src/components/PickerListDrawer.tsx
- mobile/src/theme/mobile-theme-palette.test.ts
- mobile/app/h/[hostId]/tasks.tsx
- mobile/app/terminal-settings.tsx
00c9429 to
efa0c54
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
mobile/src/terminal/terminal-webview-html-app-chrome.test.ts (1)
7-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
expect(XTERM_WEBVIEW_SOURCE).toBe(XTERM_WEBVIEW_SOURCE)is a tautology.Comparing the binding to itself always passes and proves nothing about source identity stability. If the intent is "the export is a module constant, not recreated per access", capture it twice across two dynamic imports (or drop the line).
♻️ Suggested change
expect(XTERM_WEBVIEW_SOURCE).toEqual({ html: XTERM_HTML }) - expect(XTERM_WEBVIEW_SOURCE).toBe(XTERM_WEBVIEW_SOURCE) + const reimported = await import('./terminal-webview-html') + expect(reimported.XTERM_WEBVIEW_SOURCE).toBe(XTERM_WEBVIEW_SOURCE)
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 880496ac-88dc-472d-88d8-203c884ccc57
📒 Files selected for processing (224)
mobile/app/_layout.tsxmobile/app/about.tsxmobile/app/browser-settings.tsxmobile/app/connection-log.tsxmobile/app/h/[hostId]/accounts-screen-styles.tsmobile/app/h/[hostId]/accounts.tsxmobile/app/h/[hostId]/edit.tsxmobile/app/h/[hostId]/index.tsxmobile/app/h/[hostId]/session/QuickCommandsTabButton.tsxmobile/app/h/[hostId]/session/[worktreeId].tsxmobile/app/h/[hostId]/session/mobile-session-command-input-styles.tsmobile/app/h/[hostId]/session/mobile-session-frame-styles.tsmobile/app/h/[hostId]/session/mobile-session-reader-styles.tsmobile/app/h/[hostId]/session/mobile-session-review-comment-styles.tsmobile/app/h/[hostId]/session/mobile-session-styles.tsmobile/app/h/[hostId]/tasks.tsxmobile/app/h/_layout.tsxmobile/app/index.tsxmobile/app/mobile-onboarding.tsxmobile/app/native-chat-settings.tsxmobile/app/notifications.tsxmobile/app/pair-confirm.tsxmobile/app/pair-scan.tsxmobile/app/pair.tsxmobile/app/settings.tsxmobile/app/terminal-settings.tsxmobile/app/troubleshoot.tsxmobile/app/voice-settings.tsxmobile/src/agent-history/MobileAgentSessionHistoryList.tsxmobile/src/agent-history/MobileAgentSessionHistoryPanel.tsxmobile/src/agent-history/agent-history-styles.tsmobile/src/agent-history/worktree-navigation-actions.tsmobile/src/browser/MobileBrowserKeyRow.tsxmobile/src/browser/MobileBrowserPane.tsxmobile/src/browser/MobileBrowserPointerModifiers.tsxmobile/src/browser/MobileBrowserToolbarIconButton.tsxmobile/src/browser/MobileBrowserViewModeSwitch.tsxmobile/src/components/AccountUsage.tsxmobile/src/components/ActionSheetModal.tsxmobile/src/components/AgentIcons.tsxmobile/src/components/AuthFailedBanner.tsxmobile/src/components/CodexResetCreditAction.tsxmobile/src/components/ConfirmModal.tsxmobile/src/components/ConnectionLog.tsxmobile/src/components/CustomKeyModal.tsxmobile/src/components/DragReorderList.tsxmobile/src/components/HostProtocolGate.tsxmobile/src/components/MobileAgentIcon.tsxmobile/src/components/MobileDictationSetupSheet.tsxmobile/src/components/MobileDiffReviewBody.tsxmobile/src/components/MobileDiffReviewDrawers.tsxmobile/src/components/MobileDiffReviewFileSummary.tsxmobile/src/components/MobileDiffReviewFooter.tsxmobile/src/components/MobileDiffReviewHeader.tsxmobile/src/components/MobileDiffReviewLine.tsxmobile/src/components/MobileDiffReviewScreenView.tsxmobile/src/components/MobileHostCard.tsxmobile/src/components/MobileHtmlPreview.tsxmobile/src/components/MobileMarkdown.tsxmobile/src/components/MobilePRSidebar.tsxmobile/src/components/MobilePrBasePicker.tsxmobile/src/components/MobileRepoIcon.tsxmobile/src/components/MobileRichMarkdownEditor.tsxmobile/src/components/MobileSearchField.tsxmobile/src/components/MobileSyntaxSegments.tsxmobile/src/components/NewWorkspaceFab.tsxmobile/src/components/NewWorktreeModal.tsxmobile/src/components/OrcaLogo.tsxmobile/src/components/PickerListDrawer.tsxmobile/src/components/PickerModal.tsxmobile/src/components/ProtocolBlockScreen.tsxmobile/src/components/RightDrawer.tsxmobile/src/components/SetupHookTrustDrawer.tsxmobile/src/components/SmartWorkspaceAdvancedFields.tsxmobile/src/components/SmartWorkspaceSourceDrawer.tsxmobile/src/components/SmartWorkspaceSourceField.tsxmobile/src/components/SmartWorkspaceSourceRow.tsxmobile/src/components/StatusDot.tsxmobile/src/components/TerminalShortcutSettings.tsxmobile/src/components/TextInputModal.tsxmobile/src/components/VoiceModelList.tsxmobile/src/components/WorkspaceDetailPlaceholder.tsxmobile/src/components/WorktreeAgentRow.tsxmobile/src/components/WorktreeListRow.tsxmobile/src/components/WorktreeMetaGlyphs.tsxmobile/src/components/bottom-drawer-styles.tsmobile/src/components/custom-key-modal-styles.tsmobile/src/components/mobile-diff-review-control-styles.tsmobile/src/components/mobile-diff-review-layout-styles.tsmobile/src/components/mobile-diff-review-screen-styles.tsmobile/src/components/mobile-markdown-styles.tsmobile/src/components/mobile-rich-markdown-editor-html.test.tsmobile/src/components/mobile-rich-markdown-editor-html.tsmobile/src/components/mobile-rich-markdown-editor-theme.tsmobile/src/components/mounted-bottom-drawer.tsxmobile/src/components/pr-sidebar/CommentMarkdown.tsxmobile/src/components/pr-sidebar/MermaidDiagram.tsxmobile/src/components/pr-sidebar/MobileLinkPrForm.tsxmobile/src/components/pr-sidebar/MobilePrComposeForm.tsxmobile/src/components/pr-sidebar/MobilePrViewPanel.tsxmobile/src/components/pr-sidebar/PRActionsSection.tsxmobile/src/components/pr-sidebar/PRCheckDetail.tsxmobile/src/components/pr-sidebar/PRChecksSection.tsxmobile/src/components/pr-sidebar/PRCommentCard.tsxmobile/src/components/pr-sidebar/PRCommentComposer.tsxmobile/src/components/pr-sidebar/PRCommentsSection.test.tsmobile/src/components/pr-sidebar/PRCommentsSection.tsxmobile/src/components/pr-sidebar/PRConflictingFilesSection.tsxmobile/src/components/pr-sidebar/PRReviewersSection.tsxmobile/src/components/pr-sidebar/PRSection.tsxmobile/src/components/pr-sidebar/PRSidebarHeader.tsxmobile/src/components/pr-sidebar/PrSidebarCreateEmptyState.tsxmobile/src/components/pr-sidebar/ReviewerPickerDrawer.tsxmobile/src/components/pr-sidebar/mobile-pr-compose-form-styles.tsmobile/src/components/pr-sidebar/mobile-pr-sidebar-styles.tsmobile/src/components/pr-sidebar/pr-actions-styles.tsmobile/src/components/pr-sidebar/pr-ai-triage-styles.tsmobile/src/components/pr-sidebar/pr-comment-composer-styles.tsmobile/src/components/pr-sidebar/pr-comments-styles.tsmobile/src/components/pr-sidebar/pr-conflict-styles.tsmobile/src/components/pr-sidebar/pr-create-empty-state-styles.tsmobile/src/components/pr-sidebar/pr-sidebar-status-color.tsmobile/src/components/pr-state-token.test.tsmobile/src/components/smart-workspace-source-drawer-styles.tsmobile/src/components/terminal-shortcut-settings-styles.tsmobile/src/diagnostics/troubleshoot-common-issues.tsxmobile/src/dictation/voice-settings-styles.tsmobile/src/files/MobileFileExplorerPanel.tsxmobile/src/files/MobileFileMarkdownPreview.test.tsmobile/src/files/MobileFileMarkdownPreview.tsxmobile/src/files/MobileFilePreviewBody.tsxmobile/src/files/MobileFilePreviewEditableSource.tsxmobile/src/files/MobileFilePreviewScreen.tsxmobile/src/files/MobileFilePreviewSourceText.tsxmobile/src/files/mobile-file-explorer-row.tsxmobile/src/files/mobile-file-explorer-styles.tsmobile/src/files/mobile-file-preview-styles.tsmobile/src/host/host-screen-chrome-styles.tsmobile/src/host/host-screen-styles.tsmobile/src/host/host-worktree-list-styles.tsmobile/src/onboarding/MobileOnboardingPage.tsxmobile/src/onboarding/mobile-onboarding-screen.test.tsmobile/src/onboarding/mobile-onboarding-styles.tsmobile/src/session/MobileAgentWorkingIndicator.tsxmobile/src/session/MobileNativeChatAsk.tsxmobile/src/session/MobileNativeChatComposer.tsxmobile/src/session/MobileNativeChatMessage.tsxmobile/src/session/MobileNativeChatPermission.tsxmobile/src/session/MobileNativeChatQuestion.tsxmobile/src/session/MobileNativeChatView.tsxmobile/src/session/MobileSessionHeaderIconButton.tsxmobile/src/session/MobileSessionHeaderMoreActionsSheet.tsxmobile/src/session/MobileTerminalInputActions.tsxmobile/src/session/MobileTerminalLiveInputStatus.tsxmobile/src/session/QuickCommandEditorForm.tsxmobile/src/session/QuickCommandsList.tsxmobile/src/session/QuickCommandsSheet.tsxmobile/src/session/SessionDockColumn.tsxmobile/src/session/TerminalPaneView.test.tsmobile/src/session/TerminalPaneView.tsxmobile/src/session/mobile-native-chat-message-styles.tsmobile/src/session/mobile-native-chat-view-styles.tsmobile/src/source-control/MobileBranchDiffPreviewDrawer.tsxmobile/src/source-control/MobileCommitFailurePanel.tsxmobile/src/source-control/MobileGitHistoryList.tsxmobile/src/source-control/MobileSourceControlBranchCard.tsxmobile/src/source-control/MobileSourceControlContent.tsxmobile/src/source-control/MobileSourceControlCreatePrEntry.tsxmobile/src/source-control/MobileSourceControlFileRows.tsxmobile/src/source-control/MobileSourceControlHeader.tsxmobile/src/source-control/MobileSourceControlPanel.tsxmobile/src/source-control/MobileSourceControlPrChip.tsxmobile/src/source-control/MobileSourceControlSegments.tsxmobile/src/source-control/mobile-source-control-diff-styles.tsmobile/src/source-control/mobile-source-control-hub-styles.tsmobile/src/source-control/mobile-source-control-list-styles.tsmobile/src/source-control/mobile-source-control-screen-state.tsmobile/src/source-control/mobile-source-control-styles.tsmobile/src/storage/preferences.test.tsmobile/src/storage/preferences.tsmobile/src/storage/terminal-theme-preference.test.tsmobile/src/storage/terminal-theme-preference.tsmobile/src/tasks/tasks-screen-chrome-styles.tsmobile/src/tasks/tasks-screen-detail-styles.tsmobile/src/tasks/tasks-screen-form-styles.tsmobile/src/tasks/tasks-screen-list-styles.tsmobile/src/tasks/tasks-screen-misc-styles.tsmobile/src/tasks/tasks-screen-panel-styles.tsmobile/src/tasks/tasks-screen-styles.tsmobile/src/terminal/TerminalWebView.test.tsmobile/src/terminal/TerminalWebView.tsxmobile/src/terminal/terminal-theme-slot-selection.test.tsmobile/src/terminal/terminal-theme-slot-selection.tsmobile/src/terminal/terminal-webview-engine-error-state.tsxmobile/src/terminal/terminal-webview-frame-styles.tsmobile/src/terminal/terminal-webview-html-app-chrome.test.tsmobile/src/terminal/terminal-webview-html.tsmobile/src/terminal/terminal-webview-messages.tsmobile/src/terminal/terminal-webview-theme-injected.test.tsmobile/src/terminal/terminal-webview-theme-injected.tsmobile/src/terminal/use-mobile-terminal-theme.test.tsmobile/src/terminal/use-mobile-terminal-theme.tsmobile/src/theme/app-shell-theme.test.tsmobile/src/theme/mobile-theme-palette.test.tsmobile/src/theme/mobile-theme.tsmobile/src/theme/theme-context.test.tsmobile/src/theme/theme-context.tsxmobile/src/theme/themed-style-factories.test.tsmobile/src/theme/unthemed-color-imports.test.tssrc/renderer/src/lib/terminal-contrast-correction.test.tssrc/renderer/src/lib/terminal-theme.tssrc/renderer/src/lib/terminal-themes-data.tssrc/renderer/src/lib/terminal-themes/index.tssrc/renderer/src/lib/terminal-themes/types.tssrc/shared/terminal-themes/catalog-merge.tssrc/shared/terminal-themes/classic.tssrc/shared/terminal-themes/defaults.tssrc/shared/terminal-themes/index.tssrc/shared/terminal-themes/popular-dark-core.tssrc/shared/terminal-themes/popular-dark-extended.tssrc/shared/terminal-themes/popular-dark.tssrc/shared/terminal-themes/popular-light.tssrc/shared/terminal-themes/terminal-theme-catalog.test.tssrc/shared/terminal-themes/types.ts
🚧 Files skipped from review as they are similar to previous changes (196)
- src/shared/terminal-themes/popular-light.ts
- mobile/src/host/host-screen-styles.ts
- mobile/app/h/[hostId]/accounts-screen-styles.ts
- mobile/app/h/[hostId]/session/mobile-session-styles.ts
- src/shared/terminal-themes/popular-dark.ts
- mobile/src/terminal/terminal-theme-slot-selection.ts
- mobile/src/agent-history/agent-history-styles.ts
- mobile/app/h/[hostId]/session/QuickCommandsTabButton.tsx
- src/shared/terminal-themes/classic.ts
- mobile/src/terminal/use-mobile-terminal-theme.ts
- mobile/src/files/mobile-file-explorer-styles.ts
- mobile/src/components/MobileDiffReviewHeader.tsx
- mobile/src/components/pr-sidebar/mobile-pr-sidebar-styles.ts
- mobile/src/components/pr-sidebar/pr-comment-composer-styles.ts
- src/shared/terminal-themes/types.ts
- src/shared/terminal-themes/catalog-merge.ts
- mobile/app/native-chat-settings.tsx
- mobile/src/components/pr-sidebar/pr-conflict-styles.ts
- mobile/src/components/pr-sidebar/PRCommentsSection.test.ts
- mobile/src/dictation/voice-settings-styles.ts
- mobile/src/agent-history/MobileAgentSessionHistoryPanel.tsx
- mobile/src/source-control/mobile-source-control-diff-styles.ts
- mobile/src/onboarding/mobile-onboarding-screen.test.ts
- mobile/src/components/pr-sidebar/PRCheckDetail.tsx
- mobile/app/h/[hostId]/session/mobile-session-frame-styles.ts
- mobile/src/agent-history/worktree-navigation-actions.ts
- mobile/app/mobile-onboarding.tsx
- mobile/src/components/pr-sidebar/pr-sidebar-status-color.ts
- mobile/src/components/pr-sidebar/PRCommentComposer.tsx
- mobile/src/host/host-screen-chrome-styles.ts
- mobile/app/pair-confirm.tsx
- mobile/src/terminal/TerminalWebView.test.ts
- src/shared/terminal-themes/defaults.ts
- mobile/src/source-control/MobileSourceControlCreatePrEntry.tsx
- mobile/src/files/MobileFilePreviewEditableSource.tsx
- src/renderer/src/lib/terminal-contrast-correction.test.ts
- mobile/app/h/[hostId]/edit.tsx
- mobile/src/components/pr-sidebar/PRReviewersSection.tsx
- src/shared/terminal-themes/terminal-theme-catalog.test.ts
- mobile/app/h/[hostId]/session/mobile-session-review-comment-styles.ts
- mobile/src/components/pr-sidebar/ReviewerPickerDrawer.tsx
- src/shared/terminal-themes/popular-dark-core.ts
- mobile/src/components/smart-workspace-source-drawer-styles.ts
- mobile/src/components/terminal-shortcut-settings-styles.ts
- mobile/src/source-control/MobileSourceControlPanel.tsx
- mobile/src/terminal/terminal-webview-frame-styles.ts
- mobile/src/source-control/mobile-source-control-styles.ts
- mobile/src/components/WorkspaceDetailPlaceholder.tsx
- mobile/src/components/pr-state-token.test.ts
- mobile/src/tasks/tasks-screen-detail-styles.ts
- mobile/src/diagnostics/troubleshoot-common-issues.tsx
- mobile/src/components/pr-sidebar/mobile-pr-compose-form-styles.ts
- mobile/src/components/OrcaLogo.tsx
- mobile/src/components/pr-sidebar/PRSection.tsx
- mobile/src/components/mobile-markdown-styles.ts
- mobile/src/components/custom-key-modal-styles.ts
- src/shared/terminal-themes/index.ts
- mobile/src/components/mobile-diff-review-layout-styles.ts
- mobile/src/session/MobileTerminalInputActions.tsx
- mobile/src/tasks/tasks-screen-panel-styles.ts
- mobile/src/files/mobile-file-preview-styles.ts
- mobile/src/source-control/mobile-source-control-screen-state.ts
- mobile/src/terminal/terminal-webview-theme-injected.ts
- mobile/src/components/mobile-diff-review-control-styles.ts
- mobile/src/terminal/terminal-theme-slot-selection.test.ts
- mobile/src/components/SmartWorkspaceSourceField.tsx
- mobile/src/components/MobileSyntaxSegments.tsx
- mobile/src/components/ProtocolBlockScreen.tsx
- src/shared/terminal-themes/popular-dark-extended.ts
- mobile/src/components/WorktreeMetaGlyphs.tsx
- mobile/src/components/pr-sidebar/pr-create-empty-state-styles.ts
- mobile/src/components/MobileHtmlPreview.tsx
- mobile/src/source-control/MobileBranchDiffPreviewDrawer.tsx
- mobile/src/source-control/MobileSourceControlHeader.tsx
- mobile/src/components/MobileHostCard.tsx
- mobile/src/onboarding/mobile-onboarding-styles.ts
- mobile/app/connection-log.tsx
- mobile/src/session/QuickCommandEditorForm.tsx
- mobile/src/session/MobileNativeChatPermission.tsx
- mobile/src/session/MobileNativeChatAsk.tsx
- mobile/src/components/mobile-rich-markdown-editor-html.ts
- mobile/app/h/[hostId]/session/mobile-session-reader-styles.ts
- mobile/src/components/TextInputModal.tsx
- mobile/src/source-control/MobileSourceControlFileRows.tsx
- mobile/src/components/ActionSheetModal.tsx
- mobile/src/components/AccountUsage.tsx
- mobile/src/components/NewWorkspaceFab.tsx
- mobile/src/components/pr-sidebar/PRSidebarHeader.tsx
- mobile/src/components/SetupHookTrustDrawer.tsx
- mobile/src/source-control/MobileSourceControlContent.tsx
- mobile/app/settings.tsx
- mobile/src/terminal/terminal-webview-messages.ts
- mobile/src/storage/preferences.test.ts
- mobile/src/tasks/tasks-screen-form-styles.ts
- mobile/src/components/WorktreeAgentRow.tsx
- mobile/src/session/MobileNativeChatComposer.tsx
- mobile/app/terminal-settings.tsx
- mobile/src/components/MobileDiffReviewBody.tsx
- mobile/src/components/mobile-diff-review-screen-styles.ts
- mobile/src/agent-history/MobileAgentSessionHistoryList.tsx
- mobile/src/components/MobileSearchField.tsx
- src/renderer/src/lib/terminal-theme.ts
- mobile/src/browser/MobileBrowserViewModeSwitch.tsx
- mobile/src/components/HostProtocolGate.tsx
- mobile/src/session/MobileTerminalLiveInputStatus.tsx
- mobile/src/theme/mobile-theme.ts
- mobile/src/components/mounted-bottom-drawer.tsx
- mobile/src/files/MobileFileMarkdownPreview.tsx
- mobile/src/browser/MobileBrowserPointerModifiers.tsx
- mobile/app/index.tsx
- mobile/src/source-control/MobileSourceControlPrChip.tsx
- mobile/src/files/MobileFilePreviewSourceText.tsx
- mobile/src/components/AgentIcons.tsx
- mobile/src/components/StatusDot.tsx
- mobile/src/tasks/tasks-screen-list-styles.ts
- mobile/src/source-control/MobileSourceControlSegments.tsx
- mobile/src/session/TerminalPaneView.tsx
- mobile/src/browser/MobileBrowserToolbarIconButton.tsx
- mobile/src/components/mobile-rich-markdown-editor-theme.ts
- mobile/src/components/pr-sidebar/PrSidebarCreateEmptyState.tsx
- mobile/app/h/[hostId]/session/[worktreeId].tsx
- mobile/src/onboarding/MobileOnboardingPage.tsx
- mobile/src/files/MobileFileMarkdownPreview.test.ts
- mobile/src/terminal/use-mobile-terminal-theme.test.ts
- mobile/src/browser/MobileBrowserKeyRow.tsx
- mobile/src/components/SmartWorkspaceSourceDrawer.tsx
- mobile/src/source-control/MobileGitHistoryList.tsx
- mobile/src/session/mobile-native-chat-message-styles.ts
- mobile/src/components/CodexResetCreditAction.tsx
- mobile/app/_layout.tsx
- mobile/src/components/AuthFailedBanner.tsx
- mobile/src/files/MobileFilePreviewBody.tsx
- mobile/src/components/pr-sidebar/pr-comments-styles.ts
- mobile/src/browser/MobileBrowserPane.tsx
- mobile/src/files/MobileFilePreviewScreen.tsx
- mobile/src/source-control/mobile-source-control-hub-styles.ts
- mobile/app/pair.tsx
- mobile/src/components/mobile-rich-markdown-editor-html.test.ts
- mobile/src/components/MobileDiffReviewFooter.tsx
- mobile/src/session/MobileNativeChatMessage.tsx
- mobile/src/components/bottom-drawer-styles.ts
- mobile/app/troubleshoot.tsx
- mobile/app/h/[hostId]/accounts.tsx
- mobile/src/components/MobilePRSidebar.tsx
- mobile/src/theme/theme-context.test.ts
- mobile/src/session/MobileAgentWorkingIndicator.tsx
- mobile/src/source-control/mobile-source-control-list-styles.ts
- mobile/src/components/CustomKeyModal.tsx
- mobile/app/voice-settings.tsx
- mobile/src/components/pr-sidebar/CommentMarkdown.tsx
- mobile/src/components/MobileDiffReviewDrawers.tsx
- mobile/src/components/WorktreeListRow.tsx
- mobile/app/h/[hostId]/session/mobile-session-command-input-styles.ts
- mobile/src/source-control/MobileCommitFailurePanel.tsx
- mobile/src/terminal/terminal-webview-theme-injected.test.ts
- mobile/src/components/DragReorderList.tsx
- mobile/src/tasks/tasks-screen-styles.ts
- mobile/src/storage/terminal-theme-preference.test.ts
- mobile/src/components/pr-sidebar/PRConflictingFilesSection.tsx
- mobile/src/components/MobileRichMarkdownEditor.tsx
- mobile/src/session/MobileNativeChatQuestion.tsx
- mobile/src/storage/preferences.ts
- mobile/src/session/MobileSessionHeaderMoreActionsSheet.tsx
- mobile/src/components/pr-sidebar/PRCommentCard.tsx
- mobile/src/components/SmartWorkspaceSourceRow.tsx
- mobile/src/components/MobileDiffReviewScreenView.tsx
- mobile/src/components/pr-sidebar/MobilePrComposeForm.tsx
- mobile/src/components/MobileRepoIcon.tsx
- mobile/src/tasks/tasks-screen-misc-styles.ts
- mobile/src/components/MobileAgentIcon.tsx
- mobile/src/components/MobileMarkdown.tsx
- mobile/src/components/ConnectionLog.tsx
- mobile/src/components/pr-sidebar/PRChecksSection.tsx
- mobile/src/components/MobileDiffReviewFileSummary.tsx
- mobile/src/components/MobileDictationSetupSheet.tsx
- mobile/src/components/ConfirmModal.tsx
- mobile/src/components/MobileDiffReviewLine.tsx
- mobile/src/terminal/terminal-webview-engine-error-state.tsx
- mobile/src/components/pr-sidebar/PRCommentsSection.tsx
- mobile/src/components/SmartWorkspaceAdvancedFields.tsx
- mobile/src/theme/theme-context.tsx
- mobile/src/components/pr-sidebar/PRActionsSection.tsx
- mobile/app/h/[hostId]/index.tsx
- mobile/src/terminal/TerminalWebView.tsx
- mobile/app/h/_layout.tsx
- mobile/src/source-control/MobileSourceControlBranchCard.tsx
- mobile/src/theme/mobile-theme-palette.test.ts
- mobile/src/session/QuickCommandsList.tsx
- mobile/src/tasks/tasks-screen-chrome-styles.ts
- mobile/src/components/NewWorktreeModal.tsx
- mobile/src/components/TerminalShortcutSettings.tsx
- mobile/src/session/QuickCommandsSheet.tsx
- mobile/src/components/pr-sidebar/MobilePrViewPanel.tsx
- mobile/src/terminal/terminal-webview-html.ts
- mobile/src/storage/terminal-theme-preference.ts
- mobile/app/h/[hostId]/tasks.tsx
bb71948 to
f70c6b2
Compare
|
Too many files changed for review. ( Bypass the limit by tagging |
The built-in terminal theme catalog lived under src/renderer/src/lib/, which Metro cannot see: mobile/metro.config.js adds only <repo>/src/shared to watchFolders. Moving it to src/shared/ lets the phone render the exact same 30 palettes the desktop ships instead of a hardcoded copy that silently drifts. Two content changes ride along because they are what makes the destination correct rather than merely reachable: - types.ts drops `@xterm/xterm`'s ITheme for the shared TerminalColorOverrides. It is the same 22 keys plus an optional `bold`, and it is already the mobile wire shape (RuntimeMobileTerminalTheme['theme']). A renderer-only xterm type does not belong in a module Node and Metro both consume. - terminal-themes/shared.ts becomes catalog-merge.ts. "shared.ts" inside src/shared/ names nothing; AGENTS.md bans the vague form outright. index.ts absorbs the two one-line functions from terminal-themes-data.ts under domain-concrete names, so src/shared never exports a bare `getTheme`, and that file is deleted rather than left as a shim: only three call sites referenced the old paths repo-wide. The catalog had no test of its own. The new one pins the count at 30 (a naive grep for quoted keys reports 22 because eight themes use unquoted keys), pins the two shipped default names — the display name IS the persisted settings id — and asserts every palette defines exactly the 22 keys mobile's WebView copies, so no theme can render half-default on the phone. Behaviour is unchanged: terminal-theme.ts's export surface is identical, and terminal-contrast-correction.test.ts passes with only its import path edited, which is the proof no palette value moved.
getBuiltinTerminalThemePalette must only return own catalog entries so persisted or typed ids like constructor/toString never resolve through Object.prototype. Merge into a null-prototype map and pin the reject list.
On `orca serve` / SSH hosts the phone has no say in its terminal palette:
it renders whatever the host pushes, or a hardcoded Tokyo Night when the
host pushes nothing. Give the device its own choice, mirroring desktop's
model exactly — a dark slot, a light slot, and `useSeparateLightTheme`
(default true, `src/shared/constants.ts`) — so the two products describe
the same concept with the same words and the same asymmetry (light mode
without a separate light theme uses the dark slot, still reporting light).
A `null` slot is stored as an absent key, so a fresh install and an
explicit "follow desktop" choice are one state: no migration, and no magic
string that a future built-in name could collide with. Nothing is
user-visible yet — with nothing stored the resolver is pure passthrough,
so today's host-follows behaviour is unchanged until the picker lands.
The store lives in its own module rather than `preferences.ts` (which the
app-theme preference will need room in), validates persisted names against
the shared catalog at load so a renamed built-in degrades to "follow
desktop" instead of a blank terminal, and publishes through
`useSyncExternalStore` so a write repaints mounted panes with no
navigation event — which also keeps the override out of the session
screen and out of the record layer's JSON change-detection entirely.
`TerminalPaneView.test.ts` pins the one seam the feature hangs on:
reverting the single `terminalTheme={resolvedTerminalTheme}` line passes
every other test in this change.
…RN frame The frame around the terminal WebView paints the app palette's `terminalBg`. That was invisible while the palette and the terminal were both dark, but device-local theme selection lets a user pick a light terminal inside dark app chrome, which would render the WebView inside a dark halo. The divergence is created by that change, so the fix ships with it; `colors.terminalBg` stays the fallback until a palette arrives.
…r theme slots A save issued before the store had read AsyncStorage merged the patch onto the in-memory default and then wrote all three keys, destroying the two slots it never touched; the `hydrated` flag it set also made the in-flight load discard the stored values for good. The save now hydrates first when the read has not landed yet, still publishing optimistically so a tap repaints live panes without waiting for storage, and the load publishes unconditionally so the patch merges onto a real snapshot. Also: a failed read no longer stays memoised for the whole session, the cold-start hydration effect is pinned by a test (removing it previously passed every test), and the frame background keeps the spec's `theme?.background` guard so a version-mismatched or third-party host that pushes a palette-less payload falls back instead of crashing the pane.
…hed slots A rejected read leaves the merge base at the in-memory default while writes may still succeed, so writing all three keys erased the slots the patch never named. Only patched slots are written in that state. Also pins the WebView normalizer's whitelist against the shared catalog on the side that owns it, so a catalog slot mobile does not know can never silently render half-default.
Rename the existing tokens to darkColors, add lightColors (31 keys) derived from the desktop light tokens, and keep `export const colors = darkColors` so unconverted modules keep compiling and rendering dark. Pin the NewWorkspaceFab pressed state to surfaceBrightPressed (byte- identical in dark). Seed the unthemed-import ratchet and an empty themed-style-factories suite for the migration batches.
Catch unparenthesized useThemedStyles arrow factories in the ratchet, and assert the themed-style factory registry starts empty so later conversion batches must register deliberately rather than leaving a vacuous suite.
Add ThemeProvider / useTheme / useThemedStyles with an explicit resolved mode, persist orca:appTheme defaulting to dark (no visible change), and wire the root + host shells through the runtime. Terminal slot selection falls back to the desktop default for the app mode when the host palette mode mismatches. Drop the two converted layout paths from the unthemed import ratchet.
Restore pure host passthrough for a null or uncatalogued terminal theme slot. The mode-mismatch fallback is correct in principle but not invisible on this branch: DEFAULT_APP_THEME is always dark and Appearance is not revealed until later, so the branch would only fire for light-desktop hosts and silently replace their light host palette with Ghostty Default Style Dark. Defer that logic to the PR that reveals Appearance, when a user can actually select light. Keep useTheme() mode threading; it is a no-op while mode is fixed to dark.
setAppTheme already updates preference optimistically and fire-and-forgets saveAppTheme; a rejected AsyncStorage write must not become an unhandled rejection (loadAppTheme already falls back on read errors).
…ch 1/17) Convert shared drawer, modal, and picker primitives to ThemeColors factories consumed via useThemedStyles. Scrim rgba(0,0,0,0.5) and shadowColor '#000' stay literal (one scrim/shadow in both modes). Drop the ten converted paths from the unthemed-import ratchet and register the exported factories.
Convert badge, icon, and banner chrome to useTheme / useThemedStyles. Move default color params into the body so they are not frozen at module load. Leave vendor brand literals fixed: Claude #D97757 and the OMP gradient stops. Drop fourteen converted paths from the unthemed ratchet.
Move the StyleSheet out of voice-settings.tsx into voice-settings-styles.ts so the screen has room for the upcoming ThemeColors conversion (was 394/400). Values are byte-identical.
Convert settings-family screens and related components to ThemeColors factories. voice-settings-styles.ts is a ThemeColors factory after the prior pure extraction. troubleshoot-common-issues becomes a function of colors so icons are not frozen at module load. Drop eleven converted paths from the unthemed ratchet.
…h 4/17) Convert the terminal-settings screen, the shortcut editor and its supporting primitives to ThemeColors factories. Dark-mode values are unchanged: every StyleSheet body is byte-identical modulo the factory wrapper. Two files had no line-cap headroom (TerminalShortcutSettings 399/400, CustomKeyModal 645/645), so their sheets move into new modules. Unlike the batch-3 voice-settings split, the extracted modules are born themed — a pure extract would add a bare `colors` importer the ratchet does not list, leaving that intermediate commit red. DragReorderList's animated row background is hoisted to two string locals before the worklet so the animated style stays shareable rather than cloning the whole palette to the UI runtime. Ratchet: 119 -> 113 unthemed importers. Factory suite covers all five new factories (terminal-settings is an app screen vitest cannot load).
Convert the three pairing screens, the onboarding page and MobileHostCard to ThemeColors factories. Every StyleSheet body is byte-identical modulo the factory wrapper. app/mobile-onboarding.tsx is in no batch of the migration plan: the batches were partitioned from the unthemed-color-imports ratchet, which only lists files importing `colors` directly, so a file that merely consumes an exported sheet is invisible to it. Converting mobile-onboarding-styles.ts to a factory breaks that consumer, so it comes along here. Nine more such files exist further down the plan. mobile-onboarding-screen.test.ts replaced the whole storage/preferences module with a single-key mock; theme-context binds DEFAULT_APP_THEME/loadAppTheme/ saveAppTheme from it at import time, so the mock gains those three. Ratchet: 113 -> 107 unthemed importers.
Convert the home list, host worktree screen, host edit/accounts, and the new-worktree modal to ThemeColors factories. Dark-mode values are unchanged: every StyleSheet body is byte-identical modulo the factory wrapper (host index proven as chrome+list merge). Host index sat at 1594/1603 with a 306-line sheet over the 300 .ts cap, so the sheet splits into two born-themed modules (chrome + list) plus a thin aggregator — no bare-colors intermediate. Ratchet: 107 -> 101 unthemed importers. Factory suite covers accounts and both host-index sheet halves.
…batch 7/17) Convert smart-workspace source UI, browser pane chrome, and agent session history to ThemeColors factories. Dark-mode values are unchanged: every StyleSheet body is byte-identical modulo the factory wrapper. buildWorktreeNavigationActions takes an explicit colors argument so the history icon is not frozen to the dark alias at import time. Browser scrims stay the existing rgba(13,15,24,…) literals. Ratchet: 101 -> 87 unthemed importers.
Convert the four mobile-session-*-styles modules, the hidden aggregator mobile-session-styles.ts, the session screen and its header/tab helpers, and the terminal engine-error overlay to ThemeColors factories. Dark-mode values are unchanged: every StyleSheet body is byte-identical modulo the factory wrapper. mobile-session-styles.ts was not in the ratchet (it only re-exported StyleSheet objects) but would break once its providers became factories; it is converted in this batch as createMobileSessionStyles. Ratchet: 87 -> 77 unthemed importers. Did not touch terminal-webview-frame- styles (terminal theme, not app theme).
…ch 9/17)
Convert QuickCommands{List,Sheet}, QuickCommandEditorForm, the native-chat
view/message style modules and co-located chat components, and
MobileRichMarkdownEditor (+ its HTML builder) to ThemeColors factories.
Dark-mode values are unchanged: every StyleSheet body is byte-identical
modulo the factory wrapper; the HTML builder proves string-identical under
darkColors against the pre-conversion module.
mobile-rich-markdown-editor-html injects colors into an HTML/CSS string
rather than StyleSheet — sheetcheck cannot cover it, so identity is proven
by expanding both builders with darkColors.
Ratchet: 77 -> 64 unthemed importers. Factory suite registers the two pure
style modules (component-co-located factories stay under sheetcheck).
Convert mobile-markdown-styles, the mobile-diff-review control/layout factories (and their hidden merge consumer mobile-diff-review-screen-styles), the diff-review screen components, MobileHtmlPreview, and MobileSyntaxSegments to ThemeColors factories. Dark-mode values are unchanged: every StyleSheet body is byte-identical modulo the factory wrapper. mobile-diff-review-screen-styles was not in the ratchet (it only re-exported StyleSheet objects) but would break once its providers became factories; it is converted as createMobileDiffReviewStyles with layout-then-control spread order preserved (44+19=63 unique keys, no collisions). MobileMarkdown is pulled in as the sole consumer of the markdown sheet. Ratchet: 64 -> 53 unthemed importers.
Convert the source-control style modules (base/list/diff hub), the merge factory, screen-state statusColor helper, panel/content/header/file rows, branch card, PR chip, history list, commit-failure panel, branch-diff drawer, and MobileSourceControlSegments to ThemeColors factories. Dark-mode values are unchanged: every StyleSheet body is byte-identical modulo the factory wrapper. mobile-source-control-styles merges base then list then diff (42+49+19=110 unique keys, no collisions), matching the pre-conversion spread order. statusColor now takes ThemeColors so call sites thread the active palette. MobileSourceControlSegments was a hidden hubStyles consumer and is included. Ratchet: 53 -> 38 unthemed importers.
…/17) Convert mobile-file-explorer-styles, mobile-file-preview-styles, and their panel/row/preview consumers to ThemeColors factories. Pull in the hidden preview consumers MobileFilePreviewEditableSource and MobileFilePreviewSourceText (not in the ratchet; they only re-exported filePreviewStyles). Dark-mode values are unchanged: every StyleSheet body is byte-identical modulo the factory wrapper. Ratchet: 38 -> 31 unthemed importers.
Convert mobile-pr-sidebar-styles, pr-ai-triage-styles, pr-conflict-styles, and the B13 sidebar consumers to ThemeColors factories. Pull in the hidden consumers MobileDiffReviewScreenView, PRSection, SessionDockColumn, and rewire PRCommentsSection's shared sidebar styles (it no longer bare-imports colors; pr-comments-styles stays for B14). Dark-mode StyleSheet bodies are byte-identical modulo the factory wrapper. Ratchet: 31 -> 20 unthemed importers.
… 14/17) Convert pr-comments-styles, pr-comment-composer-styles, CommentMarkdown, MermaidDiagram, PRCommentCard/Composer, and statusColor(token, colors). Call sites in the sidebar header, checks, source-control PR chip, and WorktreeMetaGlyphs/prStateColor thread ThemeColors. Dark-mode StyleSheet bodies stay byte-identical modulo the factory wrapper. Ratchet: 20 -> 13 unthemed importers.
Convert compose-form, actions, create-empty-state styles and their consumers, plus MobileLinkPrForm, MobilePrViewPanel, and MobilePrBasePicker. Dark-mode StyleSheet bodies are byte-identical modulo the factory wrapper. Ratchet: 13 -> 4 unthemed importers.
…atch 16/17) Convert terminal-webview-frame-styles to a ThemeColors factory so the RN frame fallback follows the app palette (lightColors.terminalBg is #ffffff); TerminalWebView still overlays frameOverride from the resolved terminal palette. Do NOT make XTERM_HTML a function of the app palette: XTERM_WEBVIEW_SOURCE stays a module constant so theme flips never remount the WebView. The four static color interpolations become CSS custom properties with dark defaults matching today; applyTerminalTheme (and init) set --terminal-fallback-bg and --terminal-scrollbar from an appChrome payload on the existing set-theme/init live channel. Ratchet: 4 -> 1 unthemed importer (tasks.tsx remains for B17).
Convert mobile tasks screen styles. The file had zero max-lines headroom, so the StyleSheet is extracted into six born-themed modules plus a merge factory (createTasksScreenStyles). entrycheck proves 250/250 style entries across the split with no collisions. Color helpers take ThemeColors; components call useTheme/useThemedStyles. app/index.tsx was already converted in batch 6 (batches.txt index.tsx-DUP). Ratchet: 1 -> 0 unthemed importers. Migration complete.
`statCard` hardcoded `rgba(26,26,26,0.6)` — rgb(26,26,26) is darkColors.bgPanel. Over the dark bgBase it reads as a subtle panel; over the light bgBase it composites to roughly #767676, and the 11px `textMuted` labels on top land at about 1.2:1. Confirmed on a device: "Agents spawned" / "Agent time" / "PRs created" were unreadable while every sibling card rendered correctly. The literal predates this migration, so nothing in the themed-styles chain could catch it: it is not a `colors.*` reference, so the stylesheet byte-identity and palette-token checks pass by construction, and the both-palettes factory test only asserts matching key sets plus inequality. Introduces `statTileSurface` rather than reusing `bgPanel` so dark stays pixel-identical — the dark value is the original literal. Light mirrors the construction (a few percent of ink over bgBase) and composites to exactly bgPanel, matching the sibling cards. Swept every stylesheet for literals whose RGB equals a dark palette token: 18 hits, all others deliberate — REPO_COLORS is a fixed categorical ramp, the rgba(255,255,255,0.04) overlays only lose a surface in light (one keeps a borderSubtle outline), and the red washes plus on-fill whites are mode-fixed.
… tree expo-router registers every file under `app/` as a route, so the eleven style modules this migration extracted there each produced `Route "…" is missing the required default export` and became a navigable path that renders nothing. Measured on a device: 19 such warnings before, 8 after. Destinations follow the existing `src/onboarding/mobile-onboarding-styles.ts` precedent — feature-area directory under `src/`, route stays in `app/`: voice-settings-styles to `src/dictation/` (it styles the screen that configures dictation), the three host-screen modules to a new `src/host/`, the seven tasks-screen modules to the existing `src/tasks/`. Only `src/host/` is new; every other feature area already has its directory, host overview was the one that still kept all its code inside `app/`. Moved with `git mv` so the rename is recorded. No behaviour change — only import paths move (the modules' own `mobile-theme` depth, the three screen consumers, the two merge modules' sibling imports, and eight dynamic imports in the factory suite). The remaining eight warnings are pre-existing files no batch owns, and are not all stylesheets — one is types-only and one is a component. Left alone here.
Upstream 4a71a0e added CodexResetCreditAction with a bare colors import. Convert it to createCodexResetCreditActionStyles + useThemedStyles so the unthemed-color-imports ratchet stays empty after the main rebase, and register the factory in the both-palettes suite.
The custom-key modal fills a selected modifier chip with textPrimary, so the glyph on it has to invert with the palette. It was the literal rgba(10,10,10,0.5) — readable over dark's #e0e0e0 fill, but in light the fill is #0a0a0a and the same ink at 50% composites onto itself: contrast 1.00, glyph gone. onInvertedMuted keeps dark byte-identical (the literal is the dark value) and mirrors the construction from the other side in light, ~5.4:1.
Before this migration `colors` was a module import and `styles` a module constant, so a memo that read them needed neither in its dependency array. Both are hook-derived now, and eight sites still omitted them — the memo keeps the previous palette until an unrelated dependency changes. Visible cases: the git history list is memo'd and stays mounted, so its chevrons and row chrome kept the old palette until a row expanded; the mermaid diagram kept rendering its SVG in the previous theme; the tasks screen held stale accent and icon colours in its provider, sort and Linear grouping memos.
Both fixes this migration needed were colour literals that survived inside a themed factory: invisible in dark, wrong in light. No existing guard sees that class — the sheets are byte-identical under dark and the both-palettes suite still reports a difference — so add one, with the fifteen deliberate literals (scrims, shadowColor, on-statusRed text, the HTML preview canvas) listed with the reason each is mode-independent. The factory suite also only proves something about the factories it was told to load: 110 are declared, 72 are reached. Assert that every declared factory is either registered, spread into a registered merge factory, or listed as not loadable under vitest, so a new one cannot land uncovered in silence. Registers createHostScreenStyles, the one pure style module that was missing.
SectionList file rows render as a real component so hooks stay legal. Home icon wells use surfaceFaint so light mode keeps lift; destructive on-fill text uses onStatusRed. The rich markdown editor pins its HTML document and injects CSS vars on theme flip instead of remounting, so in-progress edits are not lost. Mermaid uses theme base with mode-driven darkMode; tasks section memo lists colors.
…ry-sheet lookup CodeRabbit follow-ups on the themed-styles stack: - Minor: the inject payload and the generated editor HTML both set --editor-surface to bgBase instead of the distinct editorSurface token, so theme flips flatten the editor surface to the page base. - Major (test guard): sheetBodyAfter searched forward with no bound, so a factory returning a spread would adopt the next factory's StyleSheet.create. Slice the source at the next factory declaration before scanning. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
f70c6b2 to
4a267c1
Compare
Re-cut in progress (Grok handoff from the 2026-08-06 audit)#10490 is not being rebased as one unit. Per the audit: convert to draft and re-cut as ~4 sequenced PRs of ~50 files each on top of the refreshed #10423 theme runtime. Branches ready on
|
| Batch | Branch | Scope | Ratchet Δ | Focused tests |
|---|---|---|---|---|
| 1/4 | recut/10490-batch1-settings @ a7874b59b |
settings / pairing / onboarding / troubleshoot | −14 | 24/24 |
| 2/4 | recut/10490-batch2-session @ dcb49ba99 |
session chrome / browser / agent-history | −20 | 18/18 |
| 3/4 | recut/10490-batch3-sc-pr @ 2bdd09724 |
source-control / PR sidebar / files / diff | −58 | 27/27 |
| 4/4 | recut/10490-batch4-components @ tip |
shared components + light-mode defect tokens | −32 | 22/22 |
Open as draft PRs after #10423 merges (base must be an upstream branch; the runtime branch only lives on the fork today). Sequence: batch1 → batch2 → batch3 → batch4, each retargeted to main once the previous lands.
Intentionally deferred from this re-cut
- Route-tree moves — superseded by
2efc6e547(fix(mobile): stop support modules from registering as routes #11652). Not re-applied. - 27 files with post-2026-07-25 main drift (host index/tasks, home
index.tsx, native-chat views, terminal HTML chrome, etc.) — blind checkout from this tip would drop main features (e.g.HostRouteNoticeBanner). Surgical re-theme after feat(mobile): light/dark theme runtime foundation #10423 lands. - Colour-literal factory guard (MODE_FIXED_FACTORY_LITERALS) — salvage as a small test-only PR once ≥1 batch has landed, per audit.
What stays valuable here
The original 17 mechanical conversion commits + the two light-mode defect analyses (stat tiles / selected chip glyph) are preserved in the batch branches above. This PR body remains the design write-up; the merge path is the sequenced recut, not this head.
Closing this PR is deferred until the first batch PR is open against main, so the design narrative and dark-identity proof stay linkable.
|
Closing as part of fork PR backlog cleanup. This draft is long-conflicted (DIRTY) against current |
Stacked on #10423 (mobile theme runtime). That PR added
useTheme()/useThemedStyles()and a light palette; the mobile app still reached its colours through a frozen darkcolorsalias, so nothing followed the theme. This converts every remaining stylesheet.What it does
Each
StyleSheet.createmoves from a module constant to a module-scope factory:consumed as
const styles = useThemedStyles(createFooStyles), so the sheet rebuilds when the palette changes. 17 batches, ~190 files.mobile/src/theme/unthemed-color-imports.test.tswas the ledger; its list is now empty and it stays as a guard against a new bare-colorsimport (it also forbids inlineuseThemedStyles(() => …), which would build a fresh sheet every render).Dark mode is unchanged, and that is proved rather than asserted
Every
StyleSheet.createentry inmobile/was extracted at the base and at the tip, comments and whitespace stripped,colors.<token>substituted withdarkColors, and the two multisets compared: 2031 entries on each side, empty difference in both directions, no unresolved token. File moves, sheet splits and sheet merges are invisible to that comparison, which is why it is done on entries rather than files.Two defects the conversion exposed, both light-mode only
Home stat tiles.
statCardused the literalrgba(26,26,26,0.6)—rgb(26,26,26)isdarkColors.bgPanel. Over the lightbgBasethat composites to roughly#767676, and the 11px labels on it land near 1.2:1: "Agents spawned" / "Agent time" / "PRs created" were unreadable while every sibling card was fine. Fixed with astatTileSurfacetoken whose dark value is the original literal.Selected modifier chip. The chip fill is
colors.textPrimary, so the glyph on it has to invert with the palette; it was the literalrgba(10,10,10,0.5). Readable over dark's#e0e0e0, but in light the fill is#0a0a0aand the same ink at 50% composites onto itself — contrast 1.00, the ⌥ glyph simply disappears. Verified on an Android emulator before and after; fixed withonInvertedMuted, again dark-byte-identical.Neither was catchable by the checks above: they are not
colors.*references, so the sheets stayed byte-identical under dark, and the both-palettes suite still saw a difference. So this PR adds the guard that would have caught them — no colour literal inside acreate*Stylesfactory unless it is listed with the reason it is mode-independent (scrims,shadowColor, on-statusRedtext, the HTML preview canvas: 15 entries).Theme-flip staleness
Eight
useMemo/useCallbacksites readcolorsorstyleswithout listing them. Before this migration both were module-level and needed no dependency; now they are hook-derived, so the memo kept the previous palette until an unrelated dependency changed — visibly in the git history list (memo'd and kept mounted) and the mermaid diagram, which kept rendering in the old theme.Also here
app/, so the style modules this migration extracted there each loggedRoute "…" is missing the required default exportand became a navigable path rendering nothing. Device-measured: 19 warnings before, 8 after moving the eleven modules undersrc/. The remaining 8 are pre-existing files this migration does not own.CodexResetCreditAction. feat(mobile): add safe Codex rate-limit resets #9394 added it with a barecolorsimport after this stack was branched; it is converted here so the ratchet stays empty, and it is listed in the ratchet in the commits below that point so no intermediate head is red.Verification
vitest349 files / 2512 passed / 2 skipped / 0 failed ·tsc --noEmitclean ·oxlintno diagnostics ·oxfmt --checkclean · max-lines ratchet unchanged (no suppression added, no per-file cap raised) · dark-identity proof above · both new guards mutation-tested (each fails when its defect is reintroduced) · Android emulator paired to a real desktop for the light/dark screens, iOS builds.ELI5
Mobile styles still used a fixed dark color palette after the theme runtime landed. Every stylesheet is converted to theme-aware factories so light/dark follow the app theme.