Skip to content

Feat/rtl i18n improvements#2022

Open
mohmedofficial515 wants to merge 14 commits into
AndyMik90:developfrom
mohmedofficial515:feat/rtl-i18n-improvements
Open

Feat/rtl i18n improvements#2022
mohmedofficial515 wants to merge 14 commits into
AndyMik90:developfrom
mohmedofficial515:feat/rtl-i18n-improvements

Conversation

@mohmedofficial515

Copy link
Copy Markdown

Base Branch

  • This PR targets the develop branch (required for all feature/fix PRs)
  • This PR targets main (hotfix only - maintainers)

Description

Related Issue

Closes #

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 📚 Documentation
  • ♻️ Refactor
  • 🧪 Test

Area

  • Frontend
  • Backend
  • Fullstack

Commit Message Format

Follow conventional commits: <type>: <subject>

Types: feat, fix, docs, style, refactor, test, chore

Example: feat: add user authentication system

AI Disclosure

  • This PR includes AI-generated code (Claude, Codex, Copilot, etc.)

Tool(s) used:
Testing level:

  • Untested -- AI output not yet verified

  • Lightly tested -- ran the app / spot-checked key paths

  • Fully tested -- all tests pass, manually verified behavior

  • I understand what this PR does and how the underlying code works

Checklist

  • I've synced with develop branch
  • I've tested my changes locally
  • I've followed the code principles (SOLID, DRY, KISS)
  • My PR is small and focused (< 400 lines ideally)

Platform Testing Checklist

CRITICAL: This project supports Windows, macOS, and Linux. Platform-specific bugs are a common source of breakage.

  • Windows tested (either on Windows or via CI)
  • macOS tested (either on macOS or via CI)
  • Linux tested (CI covers this)
  • Used centralized platform/ module instead of direct process.platform checks
  • No hardcoded paths (used findExecutable() or platform abstractions)

If you only have access to one OS: CI now tests on all platforms. Ensure all checks pass before submitting.

CI/Testing Requirements

  • All CI checks pass on all platforms (Windows, macOS, Linux)
  • All existing tests pass
  • New features include test coverage
  • Bug fixes include regression tests

Screenshots

Before After

Feature Toggle

  • Behind localStorage flag: use_feature_name
  • Behind settings toggle
  • Behind environment variable/config
  • N/A - Feature is complete and ready for all users

Breaking Changes

Breaking: Yes / No

Details:

mohmedofficial515 and others added 14 commits May 31, 2026 19:00
…me, and merge progress

- Created `taskReview.json` for task review translations in Arabic.
- Created `tasks.json` for task management translations in Arabic.
- Created `terminal.json` for terminal interface translations in Arabic.
- Created `welcome.json` for welcome screen translations in Arabic.
…icons for RTL

Arabic (RTL) was already wired up (document.dir='rtl') but the layout never
mirrored because the renderer used physical Tailwind utilities everywhere.

- Codemod across 175 .tsx files: ml/mr→ms/me, pl/pr→ps/pe, text-left/right→
  text-start/end, rounded-l/r/tl/tr/bl/br→logical, border-l/r→border-s/e,
  absolute left-/right-→start-/end- (698 replacements). Radix side-animation
  utilities (slide-in-from-left/right tied to data-[side]) preserved.
- Flip 26 horizontal directional icons (Chevron/Arrow/Panel) with
  rtl:-scale-x-100; rotating expand/collapse chevrons left untouched.

typecheck passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Icon-only Buttons/triggers lacked an accessible name for screen readers.
Reuse existing common:accessibility.* keys where they fit; add 18 new keys
(close/edit/remove/restore/discard/settings/newTask/toggleSidebar/sendMessage/
attachScreenshot/removeImage/queueAll/queueSettings/openInIde/runClaude/
resumeAllSessions/showPassword/hidePassword) with fluent en/fr/ar translations.

Locale parity verified (62 accessibility keys in each of en/fr/ar). typecheck passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The entire changelog feature (11 components) was 100% hardcoded English with
zero useTranslation usage — Arabic/French users saw English throughout.

- Register new `changelog` i18n namespace (en/fr/ar) with 153 keys covering
  every user-facing string: headers, filters, list/empty states, config,
  preview, success, GitHub release, archive, actions — plus the enum-keyed
  source-mode/format/audience/emoji-level/stage labels & descriptions that were
  rendered straight from constants.
- Replace hardcoded MCP tool tooltips ("Test Connection"/"Edit"/"Delete") and
  the "Test" button label in AgentTools with settings:/common: keys; add
  settings:mcp.testConnectionTitle (en/fr/ar).

Locale parity verified (changelog: 153 keys each lang, 0 missing/extra).
typecheck passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… FirstSpecStep

These onboarding-flow components were hardcoded English (first-run experience
shown to every new user). Extract ~73 strings into the onboarding namespace
under new graphiti/authChoice/firstSpec sections; refactor GraphitiStep's
module-level LLM_PROVIDERS/EMBEDDING_PROVIDERS arrays to carry i18n key
references instead of literal name/description.

onboarding locale parity: 309 keys each in en/fr/ar (0 missing/extra).
typecheck passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…omponents

These settings components were hardcoded English. Extract ~109 strings into the
settings namespace: project-settings (Security/Memory, Integration, Linear &
GitHub sections, Notifications), settings/integrations/LinearIntegration, and
ThemeSelector. New keys grouped under integrations.{common,connection,linear,
github,memory} and theme. GitHub project-scope description uses <Trans> to
preserve the inline styled {{projectName}} span.

settings locale parity: 1009 keys each in en/fr/ar (0 missing/extra).
typecheck passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AuthChoiceStep now renders copy via t('onboarding:authChoice.*'); mock
useTranslation to resolve those keys to the English strings the existing
assertions expect (mirrors OnboardingWizard.test.tsx). 14/14 pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…AI points

Add a 'direct' Vercel AI SDK provider that wraps the free, no-API-key web
transports from ai-providers-direct (DeepSeek primary, ChatGPT assist), and
route every AI feature through it when enabled.

- providers/direct: LanguageModelV2 wrapper with prompt flattening, plain-text
  ReAct tool-call emulation (the web protocols have no native function calling),
  and streaming. Library bridged lazily so WASM/Playwright never bundle into the
  pure core. 13 unit tests.
- factory/registry/types: register SupportedProvider.Direct + model-id prefixes
  (deepseek, chatgpt) for detection and registry resolution.
- client/factory: resolveDirectModel() override at the single chokepoint both
  client factories share — covers planner, coder, QA, and every utility runner.
  Safe fallback to the configured provider when no DeepSeek token is present.
- settings: restore DirectAiConnectionSettings type + DirectAiSettings UI panel,
  default enabled (transparently falls back without a token), i18n for en/fr/ar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sing

- getDirectConnectionSettings now merges over DEFAULT_APP_SETTINGS so the shipped
  default applies even when the saved settings file predates the field (the
  accessor reads the raw file without merging defaults).
- resolveDirectModel distinguishes enabled-but-tokenless (needs-setup) from
  disabled; when direct mode is on without a token and the paid fallback also
  fails, surface an actionable setup message instead of the cryptic
  priority-queue error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a one-click "Capture token automatically" flow so users don't have to run
the CLI extractor and paste the token by hand.

- capture-token.ts: runs the bundled ai-providers-direct Playwright extractor
  via Electron-as-node. Headless first (existing session); if not signed in,
  opens a headed sign-in window then captures headlessly. Profile + .env land
  in userData, never the cwd.
- direct-ai-handlers.ts: 'direct-ai-capture-token' IPC handler, registered in
  the IPC index alongside the other handlers.
- preload + ipc types + browser mock: expose window.electronAPI.captureDeepSeekToken.
- DirectAiSettings: capture button with loading/error states; fills the token
  field on success. i18n for en/fr/ar.

Caveat: requires playwright + a Chrome/Chromium binary at runtime (available in
dev; not bundled in packaged builds). Failures surface a structured error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Node 24 defaults DNS to "verbatim" (often IPv6 first). chat.deepseek.com (and
api.github.com) have AAAA records whose IPv6 route hangs here, so undici `fetch`
hit its 10s connect timeout (UND_ERR_CONNECT_TIMEOUT) — breaking the Direct AI
(DeepSeek) connection and the GitHub app-updater.

Diagnosis: raw TCP + curl + `node` with family=4 all connect in <0.5s, but
default `fetch` failed at ~10.6s (3/3). `dns.setDefaultResultOrder('ipv4first')`
makes the same fetch succeed in <200ms.

Apply the IPv4-first default at the top of the main process and in the agent
worker thread (separate DNS default), so both the runner path and the build
pipeline reach DeepSeek.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 253 files, which is 103 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 726e59cd-34d1-4486-b1c4-2b48d07898a0

📥 Commits

Reviewing files that changed from the base of the PR and between cba7a02 and dd024c7.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json, !**/package-lock.json
📒 Files selected for processing (253)
  • apps/desktop/bash.exe.stackdump
  • apps/desktop/package.json
  • apps/desktop/src/main/agent/agent-manager.ts
  • apps/desktop/src/main/ai/agent/worker.ts
  • apps/desktop/src/main/ai/auth/resolver.ts
  • apps/desktop/src/main/ai/auth/types.ts
  • apps/desktop/src/main/ai/client/__tests__/factory.test.ts
  • apps/desktop/src/main/ai/client/factory.ts
  • apps/desktop/src/main/ai/config/agent-configs.ts
  • apps/desktop/src/main/ai/config/types.ts
  • apps/desktop/src/main/ai/providers/anthropic-oauth-fetch.ts
  • apps/desktop/src/main/ai/providers/direct/__tests__/direct-language-model.test.ts
  • apps/desktop/src/main/ai/providers/direct/capture-token.ts
  • apps/desktop/src/main/ai/providers/direct/direct-language-model.ts
  • apps/desktop/src/main/ai/providers/direct/direct-provider.ts
  • apps/desktop/src/main/ai/providers/direct/index.ts
  • apps/desktop/src/main/ai/providers/direct/prompt-flatten.ts
  • apps/desktop/src/main/ai/providers/direct/tool-protocol.ts
  • apps/desktop/src/main/ai/providers/direct/transport.ts
  • apps/desktop/src/main/ai/providers/factory.ts
  • apps/desktop/src/main/ai/providers/registry.ts
  • apps/desktop/src/main/ai/providers/transforms.ts
  • apps/desktop/src/main/ai/providers/types.ts
  • apps/desktop/src/main/ai/runners/ideation.ts
  • apps/desktop/src/main/ai/runners/insights.ts
  • apps/desktop/src/main/ai/runners/roadmap.ts
  • apps/desktop/src/main/ai/session/runner.ts
  • apps/desktop/src/main/ai/session/stream-handler.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/ipc-handlers/claude-code-handlers.ts
  • apps/desktop/src/main/ipc-handlers/direct-ai-handlers.ts
  • apps/desktop/src/main/ipc-handlers/index.ts
  • apps/desktop/src/main/project-initializer.ts
  • apps/desktop/src/preload/api/settings-api.ts
  • apps/desktop/src/preload/api/terminal-api.ts
  • apps/desktop/src/renderer/App.tsx
  • apps/desktop/src/renderer/components/AddCompetitorDialog.tsx
  • apps/desktop/src/renderer/components/AddFeatureDialog.tsx
  • apps/desktop/src/renderer/components/AddProjectModal.tsx
  • apps/desktop/src/renderer/components/AgentProfileSelector.tsx
  • apps/desktop/src/renderer/components/AgentProfiles.tsx
  • apps/desktop/src/renderer/components/AgentTools.tsx
  • apps/desktop/src/renderer/components/AppUpdateNotification.tsx
  • apps/desktop/src/renderer/components/AuthFailureModal.tsx
  • apps/desktop/src/renderer/components/AuthStatusIndicator.tsx
  • apps/desktop/src/renderer/components/BulkPRDialog.tsx
  • apps/desktop/src/renderer/components/ChatHistorySidebar.tsx
  • apps/desktop/src/renderer/components/ClaudeCodeStatusBadge.tsx
  • apps/desktop/src/renderer/components/CompetitorAnalysisDialog.tsx
  • apps/desktop/src/renderer/components/CompetitorAnalysisViewer.tsx
  • apps/desktop/src/renderer/components/CustomMcpDialog.tsx
  • apps/desktop/src/renderer/components/ExistingCompetitorAnalysisDialog.tsx
  • apps/desktop/src/renderer/components/FileAutocomplete.tsx
  • apps/desktop/src/renderer/components/FileExplorerPanel.tsx
  • apps/desktop/src/renderer/components/GitHubIssues.tsx
  • apps/desktop/src/renderer/components/GitHubSetupModal.tsx
  • apps/desktop/src/renderer/components/GitLabIssues.tsx
  • apps/desktop/src/renderer/components/GitSetupModal.tsx
  • apps/desktop/src/renderer/components/GlobalDownloadIndicator.tsx
  • apps/desktop/src/renderer/components/ImageUpload.tsx
  • apps/desktop/src/renderer/components/Insights.tsx
  • apps/desktop/src/renderer/components/KanbanBoard.tsx
  • apps/desktop/src/renderer/components/PhaseProgressIndicator.tsx
  • apps/desktop/src/renderer/components/ProactiveSwapListener.tsx
  • apps/desktop/src/renderer/components/ProfileBadge.tsx
  • apps/desktop/src/renderer/components/RateLimitModal.tsx
  • apps/desktop/src/renderer/components/ReferencedFilesSection.tsx
  • apps/desktop/src/renderer/components/RoadmapGenerationProgress.tsx
  • apps/desktop/src/renderer/components/SDKRateLimitModal.tsx
  • apps/desktop/src/renderer/components/ScreenshotCapture.tsx
  • apps/desktop/src/renderer/components/Sidebar.tsx
  • apps/desktop/src/renderer/components/SortableFeatureCard.tsx
  • apps/desktop/src/renderer/components/SortableProjectTab.tsx
  • apps/desktop/src/renderer/components/TaskCard.tsx
  • apps/desktop/src/renderer/components/TaskCreationWizard.tsx
  • apps/desktop/src/renderer/components/TaskEditDialog.tsx
  • apps/desktop/src/renderer/components/TaskFileExplorerDrawer.tsx
  • apps/desktop/src/renderer/components/TerminalGrid.tsx
  • apps/desktop/src/renderer/components/UsageIndicator.tsx
  • apps/desktop/src/renderer/components/VersionWarningModal.tsx
  • apps/desktop/src/renderer/components/WelcomeScreen.tsx
  • apps/desktop/src/renderer/components/WorktreeCleanupDialog.tsx
  • apps/desktop/src/renderer/components/Worktrees.tsx
  • apps/desktop/src/renderer/components/changelog/ArchiveTasksCard.tsx
  • apps/desktop/src/renderer/components/changelog/Changelog.tsx
  • apps/desktop/src/renderer/components/changelog/ChangelogEntry.tsx
  • apps/desktop/src/renderer/components/changelog/ChangelogFilters.tsx
  • apps/desktop/src/renderer/components/changelog/ChangelogHeader.tsx
  • apps/desktop/src/renderer/components/changelog/ChangelogList.tsx
  • apps/desktop/src/renderer/components/changelog/ConfigurationPanel.tsx
  • apps/desktop/src/renderer/components/changelog/GitHubReleaseCard.tsx
  • apps/desktop/src/renderer/components/changelog/PreviewPanel.tsx
  • apps/desktop/src/renderer/components/changelog/Step3SuccessScreen.tsx
  • apps/desktop/src/renderer/components/context/MemoriesTab.tsx
  • apps/desktop/src/renderer/components/context/MemoryCard.tsx
  • apps/desktop/src/renderer/components/context/PRReviewCard.tsx
  • apps/desktop/src/renderer/components/context/ProjectIndexTab.tsx
  • apps/desktop/src/renderer/components/context/service-sections/ExternalServicesSection.tsx
  • apps/desktop/src/renderer/components/github-issues/components/AutoFixButton.tsx
  • apps/desktop/src/renderer/components/github-issues/components/BatchReviewWizard.tsx
  • apps/desktop/src/renderer/components/github-issues/components/EmptyStates.tsx
  • apps/desktop/src/renderer/components/github-issues/components/GitHubErrorDisplay.tsx
  • apps/desktop/src/renderer/components/github-issues/components/InvestigationDialog.tsx
  • apps/desktop/src/renderer/components/github-issues/components/IssueDetail.tsx
  • apps/desktop/src/renderer/components/github-issues/components/IssueListHeader.tsx
  • apps/desktop/src/renderer/components/github-prs/GitHubPRs.tsx
  • apps/desktop/src/renderer/components/github-prs/components/FindingItem.tsx
  • apps/desktop/src/renderer/components/github-prs/components/PRDetail.tsx
  • apps/desktop/src/renderer/components/github-prs/components/PRFilterBar.tsx
  • apps/desktop/src/renderer/components/github-prs/components/PRHeader.tsx
  • apps/desktop/src/renderer/components/github-prs/components/PRList.tsx
  • apps/desktop/src/renderer/components/github-prs/components/PRLogs.tsx
  • apps/desktop/src/renderer/components/github-prs/components/ReviewFindings.tsx
  • apps/desktop/src/renderer/components/github-prs/components/ReviewStatusTree.tsx
  • apps/desktop/src/renderer/components/gitlab-issues/components/EmptyStates.tsx
  • apps/desktop/src/renderer/components/gitlab-issues/components/InvestigationDialog.tsx
  • apps/desktop/src/renderer/components/gitlab-issues/components/IssueDetail.tsx
  • apps/desktop/src/renderer/components/gitlab-issues/components/IssueListHeader.tsx
  • apps/desktop/src/renderer/components/gitlab-merge-requests/GitLabMergeRequests.tsx
  • apps/desktop/src/renderer/components/gitlab-merge-requests/components/CreateMergeRequestDialog.tsx
  • apps/desktop/src/renderer/components/gitlab-merge-requests/components/FindingItem.tsx
  • apps/desktop/src/renderer/components/gitlab-merge-requests/components/MRDetail.tsx
  • apps/desktop/src/renderer/components/gitlab-merge-requests/components/MergeRequestItem.tsx
  • apps/desktop/src/renderer/components/gitlab-merge-requests/components/ReviewFindings.tsx
  • apps/desktop/src/renderer/components/ideation/GenerationProgressScreen.tsx
  • apps/desktop/src/renderer/components/ideation/IdeaCard.tsx
  • apps/desktop/src/renderer/components/ideation/IdeaDetailPanel.tsx
  • apps/desktop/src/renderer/components/ideation/IdeationDialogs.tsx
  • apps/desktop/src/renderer/components/ideation/IdeationEmptyState.tsx
  • apps/desktop/src/renderer/components/ideation/IdeationFilters.tsx
  • apps/desktop/src/renderer/components/ideation/IdeationHeader.tsx
  • apps/desktop/src/renderer/components/linear-import/LinearTaskImportModalRefactored.tsx
  • apps/desktop/src/renderer/components/linear-import/components/SearchAndFilterBar.tsx
  • apps/desktop/src/renderer/components/onboarding/AuthChoiceStep.test.tsx
  • apps/desktop/src/renderer/components/onboarding/AuthChoiceStep.tsx
  • apps/desktop/src/renderer/components/onboarding/CompletionStep.tsx
  • apps/desktop/src/renderer/components/onboarding/DevToolsStep.tsx
  • apps/desktop/src/renderer/components/onboarding/FirstSpecStep.tsx
  • apps/desktop/src/renderer/components/onboarding/GraphitiStep.tsx
  • apps/desktop/src/renderer/components/onboarding/MemoryStep.tsx
  • apps/desktop/src/renderer/components/onboarding/OAuthStep.tsx
  • apps/desktop/src/renderer/components/onboarding/OllamaModelSelector.tsx
  • apps/desktop/src/renderer/components/project-settings/AutoBuildIntegration.tsx
  • apps/desktop/src/renderer/components/project-settings/ClaudeOAuthFlow.tsx
  • apps/desktop/src/renderer/components/project-settings/CollapsibleSection.tsx
  • apps/desktop/src/renderer/components/project-settings/GeneralSettings.tsx
  • apps/desktop/src/renderer/components/project-settings/GitHubIntegrationSection.tsx
  • apps/desktop/src/renderer/components/project-settings/GitHubOAuthFlow.tsx
  • apps/desktop/src/renderer/components/project-settings/IntegrationSettings.tsx
  • apps/desktop/src/renderer/components/project-settings/LinearIntegrationSection.tsx
  • apps/desktop/src/renderer/components/project-settings/NotificationsSection.tsx
  • apps/desktop/src/renderer/components/project-settings/PasswordInput.tsx
  • apps/desktop/src/renderer/components/project-settings/SecuritySettings.tsx
  • apps/desktop/src/renderer/components/roadmap/FeatureCard.tsx
  • apps/desktop/src/renderer/components/roadmap/FeatureDetailPanel.tsx
  • apps/desktop/src/renderer/components/roadmap/PhaseCard.tsx
  • apps/desktop/src/renderer/components/roadmap/RoadmapEmptyState.tsx
  • apps/desktop/src/renderer/components/roadmap/RoadmapHeader.tsx
  • apps/desktop/src/renderer/components/roadmap/RoadmapTabs.tsx
  • apps/desktop/src/renderer/components/settings/AccountPriorityList.tsx
  • apps/desktop/src/renderer/components/settings/AccountSettings.tsx
  • apps/desktop/src/renderer/components/settings/AddAccountDialog.tsx
  • apps/desktop/src/renderer/components/settings/AdvancedSettings.tsx
  • apps/desktop/src/renderer/components/settings/AgentProfileSettings.tsx
  • apps/desktop/src/renderer/components/settings/AppSettings.tsx
  • apps/desktop/src/renderer/components/settings/AuthTerminal.tsx
  • apps/desktop/src/renderer/components/settings/DebugSettings.tsx
  • apps/desktop/src/renderer/components/settings/DevToolsSettings.tsx
  • apps/desktop/src/renderer/components/settings/DirectAiSettings.tsx
  • apps/desktop/src/renderer/components/settings/LanguageSettings.tsx
  • apps/desktop/src/renderer/components/settings/ModelSearchableSelect.tsx
  • apps/desktop/src/renderer/components/settings/MultiProviderModelSelect.tsx
  • apps/desktop/src/renderer/components/settings/OllamaConnectionPanel.tsx
  • apps/desktop/src/renderer/components/settings/OllamaModelManager.tsx
  • apps/desktop/src/renderer/components/settings/ProfileEditDialog.tsx
  • apps/desktop/src/renderer/components/settings/ProfileList.tsx
  • apps/desktop/src/renderer/components/settings/ProjectSelector.tsx
  • apps/desktop/src/renderer/components/settings/ProviderAccountCard.tsx
  • apps/desktop/src/renderer/components/settings/ProviderAccountsList.tsx
  • apps/desktop/src/renderer/components/settings/ProviderSection.tsx
  • apps/desktop/src/renderer/components/settings/ProviderTabBar.tsx
  • apps/desktop/src/renderer/components/settings/ThemeSelector.tsx
  • apps/desktop/src/renderer/components/settings/integrations/GitHubIntegration.tsx
  • apps/desktop/src/renderer/components/settings/integrations/GitLabIntegration.tsx
  • apps/desktop/src/renderer/components/settings/integrations/LinearIntegration.tsx
  • apps/desktop/src/renderer/components/settings/terminal-font-settings/CursorConfigPanel.tsx
  • apps/desktop/src/renderer/components/task-detail/TaskActions.tsx
  • apps/desktop/src/renderer/components/task-detail/TaskDetailModal.tsx
  • apps/desktop/src/renderer/components/task-detail/TaskFiles.tsx
  • apps/desktop/src/renderer/components/task-detail/TaskHeader.tsx
  • apps/desktop/src/renderer/components/task-detail/TaskLogs.tsx
  • apps/desktop/src/renderer/components/task-detail/TaskMetadata.tsx
  • apps/desktop/src/renderer/components/task-detail/TaskSubtasks.tsx
  • apps/desktop/src/renderer/components/task-detail/TaskWarnings.tsx
  • apps/desktop/src/renderer/components/task-detail/task-review/ConflictDetailsDialog.tsx
  • apps/desktop/src/renderer/components/task-detail/task-review/CreatePRDialog.tsx
  • apps/desktop/src/renderer/components/task-detail/task-review/DiffViewDialog.tsx
  • apps/desktop/src/renderer/components/task-detail/task-review/DiscardDialog.tsx
  • apps/desktop/src/renderer/components/task-detail/task-review/QAFeedbackSection.tsx
  • apps/desktop/src/renderer/components/task-detail/task-review/StagedSuccessMessage.tsx
  • apps/desktop/src/renderer/components/task-detail/task-review/TerminalDropdown.tsx
  • apps/desktop/src/renderer/components/task-detail/task-review/WorkspaceMessages.tsx
  • apps/desktop/src/renderer/components/task-detail/task-review/WorkspaceStatus.tsx
  • apps/desktop/src/renderer/components/task-form/ImagePreviewModal.tsx
  • apps/desktop/src/renderer/components/task-form/TaskFormFields.tsx
  • apps/desktop/src/renderer/components/task-form/TaskModalLayout.tsx
  • apps/desktop/src/renderer/components/terminal/CreateWorktreeDialog.tsx
  • apps/desktop/src/renderer/components/terminal/TaskSelector.tsx
  • apps/desktop/src/renderer/components/terminal/TerminalHeader.tsx
  • apps/desktop/src/renderer/components/terminal/WorktreeSelector.tsx
  • apps/desktop/src/renderer/components/ui/alert-dialog.tsx
  • apps/desktop/src/renderer/components/ui/combobox.tsx
  • apps/desktop/src/renderer/components/ui/dialog.tsx
  • apps/desktop/src/renderer/components/ui/dropdown-menu.tsx
  • apps/desktop/src/renderer/components/ui/error-boundary.tsx
  • apps/desktop/src/renderer/components/ui/full-screen-dialog.tsx
  • apps/desktop/src/renderer/components/ui/resizable-panels.tsx
  • apps/desktop/src/renderer/components/ui/scroll-area.tsx
  • apps/desktop/src/renderer/components/ui/select.tsx
  • apps/desktop/src/renderer/components/ui/toast.tsx
  • apps/desktop/src/renderer/components/workspace/AddWorkspaceModal.tsx
  • apps/desktop/src/renderer/index.html
  • apps/desktop/src/renderer/lib/browser-mock.ts
  • apps/desktop/src/renderer/lib/mocks/claude-profile-mock.ts
  • apps/desktop/src/renderer/stores/insights-store.ts
  • apps/desktop/src/renderer/stores/project-store.ts
  • apps/desktop/src/shared/constants/config.ts
  • apps/desktop/src/shared/constants/i18n.ts
  • apps/desktop/src/shared/constants/ipc.ts
  • apps/desktop/src/shared/constants/spellcheck.ts
  • apps/desktop/src/shared/i18n/index.ts
  • apps/desktop/src/shared/i18n/locales/ar/changelog.json
  • apps/desktop/src/shared/i18n/locales/ar/common.json
  • apps/desktop/src/shared/i18n/locales/ar/dialogs.json
  • apps/desktop/src/shared/i18n/locales/ar/errors.json
  • apps/desktop/src/shared/i18n/locales/ar/gitlab.json
  • apps/desktop/src/shared/i18n/locales/ar/navigation.json
  • apps/desktop/src/shared/i18n/locales/ar/onboarding.json
  • apps/desktop/src/shared/i18n/locales/ar/settings.json
  • apps/desktop/src/shared/i18n/locales/ar/taskReview.json
  • apps/desktop/src/shared/i18n/locales/ar/tasks.json
  • apps/desktop/src/shared/i18n/locales/ar/terminal.json
  • apps/desktop/src/shared/i18n/locales/ar/welcome.json
  • apps/desktop/src/shared/i18n/locales/en/changelog.json
  • apps/desktop/src/shared/i18n/locales/en/common.json
  • apps/desktop/src/shared/i18n/locales/en/onboarding.json
  • apps/desktop/src/shared/i18n/locales/en/settings.json
  • apps/desktop/src/shared/i18n/locales/fr/changelog.json
  • apps/desktop/src/shared/i18n/locales/fr/common.json
  • apps/desktop/src/shared/i18n/locales/fr/onboarding.json
  • apps/desktop/src/shared/i18n/locales/fr/settings.json
  • apps/desktop/src/shared/types/ipc.ts
  • apps/desktop/src/shared/types/settings.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

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

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎉 Thanks for your first PR!

A maintainer will review it soon. Please make sure:

  • Your branch is synced with develop
  • CI checks pass
  • You've followed our contribution guide

Welcome to the Auto Claude community!

Comment on lines +135 to +138
if (isNotLoggedIn(result)) {
await runExtractor(scriptPath, true, consumerRoot);
result = await runExtractor(scriptPath, false, consumerRoot);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The result of the headed runExtractor call is discarded, so if it times out or fails, the user sees a generic "not logged in" error instead of the real one.
Severity: MEDIUM

Suggested Fix

Capture the result of the headed runExtractor call. Check if it was successful. If it failed, return the failure result immediately. Do not proceed with the final headless runExtractor call if the headed sign-in step failed.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: apps/desktop/src/main/ai/providers/direct/capture-token.ts#L135-L138

Potential issue: In `captureDeepSeekToken`, the result of the headed `runExtractor` call
is not assigned to any variable. If this operation fails, for instance due to a timeout
after 240 seconds, the error information is lost. The function then proceeds to another
headless `runExtractor` call which returns a `NOT_LOGGED_IN` error. This masks the
original timeout error, leading to a confusing user experience where the user waits a
long time only to see a misleading error message.

Did we get this right? 👍 / 👎 to inform future reviews.

@@ -70,7 +70,23 @@ export const DEFAULT_APP_SETTINGS = {
// GPU acceleration for terminal rendering
// Default to 'off' until WebGL stability is proven across all GPU drivers.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: New users without a configured provider will see a confusing error about 'Direct AI Connection' when trying to use AI features, because this connection type is enabled by default.
Severity: LOW

Suggested Fix

To improve the user experience, consider disabling directAiConnection by default. Alternatively, improve the error handling to present a more general and helpful message, such as guiding the user to the settings page to configure any available AI provider, rather than a specific one.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: apps/desktop/src/shared/constants/config.ts#L71

Potential issue: The `directAiConnection` feature is enabled by default. For a new user
without a pre-configured DeepSeek token or a fallback paid provider, attempting to use
an AI feature will throw an error. The error message, `DIRECT_NEEDS_TOKEN_MESSAGE`, is
confusing as it refers to a feature the user did not explicitly enable, creating a poor
onboarding experience.

Did we get this right? 👍 / 👎 to inform future reviews.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a free 'Direct AI Connection' feature to route agent tasks directly through DeepSeek and ChatGPT web protocols, adds Arabic language support with RTL layouts, implements Anthropic prompt caching, and fixes Windows CLI path quoting. Feedback from the review highlights critical compatibility issues with the Vercel AI SDK LanguageModelV2 interface in the prompt flattening and model implementation, such as using incorrect properties (input instead of args, and output instead of result) which will cause runtime crashes. Additionally, the reviewer noted that spinning up a new browser session on every generation call is highly inefficient, warned against using fragile relative file dependencies in package.json, recommended safer RTL detection and locale-aware date formatting, and requested the removal of a temporary stack dump file.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +86 to +92
} else if (part.type === 'tool-call') {
// Echo the assistant's prior tool call so the model sees the loop it
// is already in. Mirrors the ReAct block the parser emits/expects.
segments.push(
`<tool_call>\n${JSON.stringify({ name: part.toolName, arguments: part.input })}\n</tool_call>`,
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

In the Vercel AI SDK LanguageModelV2 prompt, the content part for a tool-call message uses the args property to store the arguments, not input. Using part.input will result in undefined, causing the tool arguments to be completely omitted when echoing the assistant's prior turns. This will break multi-turn tool use as the model won't see its previous arguments.

Suggested change
} else if (part.type === 'tool-call') {
// Echo the assistant's prior tool call so the model sees the loop it
// is already in. Mirrors the ReAct block the parser emits/expects.
segments.push(
`<tool_call>\n${JSON.stringify({ name: part.toolName, arguments: part.input })}\n</tool_call>`,
);
}
} else if (part.type === 'tool-call') {
// Echo the assistant's prior tool call so the model sees the loop it
// is already in. Mirrors the ReAct block the parser emits/expects.
segments.push(
`<tool_call>\\n${JSON.stringify({ name: part.toolName, arguments: part.args })}\\n</tool_call>`,
);
}

Comment on lines +32 to +52
function renderToolOutput(output: { type: string; value?: unknown }): string {
switch (output.type) {
case 'text':
case 'error-text':
return String(output.value ?? '');
case 'json':
case 'error-json':
return JSON.stringify(output.value ?? null);
case 'content': {
// Array of text/media parts — keep text, mark media placeholders.
const parts = Array.isArray(output.value) ? output.value : [];
return parts
.map((p: { type: string; text?: string; mediaType?: string }) =>
p.type === 'text' ? (p.text ?? '') : `[media: ${p.mediaType ?? 'unknown'}]`,
)
.join('\n');
}
default:
return JSON.stringify(output.value ?? null);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

The renderToolOutput function expects a structured { type, value } object, but the Vercel AI SDK passes the raw tool execution result directly as part.result (which can be a string, object, array, etc.). We should redefine this function to accept unknown and format it robustly to prevent runtime crashes.

function renderToolOutput(result: unknown): string {
  if (result == null) return '';
  if (typeof result === 'string') return result;
  if (typeof result === 'object') {
    try {
      return JSON.stringify(result);
    } catch {
      return String(result);
    }
  }
  return String(result);
}

Comment on lines +102 to +106
for (const part of message.content) {
lines.push(
`Tool result (tool="${part.toolName}", id="${part.toolCallId}"):\n${renderToolOutput(part.output)}`,
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

In the Vercel AI SDK LanguageModelV2 prompt, the content part for a tool message contains result: unknown, NOT output. At runtime, part.output will be undefined, causing renderToolOutput(undefined) to throw a TypeError and crash the agent loop. Update this to use part.result.

Suggested change
for (const part of message.content) {
lines.push(
`Tool result (tool="${part.toolName}", id="${part.toolCallId}"):\n${renderToolOutput(part.output)}`,
);
}
for (const part of message.content) {
lines.push(
`Tool result (tool="${part.toolName}", id="${part.toolCallId}"):\\n${renderToolOutput(part.result)}`
);
}

Comment on lines +130 to +138
function toToolCallContent(calls: ParsedToolCall[]): LanguageModelV2Content[] {
return calls.map((call) => ({
type: 'tool-call' as const,
toolCallId: crypto.randomUUID(),
toolName: call.toolName,
// AI SDK expects the arguments as a stringified JSON object.
input: JSON.stringify(call.args ?? {}),
}));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

In the Vercel AI SDK LanguageModelV2 output, the property for tool call arguments is args (which must be a parsed object), NOT input (which is a stringified JSON). Returning input as a stringified JSON will cause the AI SDK to fail to parse the tool call arguments or throw an error.

function toToolCallContent(calls: ParsedToolCall[]): LanguageModelV2Content[] {
  return calls.map((call) => ({
    type: 'tool-call' as const,
    toolCallId: crypto.randomUUID(),
    toolName: call.toolName,
    args: call.args ?? {},
  }));
}

Comment thread apps/desktop/package.json
"@xterm/addon-webgl": "^0.19.0",
"@xterm/xterm": "^6.0.0",
"ai": "^6.0.116",
"ai-providers-direct": "file:../../../ai-providers-direct",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Using a relative file: dependency pointing outside the repository root (file:../../../ai-providers-direct) is highly fragile. It will break CI/CD pipelines, automated testing, and production packaging on other machines where this relative path does not exist. Consider publishing this package to a private registry, bundling it, or using a monorepo workspace protocol (e.g., workspace:* if using pnpm/yarn/npm workspaces) to reference it.

Comment on lines 188 to 190
if (llmProvider === 'openai' || embeddingProvider === 'openai') {
if (!config.openaiApiKey.trim()) return 'OpenAI API key';
if (!config.openaiApiKey.trim()) return t('graphiti.requiredKeys.openai');
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Calling .trim() directly on config properties (like config.openaiApiKey.trim()) will throw a TypeError and crash the onboarding wizard if those properties are undefined (e.g., if they are not initialized in the state or are missing from a legacy settings file). Use optional chaining to safely handle potentially undefined values.

Suggested change
if (llmProvider === 'openai' || embeddingProvider === 'openai') {
if (!config.openaiApiKey.trim()) return 'OpenAI API key';
if (!config.openaiApiKey.trim()) return t('graphiti.requiredKeys.openai');
}
if (llmProvider === 'openai' || embeddingProvider === 'openai') {
if (!config.openaiApiKey?.trim()) return t('graphiti.requiredKeys.openai');
}

Comment on lines 14 to +15
export function TaskCard({ task, isSelected, onToggle }: TaskCardProps) {
const { t } = useTranslation('changelog');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

toLocaleDateString() formats the date using the system's default locale, which might not match the user's selected language in the app. To ensure a consistent internationalized experience, pass the current language from i18n to toLocaleDateString().

  const { t, i18n } = useTranslation('changelog');
  const completedDate = new Date(task.completedAt).toLocaleDateString(i18n.language);

Comment on lines 59 to 60

export function CommitCard({ commit }: CommitCardProps) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

toLocaleDateString() formats the date using the system's default locale, which might not match the user's selected language in the app. To ensure a consistent internationalized experience, pass the current language from i18n to toLocaleDateString().

  const { t, i18n } = useTranslation('changelog');
  const commitDate = new Date(commit.date).toLocaleDateString(i18n.language);

Comment on lines +322 to +326
useEffect(() => {
const isRtl = i18n.language === 'ar';
document.documentElement.dir = isRtl ? 'rtl' : 'ltr';
document.documentElement.lang = i18n.language;
}, [i18n.language]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Checking i18n.language === 'ar' might fail if the language is set to a regional variant of Arabic (e.g., ar-EG, ar-SA). It is safer to use startsWith('ar') or import the RTL_LANGUAGES constant from src/shared/constants/i18n.ts to determine if the language is RTL.

Suggested change
useEffect(() => {
const isRtl = i18n.language === 'ar';
document.documentElement.dir = isRtl ? 'rtl' : 'ltr';
document.documentElement.lang = i18n.language;
}, [i18n.language]);
useEffect(() => {
const isRtl = i18n.language.startsWith('ar');
document.documentElement.dir = isRtl ? 'rtl' : 'ltr';
document.documentElement.lang = i18n.language;
}, [i18n.language]);

@@ -0,0 +1,28 @@
Stack trace:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The bash.exe.stackdump file appears to be a temporary crash dump file generated during local development. It should not be committed to the repository. Please remove this file and ensure it is added to your .gitignore to prevent future accidental commits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants