-
-
Notifications
You must be signed in to change notification settings - Fork 786
🌐 Add Complete Hebrew (he) Translation Support #417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
|
sumca1 seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
📝 WalkthroughWalkthroughAdds wide frontend internationalization (en/fr/he) and RTL support, a Markdown renderer with file-open IPC, Insights “stop” control flow (service, IPC, preload API, store, UI), formatting toolbar/editor features, task-language propagation, proxy controls and types, packaging updates to include locales, and several UI/component i18n and minor API/type adjustments. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as Renderer (Insights UI)
participant Store as Insights Store
participant Preload as Preload (ipc)
participant Main as Main (ipcMain)
participant Service as InsightsService
participant Exec as SessionExecutor
Note over UI,Store: User clicks Stop on an active insights session
UI->>Store: dispatch stopInsights(projectId)
Store->>Preload: invoke INSIGHTS_STOP(projectId)
Preload->>Main: IPC INSIGHTS_STOP(projectId)
Main->>Service: stopChat(projectId)
Service->>Exec: cancelSession(projectId)
Exec-->>Service: cancel result (bool)
alt canceled
Service->>Main: emit INSIGHTS_STOPPED(projectId)
Main-->>Preload: resolve { success: true }
Preload-->>Store: response success
Store->>Store: clear streaming, reset tools, set status=idle
Store-->>UI: updated state (stopped)
else not running
Main-->>Preload: resolve { success: false, error }
Preload-->>Store: response failure
Store-->>UI: surface error message
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
Comment |
There was a problem hiding this comment.
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!
- Add complete Hebrew translation for all UI components - Include translations for: common, dialogs, navigation, onboarding, settings, taskReview, tasks, welcome - Update i18n configuration to support Hebrew locale - Add RTL support in package.json build configuration - All user-facing strings are now available in Hebrew
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 59
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (61)
apps/frontend/src/renderer/components/task-detail/TaskWarnings.tsx (1)
34-82: Add missing translation keys toenandfrlocale files.The following keys are missing from
apps/frontend/src/shared/i18n/locales/en/taskReview.jsonandapps/frontend/src/shared/i18n/locales/fr/taskReview.json:
warnings.taskStuckTitlewarnings.taskStuckDescriptionactions.recoveringwarnings.recoverAndRestartwarnings.taskIncompleteTitlewarnings.taskIncompleteDescriptionactions.resumeTaskAll translation keys must be added to the minimum required language files (en and fr) in addition to the new Hebrew locale.
apps/frontend/src/renderer/components/github-prs/GitHubPRs.tsx (1)
145-145: Complete the translation implementation - hardcoded strings remain.The file still contains hardcoded English strings that must be replaced with translation keys:
- Line 145:
"Pull Requests"in the header- Line 159:
"open"in the PR count display- Line 205:
"Select a pull request to view details"in EmptyStateAccording to the coding guidelines: "Always use translation keys with
useTranslation()for all user-facing text" and "Never use hardcoded strings in JSX/TSX files for user-facing text."Since this PR adds Hebrew translation support, leaving these strings untranslated will result in a mixed Hebrew/English UI, breaking the localization experience.
🔎 Suggested implementation
Add
useTranslation('context')to the mainGitHubPRscomponent and replace the hardcoded strings:export function GitHubPRs({ onOpenSettings }: GitHubPRsProps) { + const { t } = useTranslation('context'); const projects = useProjectStore((state) => state.projects); // ... rest of the codeThen replace the hardcoded strings:
<h2 className="text-sm font-medium flex items-center gap-2"> <GitPullRequest className="h-4 w-4" /> - Pull Requests + {t('github.pullRequests')} </h2><span className="text-xs text-muted-foreground"> - {prs.length} open + {t('github.prsOpen', { count: prs.length })} </span>) : ( - <EmptyState message="Select a pull request to view details" /> + <EmptyState message={t('github.selectPRHint')} /> )}Remember to add these keys (
github.pullRequests,github.prsOpen,github.selectPRHint) to all language files:en/context.json,fr/context.json, andhe/context.json.Based on learnings, ...
Also applies to: 159-159, 205-205
apps/frontend/src/renderer/components/SortableProjectTab.tsx (1)
108-108: Use logical property for RTL support.The close button uses
mr-1(margin-right), which won't flip correctly in RTL layouts for Hebrew. Useme-1(margin-inline-end) instead, which automatically adapts to text direction.🔎 Proposed fix for RTL support
className={cn( - 'h-6 w-6 p-0 mr-1 opacity-0 group-hover:opacity-100', + 'h-6 w-6 p-0 me-1 opacity-0 group-hover:opacity-100', 'transition-opacity duration-200 rounded', 'hover:bg-destructive hover:text-destructive-foreground',apps/frontend/src/renderer/components/SortableFeatureCard.tsx (1)
88-88: Priority labels should be translated.The
ROADMAP_PRIORITY_LABELSconstant contains user-facing text that should be internationalized like other strings in this component. Hebrew users will currently see English priority labels.🔎 Suggested approach
Replace the constant lookup with a translation key:
- > - {ROADMAP_PRIORITY_LABELS[feature.priority]} - </Badge> + > + {t(`featureCard.priority.${feature.priority}`)} + </Badge>Then add the corresponding keys to translation files (e.g.,
roadmap.json):{ "featureCard": { "priority": { "p0": "Critical", "p1": "High", "p2": "Medium", "p3": "Low" } } }As per coding guidelines and learnings.
apps/frontend/src/renderer/components/task-detail/task-review/DiscardDialog.tsx (2)
43-49: Critical:tfunction is undefined - missing useTranslation import and hook.The
t()function is called on line 45 butuseTranslationis neither imported nor initialized in this component. This will cause a runtimeReferenceError: t is not defined.🔎 Proposed fix to add missing i18n setup
import { FolderX, Loader2 } from 'lucide-react'; +import { useTranslation } from 'react-i18next'; import { AlertDialog, AlertDialogAction,And inside the component function:
export function DiscardDialog({ open, task, worktreeStatus, isDiscarding, onOpenChange, onDiscard }: DiscardDialogProps) { + const { t } = useTranslation('dialogs'); return (
40-40: Multiple hardcoded strings need internationalization.Per coding guidelines, all user-facing text must use translation keys. The following strings are hardcoded:
- Line 40:
"Discard Build"(title)- Lines 48-49:
"This will permanently delete..."(description)- Lines 54, 57:
"Files changed:","Lines:"(labels)- Line 68:
"Cancel"- Line 80:
"Discarding..."- Line 85:
"Discard Build"(button)🔎 Proposed fix for remaining hardcoded strings
<AlertDialogHeader> <AlertDialogTitle className="flex items-center gap-2"> <FolderX className="h-5 w-5 text-destructive" /> - Discard Build + {t('discardBuild.title')} </AlertDialogTitle> <AlertDialogDescription asChild> <div className="text-sm text-muted-foreground space-y-3"> <p> {t('dialogs.discardChanges')} <strong className="text-foreground">"{task.title}"</strong>? </p> <p className="text-destructive"> - This will permanently delete the isolated workspace and all uncommitted changes. - The task will be moved back to Planning status. + {t('discardBuild.warning')} </p> {worktreeStatus?.exists && ( <div className="bg-muted/50 rounded-lg p-3 text-sm"> <div className="flex justify-between mb-1"> - <span className="text-muted-foreground">Files changed:</span> + <span className="text-muted-foreground">{t('discardBuild.filesChanged')}</span> <span>{worktreeStatus.filesChanged || 0}</span> </div> <div className="flex justify-between"> - <span className="text-muted-foreground">Lines:</span> + <span className="text-muted-foreground">{t('discardBuild.lines')}</span> <span className="text-success">+{worktreeStatus.additions || 0}</span> <span className="text-destructive">-{worktreeStatus.deletions || 0}</span> </div> </div> )} </div> </AlertDialogDescription> </AlertDialogHeader> <AlertDialogFooter> - <AlertDialogCancel disabled={isDiscarding}>Cancel</AlertDialogCancel> + <AlertDialogCancel disabled={isDiscarding}>{t('common.cancel')}</AlertDialogCancel> <AlertDialogAction onClick={(e) => { e.preventDefault(); onDiscard(); }} disabled={isDiscarding} className="bg-destructive text-destructive-foreground hover:bg-destructive/90" > {isDiscarding ? ( <> <Loader2 className="mr-2 h-4 w-4 animate-spin" /> - Discarding... + {t('discardBuild.discarding')} </> ) : ( <> <FolderX className="mr-2 h-4 w-4" /> - Discard Build + {t('discardBuild.title')} </> )} </AlertDialogAction> </AlertDialogFooter>Also applies to: 48-49, 54-60, 68-68, 77-86
apps/frontend/src/renderer/components/ideation/IdeaDetailPanel.tsx (1)
52-52: Multiple hardcoded strings need internationalization.Per coding guidelines, all user-facing text must use translation keys. The following strings are hardcoded:
- Line 52:
{idea.status}(should uset(\status.${idea.status}`)`)- Line 68:
"Description"- Line 76:
"Rationale"- Line 95:
"Convert to Auto-Build Task"- Line 103:
"Dismiss Idea"- Line 111:
"Go to Task"🔎 Proposed fix for hardcoded strings
{idea.status !== 'draft' && ( <Badge variant="outline" className={IDEATION_STATUS_COLORS[idea.status]}> - {idea.status} + {t(`status.${idea.status}`)} </Badge> )}{/* Description */} <div> - <h3 className="text-sm font-medium mb-2">Description</h3> + <h3 className="text-sm font-medium mb-2">{t('description')}</h3> <p className="text-sm text-muted-foreground">{idea.description}</p> </div> {/* Rationale */} <div> <h3 className="text-sm font-medium mb-2 flex items-center gap-2"> <Lightbulb className="h-4 w-4" /> - Rationale + {t('rationale')} </h3>{!isDismissed && !isConverted && ( <div className="shrink-0 p-4 border-t border-border space-y-2"> <Button className="w-full" onClick={() => onConvert(idea)}> <Play className="h-4 w-4 mr-2" /> - Convert to Auto-Build Task + {t('convertToTask')} </Button> <Button variant="outline" className="w-full" onClick={() => onDismiss(idea)} > <X className="h-4 w-4 mr-2" /> - Dismiss Idea + {t('dismissIdea')} </Button> </div> )} {isConverted && idea.taskId && onGoToTask && ( <div className="shrink-0 p-4 border-t border-border"> <Button className="w-full" onClick={() => onGoToTask(idea.taskId!)}> <ExternalLink className="h-4 w-4 mr-2" /> - Go to Task + {t('goToTask')} </Button> </div> )}Also applies to: 68-69, 74-78, 93-105, 107-112
apps/frontend/src/renderer/components/task-detail/TaskHeader.tsx (1)
49-63: Multiple hardcoded strings need internationalization.Per coding guidelines, all user-facing text must use translation keys. Several strings remain hardcoded:
- Line 52:
"Stuck"- Line 58:
"Incomplete"- Line 61:
"{taskProgress.completed}/{taskProgress.total} subtasks"- Lines 77-79:
"Completed","Has Errors","Approve Plan","QA Issues"- Line 102:
"Cannot edit while task is running","Edit task"🔎 Proposed fix for hardcoded strings
{isStuck ? ( <Badge variant="warning" className="text-xs flex items-center gap-1 animate-pulse"> <AlertTriangle className="h-3 w-3" /> - Stuck + {t('labels.stuck')} </Badge> ) : isIncomplete ? ( <> <Badge variant="warning" className="text-xs flex items-center gap-1"> <AlertTriangle className="h-3 w-3" /> - Incomplete + {t('labels.incomplete')} </Badge> <Badge variant="outline" className="text-xs text-orange-400"> - {taskProgress.completed}/{taskProgress.total} subtasks + {t('subtasksProgress', { completed: taskProgress.completed, total: taskProgress.total })} </Badge> </>{task.status === 'human_review' && task.reviewReason && ( <Badge variant={task.reviewReason === 'completed' ? 'success' : task.reviewReason === 'errors' ? 'destructive' : 'warning'} className="text-xs" > - {task.reviewReason === 'completed' ? 'Completed' : - task.reviewReason === 'errors' ? 'Has Errors' : - task.reviewReason === 'plan_review' ? 'Approve Plan' : 'QA Issues'} + {t(`reviewReason.${task.reviewReason === 'errors' ? 'hasErrors' : task.reviewReason === 'plan_review' ? 'approvePlan' : task.reviewReason}`)} </Badge> )}<TooltipContent side="bottom"> - {isRunning && !isStuck ? 'Cannot edit while task is running' : 'Edit task'} + {isRunning && !isStuck ? t('tooltips.cannotEditWhileRunning') : t('tooltips.editTask')} </TooltipContent>Also applies to: 72-80, 101-103
apps/frontend/src/shared/i18n/locales/en/tasks.json (1)
1-135: Add missing translation keys toapps/frontend/src/shared/i18n/locales/fr/tasks.json.The English locale file adds new sections (
form,errors,editDialog) and status keys (ai_review,human_review), but the French translation file is missing these sections entirely. Per coding guidelines, new translation keys must be added to ALL language files (minimum:en/*.jsonandfr/*.json). Updatefr/tasks.jsonto include all new translations that correspond to the entries inen/tasks.json.apps/frontend/src/renderer/components/task-detail/TaskMetadata.tsx (1)
158-221: Consider localizing remaining hardcoded section labels.While the timestamp labels are now localized, several section headers remain as hardcoded English strings:
- "Rationale" (line 158)
- "Problem Solved" (line 169)
- "Target Audience" (line 180)
- "Dependencies" (line 191)
- "Acceptance Criteria" (line 206)
- "Affected Files" (line 221)
These user-facing strings should also use translation keys for consistency with the i18n effort.
As per coding guidelines, always use translation keys for all user-facing text.
apps/frontend/src/renderer/components/task-detail/task-review/ConflictDetailsDialog.tsx (1)
43-119: Consider localizing remaining hardcoded strings.While the Close button is now localized, several user-facing strings remain hardcoded:
- "Merge Conflicts Preview" (line 43)
- "potential conflict(s) detected" (line 46)
- "can be auto-merged" (line 49)
- "Location:", "Reason:", "Strategy:" (lines 90-96)
- "No conflicts detected" (line 104)
- "Stage with AI Merge" / "Merge with AI" (line 119)
Consider localizing these strings for complete i18n coverage of this dialog.
As per coding guidelines, always use translation keys for all user-facing text.
apps/frontend/src/renderer/components/TaskFileExplorerDrawer.tsx (1)
78-106: Add missing translation keys to French locale file.All four translation keys are missing from
fr/common.json:
fileExplorer.titletooltips.refreshtooltips.closefileExplorer.dragReferencesThese keys exist in
en/common.jsonandhe/common.json, but French translations must be added toapps/frontend/src/shared/i18n/locales/fr/common.jsonbefore this change can be approved.apps/frontend/src/renderer/components/UsageIndicator.tsx (1)
68-136: Add missing translation keys to French locale file.Verification found that all translation keys exist in
en/common.jsonandhe/common.json, but the following keys are missing fromfr/common.json:
usage.statususage.sessionUsageusage.resetsusage.weeklyUsageusage.activeAccountPer coding guidelines, translation keys must be added to ALL language files. Update
apps/frontend/src/shared/i18n/locales/fr/common.jsonwith the missing keys before this change can be approved.apps/frontend/src/renderer/components/FileExplorerPanel.tsx (1)
77-104: Add missing translation keys tofr/common.json.The following keys are missing from
fr/common.jsonand must be added:
fileExplorer.titletooltips.refreshfileExplorer.dragHintThese keys already exist in
en/common.jsonandhe/common.json. Per guidelines, all translation keys must be added to all language files (minimumen/*.jsonandfr/*.json).Additionally, the Close button (lines 89-96) lacks a
titleattribute for accessibility. Consider addingtitle={t('tooltips.close')}to match the Refresh button pattern.apps/frontend/src/renderer/components/CompetitorAnalysisDialog.tsx (1)
45-105: Createfr/roadmap.jsonwith all competitorDialog translation keys.The French locale is missing the
roadmap.jsonfile entirely. All translation keys used inCompetitorAnalysisDialog.tsxmust be added toapps/frontend/src/shared/i18n/locales/fr/roadmap.json:
competitorDialog.titlecompetitorDialog.descriptioncompetitorDialog.whatItDoescompetitorDialog.identifiesCompetitorscompetitorDialog.searchesFeedbackcompetitorDialog.suggestsFeaturescompetitorDialog.webSearchesTitlecompetitorDialog.webSearchesDescriptioncompetitorDialog.optionalInfocompetitorDialog.skipButtoncompetitorDialog.enableButtonThe keys exist in
en/roadmap.jsonandhe/roadmap.json, but the French translation file is missing entirely.apps/frontend/src/renderer/components/terminal/TaskSelector.tsx (1)
158-158: Fix hardcoded string - use translation key.Line 158 contains a hardcoded string
"Add new task"that should use the translation key. This is inconsistent with line 139 which correctly usest('taskSelector.addNewTask')for the same text.Based on learnings, never use hardcoded strings in JSX/TSX files for user-facing text.
🔎 Proposed fix
- Add new task + {t('taskSelector.addNewTask')}apps/frontend/src/renderer/components/context/MemoryCard.tsx (2)
115-119: Hardcoded string"Session #"should use translation key.The session label concatenates a hardcoded English string with the session number. Per coding guidelines, all user-facing text should use translation keys.
Proposed fix
const sessionLabel = memory.session_number - ? `Session #${memory.session_number}` + ? t('memories.memoryCard.sessionNumber', { number: memory.session_number }) : parsed?.session_number - ? `Session #${parsed.session_number}` + ? t('memories.memoryCard.sessionNumber', { number: parsed.session_number }) : null;Add the corresponding key to the context namespace translation files:
"memories": { "memoryCard": { "sessionNumber": "Session #{{number}}" } }
134-136: Memory type badge displays untranslated text.
memory.type.replace(/_/g, ' ')displays the raw type value (e.g., "session_insight" → "session insight"). For full i18n support, consider using a translation key for memory types.Proposed approach
<Badge variant="outline" className="text-xs capitalize font-medium"> - {memory.type.replace(/_/g, ' ')} + {t(`memories.types.${memory.type}`, memory.type.replace(/_/g, ' '))} </Badge>This uses the type as a fallback if the translation key doesn't exist.
apps/frontend/src/renderer/components/AgentProfiles.tsx (2)
89-92: Profile name and description are not translated.
profile.nameandprofile.descriptionare rendered directly fromDEFAULT_AGENT_PROFILES. For full Hebrew support, these should use translation keys.Proposed approach
<div className="flex-1 min-w-0"> - <h3 className="font-semibold text-foreground">{profile.name}</h3> + <h3 className="font-semibold text-foreground"> + {t(`agentProfile.profiles.${profile.id}.name`, profile.name)} + </h3> <p className="mt-1 text-sm text-muted-foreground"> - {profile.description} + {t(`agentProfile.profiles.${profile.id}.description`, profile.description)} </p>Then add corresponding keys in the settings namespace translation files for each profile (e.g.,
auto,balanced,thorough).
96-101: Model and thinking level labels are not translated.
getModelLabelandgetThinkingLabelreturn labels from constants. For complete i18n, consider translating these as well, or at minimum the "Thinking" suffix is correctly translated.apps/frontend/src/renderer/components/GitHubSetupModal.tsx (2)
489-508: Add explicittype="button"to prevent unintended form submission.These buttons lack an explicit
typeattribute. The default type is"submit", which can cause unintended form submissions when placed inside a form element.Proposed fix
<button + type="button" onClick={() => setRepoAction('create')} className="flex flex-col items-center gap-2 p-4 rounded-lg border-2 border-dashed hover:border-primary hover:bg-primary/5 transition-colors" > ... </button> <button + type="button" onClick={() => setRepoAction('link')} className="flex flex-col items-center gap-2 p-4 rounded-lg border-2 border-dashed hover:border-primary hover:bg-primary/5 transition-colors" >Apply the same fix to other
<button>elements without explicit types (lines 516, 537, 551, 595, 607, 628).
280-283: Hardcoded error messages should use translation keys.Error messages like
'Please enter a repository name'and'Please select an owner for the repository'are hardcoded in English.Proposed fix
if (!newRepoName.trim()) { - setError('Please enter a repository name'); + setError(t('githubSetup.errors.repoNameRequired')); return; } if (!selectedOwner) { - setError('Please select an owner for the repository'); + setError(t('githubSetup.errors.ownerRequired')); return; }Similar changes needed for error messages at lines 333, 339.
apps/frontend/src/renderer/components/ideation/IdeaCard.tsx (1)
142-142: Translate hardcoded tooltip strings.The tooltip content strings are still hardcoded in English ("Convert to Task", "Dismiss", "Go to Task") and should use translation keys. Based on coding guidelines, all user-facing text must reference translation keys from the i18n locales.
🔎 Proposed fix
- <TooltipContent>Convert to Task</TooltipContent> + <TooltipContent>{t('card.convertToTask')}</TooltipContent>- <TooltipContent>Dismiss</TooltipContent> + <TooltipContent>{t('card.dismiss')}</TooltipContent>- <TooltipContent>Go to Task</TooltipContent> + <TooltipContent>{t('card.goToTask')}</TooltipContent>Remember to add these keys to all language files (minimum:
en/ideation.json,fr/ideation.json, andhe/ideation.json).Based on learnings, coding guidelines require all user-facing text to use translation keys.
Also applies to: 158-158, 179-179, 200-200
apps/frontend/src/renderer/components/task-detail/task-review/DiffViewDialog.tsx (1)
73-73: Consider translating file status labels.The file status badges display raw git status values (
file.status) without translation. While these are technical terms, for a fully localized user experience, consider translating them (e.g.,t(\diffDialog.status.${file.status}``)) to maintain consistency with the rest of the UI.apps/frontend/src/renderer/components/settings/ThemeSelector.tsx (1)
118-118: Translate hardcoded title attributes on color preview elements.The
titleattributes on the color preview divs (lines 118 and 123) contain hardcoded English text "Background color" and "Accent color". These are user-facing tooltips and should use translation keys per coding guidelines.🔎 Proposed fix
<div className="w-6 h-6 rounded-full border-2 border-background shadow-sm" style={{ backgroundColor: bgColor }} - title="Background color" + title={t('theme.backgroundColorTooltip')} /> <div className="w-6 h-6 rounded-full border-2 border-background shadow-sm" style={{ backgroundColor: accentColor }} - title="Accent color" + title={t('theme.accentColorTooltip')} />Remember to add these keys to all language files (minimum:
en/settings.json,fr/settings.json, andhe/settings.json).Based on coding guidelines, all user-facing text must use translation keys.
Also applies to: 123-123
apps/frontend/src/renderer/components/ExistingCompetitorAnalysisDialog.tsx (1)
48-52: Use dynamic locale for date formatting instead of hardcoded 'en-US'.The
Intl.DateTimeFormatis instantiated with a hardcoded'en-US'locale, which doesn't respect the user's selected language. For proper internationalization, use the current i18n language setting.🔎 Proposed fix
+ const { i18n } = useTranslation('roadmap'); + const formatDate = (date?: Date) => { if (!date) return t('competitorAnalysis.recently'); - return new Intl.DateTimeFormat('en-US', { + return new Intl.DateTimeFormat(i18n.language, { month: 'short', day: 'numeric', year: 'numeric', }).format(date); };This ensures dates are formatted according to the user's selected language (e.g., Hebrew users see Hebrew date formats).
apps/frontend/src/renderer/components/context/MemoriesTab.tsx (2)
66-93: Consider translating additional user-facing strings.While the main labels are now internationalized, several user-facing strings remain hardcoded:
- Line 69: "Connected"
- Line 83: "Database", "Path" (InfoItem labels)
- Line 86: "Episodes"
- Line 91: "Last session"
These should also use translation keys for complete i18n support, especially for RTL languages like Hebrew where term order and formatting may differ.
126-138: Consider internationalizing search results text.The search results count message (Line 127) uses a template literal with conditional pluralization:
{searchResults.length} result{searchResults.length !== 1 ? 's' : ''} foundAnd Line 137 shows "Score: {result.score.toFixed(2)}".
For proper i18n support, especially with languages that have different pluralization rules, consider using translation keys with pluralization support (e.g.,
t('memories.resultsCount', { count: searchResults.length })).apps/frontend/src/renderer/components/task-detail/TaskDetailModal.tsx (5)
214-220: Hardcoded string: Translate completion message.Line 217 contains the hardcoded string "Task completed" which should use a translation key.
🔎 Proposed fix
<div className="completion-state text-sm flex items-center gap-2 text-success"> <CheckCircle2 className="h-5 w-5" /> - <span className="font-medium">Task completed</span> + <span className="font-medium">{t('messages.taskCompleted')}</span> </div>As per coding guidelines: Never use hardcoded strings in JSX/TSX files for user-facing text.
285-293: Hardcoded strings: Translate review reason labels.Lines 290-292 contain hardcoded review reason labels ("Completed", "Has Errors", "Approve Plan", "QA Issues") that should use translation keys.
🔎 Proposed fix
<Badge variant={task.reviewReason === 'completed' ? 'success' : task.reviewReason === 'errors' ? 'destructive' : 'warning'} className="text-xs" > - {task.reviewReason === 'completed' ? 'Completed' : - task.reviewReason === 'errors' ? 'Has Errors' : - task.reviewReason === 'plan_review' ? 'Approve Plan' : 'QA Issues'} + {t(`reviewReasons.${task.reviewReason}`)} </Badge>As per coding guidelines: Always use translation keys with
useTranslation()for all user-facing text.
298-301: Hardcoded string: Translate subtasks label.Line 300 contains the hardcoded string "subtasks" which should use a translation key for proper pluralization and localization.
🔎 Proposed fix
{totalSubtasks > 0 && ( <span className="text-xs text-muted-foreground ml-1"> - {completedSubtasks}/{totalSubtasks} subtasks + {t('labels.subtasksCount', { completed: completedSubtasks, total: totalSubtasks })} </span> )}
486-491: Hardcoded strings: Translate delete warning message.Lines 490-491 contain a long hardcoded warning message that should use a translation key.
🔎 Proposed fix
<p className="text-destructive"> - This action cannot be undone. All task files, including the spec, implementation plan, and any generated code will be permanently deleted from the project. + {t('dialogs.deleteWarning')} </p>
510-520: Hardcoded strings: Translate delete action button text.Lines 513 and 518 contain hardcoded strings ("Deleting...", "Delete Permanently") that should use translation keys.
🔎 Proposed fix
{state.isDeleting ? ( <> <Loader2 className="mr-2 h-4 w-4 animate-spin" /> - Deleting... + {t('buttons.deleting')} </> ) : ( <> <Trash2 className="mr-2 h-4 w-4" /> - Delete Permanently + {t('buttons.deletePermanently')} </> )}apps/frontend/src/renderer/components/context/ProjectIndexTab.tsx (4)
88-112: Hardcoded strings: Translate Overview section.Line 94 contains "Overview" and Lines 103-104 contain service count text with manual pluralization logic. These should use translation keys with proper i18n pluralization support.
🔎 Proposed fix
<Card> <CardHeader className="pb-3"> - <CardTitle className="text-base">Overview</CardTitle> + <CardTitle className="text-base">{t('projectIndex.overview.title')}</CardTitle> </CardHeader> <CardContent className="space-y-3"> <div className="flex items-center gap-2"> <Badge variant="outline" className="capitalize"> {projectIndex.project_type} </Badge> {Object.keys(projectIndex.services).length > 0 && ( <Badge variant="secondary"> - {Object.keys(projectIndex.services).length} service - {Object.keys(projectIndex.services).length !== 1 ? 's' : ''} + {t('projectIndex.overview.servicesCount', { count: Object.keys(projectIndex.services).length })} </Badge> )}As per coding guidelines: Always use translation keys with proper pluralization support.
115-126: Hardcoded string: Translate Services section heading.Line 118 contains the hardcoded string "Services" which should use a translation key.
🔎 Proposed fix
<div className="space-y-4"> <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wider"> - Services + {t('projectIndex.services.title')} </h3>
128-163: Hardcoded strings: Translate Infrastructure section.Line 132 contains "Infrastructure" and Lines 138-158 contain infrastructure-related labels ("Docker Compose", "CI/CD", "Deployment", "Docker Services") that should use translation keys.
🔎 Proposed fix
<h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wider"> - Infrastructure + {t('projectIndex.infrastructure.title')} </h3> <Card> <CardContent className="pt-6"> <div className="grid gap-4 sm:grid-cols-2"> {projectIndex.infrastructure.docker_compose && ( - <InfoItem label="Docker Compose" value={projectIndex.infrastructure.docker_compose} /> + <InfoItem label={t('projectIndex.infrastructure.dockerCompose')} value={projectIndex.infrastructure.docker_compose} /> )} {projectIndex.infrastructure.ci && ( - <InfoItem label="CI/CD" value={projectIndex.infrastructure.ci} /> + <InfoItem label={t('projectIndex.infrastructure.cicd')} value={projectIndex.infrastructure.ci} /> )} {projectIndex.infrastructure.deployment && ( - <InfoItem label="Deployment" value={projectIndex.infrastructure.deployment} /> + <InfoItem label={t('projectIndex.infrastructure.deployment')} value={projectIndex.infrastructure.deployment} /> )} {projectIndex.infrastructure.docker_services && projectIndex.infrastructure.docker_services.length > 0 && ( <div className="sm:col-span-2"> - <span className="text-xs text-muted-foreground">Docker Services</span> + <span className="text-xs text-muted-foreground">{t('projectIndex.infrastructure.dockerServices')}</span>
165-194: Hardcoded strings: Translate Conventions section.Line 169 contains "Conventions" and Lines 175-187 contain convention-related labels that should use translation keys.
🔎 Proposed fix
<h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wider"> - Conventions + {t('projectIndex.conventions.title')} </h3> <Card> <CardContent className="pt-6"> <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3"> {projectIndex.conventions.python_linting && ( - <InfoItem label="Python Linting" value={projectIndex.conventions.python_linting} /> + <InfoItem label={t('projectIndex.conventions.pythonLinting')} value={projectIndex.conventions.python_linting} /> )} {projectIndex.conventions.js_linting && ( - <InfoItem label="JS Linting" value={projectIndex.conventions.js_linting} /> + <InfoItem label={t('projectIndex.conventions.jsLinting')} value={projectIndex.conventions.js_linting} /> )} {projectIndex.conventions.formatting && ( - <InfoItem label="Formatting" value={projectIndex.conventions.formatting} /> + <InfoItem label={t('projectIndex.conventions.formatting')} value={projectIndex.conventions.formatting} /> )} {projectIndex.conventions.git_hooks && ( - <InfoItem label="Git Hooks" value={projectIndex.conventions.git_hooks} /> + <InfoItem label={t('projectIndex.conventions.gitHooks')} value={projectIndex.conventions.git_hooks} /> )} {projectIndex.conventions.typescript && ( - <InfoItem label="TypeScript" value="Enabled" /> + <InfoItem label={t('projectIndex.conventions.typescript')} value={t('projectIndex.conventions.enabled')} /> )}apps/frontend/src/renderer/components/roadmap/FeatureDetailPanel.tsx (3)
216-222: Hardcoded string: Translate button text.Line 220 contains the hardcoded string "Go to Task" which should use a translation key.
🔎 Proposed fix
<Button className="w-full" onClick={() => onGoToTask(feature.linkedSpecId!)}> <ExternalLink className="h-4 w-4 mr-2" /> - Go to Task + {t('featureDetail.goToTask')} </Button>As per coding guidelines: Always use translation keys for all user-facing text.
224-232: Hardcoded string: Translate button text.Line 228 contains the hardcoded string "Convert to Auto-Build Task" which should use a translation key.
🔎 Proposed fix
<Button className="w-full" onClick={() => onConvertToSpec(feature)}> <Zap className="h-4 w-4 mr-2" /> - Convert to Auto-Build Task + {t('featureDetail.convertToTask')} </Button>
194-207: Hardcoded string: Translate severity label.Line 205 contains the hardcoded string "severity" which should use a translation key.
🔎 Proposed fix
<Badge variant="outline" className={`text-xs ${ insight.severity === 'high' ? 'text-red-500 border-red-500/50' : insight.severity === 'medium' ? 'text-yellow-500 border-yellow-500/50' : 'text-green-500 border-green-500/50' }`} > - {insight.severity} severity + {t('featureDetail.severity', { level: insight.severity })} </Badge>apps/frontend/src/renderer/components/ideation/IdeationDialogs.tsx (1)
48-177: Add French translation file for ideation component.The code correctly implements i18n with proper translation keys that all exist in
en/ideation.json. However,fr/ideation.jsonis completely missing. Per the project requirements, all new translation keys must be added to both English and French locale files (minimum:en/*.jsonandfr/*.json). Createapps/frontend/src/shared/i18n/locales/fr/ideation.jsonwith French translations for all keys present in the English version.apps/frontend/src/renderer/components/Worktrees.tsx (4)
81-84: Hardcoded error messages should use translation keys.Error messages displayed to users should be internationalized. The strings
'Failed to load worktrees'are hardcoded.As per coding guidelines, never use hardcoded strings for user-facing text.
🔎 Proposed fix
if (result.success && result.data) { setWorktrees(result.data.worktrees); } else { - setError(result.error || 'Failed to load worktrees'); + setError(result.error || t('loadFailed')); } } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to load worktrees'); + setError(err instanceof Error ? err.message : t('loadFailed')); } finally {
106-107: Additional hardcoded error messages need translation.Lines 106, 141:
'Task not found for this worktree'and Lines 154, 157:'Failed to delete worktree'should use translation keys for consistency.🔎 Proposed fix
if (!task) { - setError('Task not found for this worktree'); + setError(t('taskNotFound')); return; }Add corresponding keys to
worktrees.json:{ "loadFailed": "Failed to load worktrees", "taskNotFound": "Task not found for this worktree", "deleteFailed": "Failed to delete worktree" }Also applies to: 140-142
120-128: Hardcoded merge failure messages.The
'Merge failed'strings on lines 122 and 128 should use a translation key.🔎 Proposed fix
} else { setMergeResult({ success: false, - message: result.error || 'Merge failed' + message: result.error || t('mergeFailed') }); } } catch (err) { setMergeResult({ success: false, - message: err instanceof Error ? err.message : 'Merge failed' + message: err instanceof Error ? err.message : t('mergeFailed') });
1-49: Add missing French translation file for worktrees namespace.The component uses
useTranslation('worktrees')but the requiredapps/frontend/src/shared/i18n/locales/fr/worktrees.jsonfile is missing. Coding guidelines require translation keys to be added to all language files (minimum:en/*.jsonandfr/*.json). Create the French translation file with all keys currently used in the component.apps/frontend/src/renderer/components/onboarding/OAuthStep.tsx (5)
148-156: Hardcoded alert messages should be translated.The authentication flow messages in
handleAddProfileare hardcoded English strings. These user-facing messages should use translation keys.As per coding guidelines, never use hardcoded strings for user-facing text.
🔎 Proposed fix
if (initResult.success) { await loadClaudeProfiles(); setNewProfileName(''); - alert( - `Authenticating "${profileName}"...\n\n` + - `A browser window will open for you to log in with your Claude account.\n\n` + - `The authentication will be saved automatically once complete.` - ); + alert(t('oauth.alerts.authenticating', { profileName })); } else { await loadClaudeProfiles(); - alert(`Failed to start authentication: ${initResult.error || 'Please try again.'}`); + alert(t('oauth.alerts.authFailed', { error: initResult.error || t('oauth.errors.tryAgain') })); }
227-237: More hardcoded alert messages in handleAuthenticateProfile.Similar to
handleAddProfile, these authentication alerts use hardcoded English strings.🔎 Proposed fix
if (initResult.success) { - alert( - `Authenticating profile...\n\n` + - `A browser window will open for you to log in with your Claude account.\n\n` + - `The authentication will be saved automatically once complete.` - ); + alert(t('oauth.alerts.authenticatingProfile')); } else { - alert(`Failed to start authentication: ${initResult.error || 'Please try again.'}`); + alert(t('oauth.alerts.authFailed', { error: initResult.error || t('oauth.errors.tryAgain') })); } } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to authenticate profile'); - alert('Failed to start authentication. Please try again.'); + setError(err instanceof Error ? err.message : t('oauth.errors.authProfileFailed')); + alert(t('oauth.alerts.authStartFailed'));
364-366: Hardcoded empty state message.Line 366 contains hardcoded text
"No accounts configured yet".🔎 Proposed fix
{claudeProfiles.length === 0 ? ( <div className="rounded-lg border border-dashed border-border p-4 text-center mb-4"> - <p className="text-sm text-muted-foreground">No accounts configured yet</p> + <p className="text-sm text-muted-foreground">{t('oauth.noAccountsYet')}</p> </div>
530-537: Manual token entry section has multiple hardcoded strings.The manual token entry UI contains several untranslated strings:
- Line 533: "Manual Token Entry"
- Line 536: Instructions text
- Line 574: "Cancel"
- Line 587: "Save Token"
🔎 Proposed fix
<Label className="text-xs font-medium text-muted-foreground"> - Manual Token Entry + {t('oauth.manualTokenEntry')} </Label> <span className="text-xs text-muted-foreground"> - Run <code className="px-1 py-0.5 bg-muted rounded font-mono text-xs">claude setup-token</code> to get your token + {t('oauth.tokenInstructions')} </span><Button variant="ghost" size="sm" onClick={() => toggleTokenEntry(profile.id)} className="h-7 text-xs" > - Cancel + {t('oauth.cancel')} </Button>- Save Token + {t('oauth.saveTokenButton')}Also applies to: 574-574, 587-587
490-490: Hardcoded title attributes on buttons.Button
titleattributes on lines 490 and 503 ("Rename profile","Delete profile") should be translated for accessibility.🔎 Proposed fix
<Button variant="ghost" size="icon" onClick={() => startEditingProfile(profile)} className="h-7 w-7 text-muted-foreground hover:text-foreground" - title="Rename profile" + title={t('oauth.renameProfile')} >Also applies to: 503-503
apps/frontend/src/renderer/components/changelog/ChangelogList.tsx (1)
52-63: Hardcoded fallback string'item'should use translation key.The default case returns a hardcoded English string
'item'which will not be translated. As per coding guidelines, never use hardcoded strings for user-facing text.🔎 Proposed fix
case 'git-history': case 'branch-diff': return count !== 1 ? t('commits.commits') : t('commits.commit'); default: - return 'item'; + return t('commits.item'); }apps/frontend/src/renderer/components/onboarding/OllamaModelSelector.tsx (2)
30-52: Model descriptions are hardcoded English strings.The
descriptionfield inRECOMMENDED_MODELScontains hardcoded English strings that won't be translated. These should use translation keys or be moved to translation files.🔎 Suggested approach
Option 1: Use translation keys in the component:
const RECOMMENDED_MODELS: OllamaModel[] = [ { name: 'embeddinggemma', descriptionKey: 'ollama.models.embeddinggemma', // Use key instead size_estimate: '621 MB', dim: 768, installed: false, }, // ... ];Then in the render:
<p className="text-xs text-muted-foreground">{t(model.descriptionKey)}</p>Option 2: Keep the existing keys
ollama.googleLightweight,ollama.popularGeneral,ollama.mixedBreadLargeand map them by model name.
397-397: Model description rendered without translation.Line 397 displays
model.descriptiondirectly, which contains hardcoded English text from theRECOMMENDED_MODELSarray. This bypasses the i18n system.apps/frontend/src/renderer/components/EnvConfigModal.tsx (3)
383-387: Hardcoded "Saving..." text should use translation key.The text "Saving..." on line 386 is hardcoded and should use a translation key.
🔎 Proposed fix
{isSaving ? ( <> <Loader2 className="mr-2 h-5 w-5 animate-spin" /> - Saving... + {t('auth.saving')} </>
401-404: Hardcoded "or" divider should use translation key.The text "or" in the divider is hardcoded English. This appears in multiple places (lines 402 and 463).
🔎 Proposed fix
<div className="relative flex justify-center text-xs uppercase"> - <span className="bg-background px-2 text-muted-foreground">or</span> + <span className="bg-background px-2 text-muted-foreground">{t('auth.or', { ns: 'common' })}</span> </div>Apply the same fix at line 463.
495-507: Missingtypeattribute on button element.Static analysis indicates this button lacks an explicit
typeattribute. The default type is "submit", which may cause unintended form submission.🔎 Proposed fix
<button + type="button" onClick={handleCopyCommand} className="inline-flex items-center text-info hover:text-info/80" > <Copy className="h-3 w-3 ml-1" /> </button>apps/frontend/src/renderer/components/TaskEditDialog.tsx (1)
211-286: Missingtin useCallback dependencies.The
handlePastecallback usest()for error messages but doesn't includetin its dependency array. Whiletis typically stable, it's good practice to include it for correctness.🔎 Proposed fix
- }, [images]); + }, [images, t]);Apply similar changes to
handleTextareaDropat line 384.apps/frontend/src/renderer/components/Insights.tsx (4)
189-196: Hardcoded tooltip text violates i18n guidelines.The button's
titleattribute uses hardcoded English strings.🔎 Proposed fix
<Button variant="ghost" size="icon" className="h-8 w-8" onClick={() => setShowSidebar(!showSidebar)} - title={showSidebar ? 'Hide sidebar' : 'Show sidebar'} + title={showSidebar ? t('hideSidebar') : t('showSidebar')} >Add keys to
insights.json:"hideSidebar": "Hide sidebar", "showSidebar": "Show sidebar"As per coding guidelines, always use translation keys for all user-facing text.
394-397: Hardcoded "You" / "Assistant" labels in MessageBubble.These user-facing labels should use translation keys for consistency with the rest of the component.
🔎 Proposed fix
+function MessageBubble({ + message, + onCreateTask, + isCreatingTask, + taskCreated +}: MessageBubbleProps) { + const { t } = useTranslation('insights'); const isUser = message.role === 'user'; // ... <div className="text-sm font-medium text-foreground"> - {isUser ? 'You' : 'Assistant'} + {isUser ? t('you') : t('assistant')} </div>As per coding guidelines, never use hardcoded strings for user-facing text.
406-470: Hardcoded strings in task suggestion card.Multiple hardcoded strings need translation: "Suggested Task", "Creating...", "Task Created", "Create Task".
🔎 Proposed fix
<span className="text-sm font-medium text-primary"> - Suggested Task + {t('suggestedTask')} </span> // ... {isCreatingTask ? ( <> <Loader2 className="mr-2 h-4 w-4 animate-spin" /> - Creating... + {t('creating')} </> ) : taskCreated ? ( <> <CheckCircle2 className="mr-2 h-4 w-4" /> - Task Created + {t('taskCreated')} </> ) : ( <> <Plus className="mr-2 h-4 w-4" /> - Create Task + {t('createTask')} </> )}Add the
useTranslationhook toMessageBubbleand add keys toinsights.json.As per coding guidelines, always use translation keys for user-facing text.
540-543: Hardcoded tool count text in ToolUsageHistory.The pluralized "tool"/"tools" text should use translation keys with i18next pluralization.
🔎 Proposed fix
+function ToolUsageHistory({ tools }: ToolUsageHistoryProps) { + const { t } = useTranslation('insights'); // ... - <span>{tools.length} tool{tools.length !== 1 ? 's' : ''} used</span> + <span>{t('toolsUsed', { count: tools.length })}</span>In
insights.json:"toolsUsed": "{{count}} tool used", "toolsUsed_other": "{{count}} tools used"As per coding guidelines, use translation keys for all user-facing text.
| // Stop insights chat response | ||
| ipcMain.handle( | ||
| IPC_CHANNELS.INSIGHTS_STOP, | ||
| async (_, projectId: string): Promise<IPCResult> => { | ||
| const stopped = insightsService.stopChat(projectId); | ||
| if (stopped) { | ||
| const mainWindow = getMainWindow(); | ||
| if (mainWindow) { | ||
| mainWindow.webContents.send(IPC_CHANNELS.INSIGHTS_STOPPED, projectId); | ||
| } | ||
| return { success: true }; | ||
| } | ||
| return { success: false, error: 'No active chat session to stop' }; | ||
| } | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Look at the insights-handlers.ts file to see other handlers and their validation patterns
cat -n apps/frontend/src/main/ipc-handlers/insights-handlers.ts | head -100Repository: AndyMik90/Auto-Claude
Length of output: 4261
🏁 Script executed:
#!/bin/bash
# Search for projectStore.getProject usage in this file to understand the validation pattern
rg -n "projectStore.getProject" apps/frontend/src/main/ipc-handlers/insights-handlers.ts -B 2 -A 2Repository: AndyMik90/Auto-Claude
Length of output: 2895
🏁 Script executed:
#!/bin/bash
# Find and examine the stopChat implementation
rg -n "stopChat" --type ts -A 15Repository: AndyMik90/Auto-Claude
Length of output: 2545
🏁 Script executed:
#!/bin/bash
# Also check the IPC handler patterns - are there other similar stop/cancel handlers?
rg -n "ipcMain.handle" apps/frontend/src/main/ipc-handlers/insights-handlers.ts -A 3Repository: AndyMik90/Auto-Claude
Length of output: 2108
Add project validation for consistency with other handlers.
All other handlers in this file validate the project exists via projectStore.getProject(projectId) before proceeding. The INSIGHTS_STOP handler calls insightsService.stopChat(projectId) directly without this validation.
While stopChat only requires the projectId to cancel the session (not project data like project.path), adding validation would maintain consistency across all handlers and provide clearer error messages if the project is invalid.
🤖 Prompt for AI Agents
In apps/frontend/src/main/ipc-handlers/insights-handlers.ts around lines 261 to
275, the INSIGHTS_STOP handler skips validating the project like other handlers
do; add a call to projectStore.getProject(projectId) at the start, return the
same structured IPC error (e.g., { success: false, error: 'Project not found' }
or matching the file's existing message) if the project is missing, and only
then call insightsService.stopChat(projectId), send
IPC_CHANNELS.INSIGHTS_STOPPED if stopped, and return the existing
success/failure responses so behavior and error messages match other handlers in
this file.
| import type { EmptyStateProps, NotConnectedStateProps } from '../types'; | ||
|
|
||
| export function EmptyState({ searchQuery, icon: Icon = Github, message }: EmptyStateProps) { | ||
| const { t } = useTranslation('context'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find and verify translation keys in all locale files
echo "=== Available locale directories ==="
find apps/frontend/src/shared/i18n/locales -maxdepth 1 -type d ! -name "locales" | sort
echo -e "\n=== Checking for context.json files ==="
find apps/frontend/src/shared/i18n/locales -name "context.json" | sort
echo -e "\n=== Verifying translation keys in each locale ==="
for locale_file in $(find apps/frontend/src/shared/i18n/locales -name "context.json" | sort); do
echo -e "\n--- $locale_file ---"
jq -r '.github | keys' "$locale_file" 2>/dev/null || echo "Error reading file or 'github' key missing"
doneRepository: AndyMik90/Auto-Claude
Length of output: 764
🏁 Script executed:
#!/bin/bash
# Check French locale directory contents
echo "=== French locale directory contents ==="
ls -la apps/frontend/src/shared/i18n/locales/fr/
echo -e "\n=== Check if context.json exists in fr ==="
if [ -f apps/frontend/src/shared/i18n/locales/fr/context.json ]; then
echo "fr/context.json exists"
else
echo "fr/context.json MISSING"
fi
echo -e "\n=== Files in each locale directory ==="
for locale_dir in apps/frontend/src/shared/i18n/locales/*/; do
locale_name=$(basename "$locale_dir")
echo "$locale_name: $(ls -1 "$locale_dir" | tr '\n' ', ')"
doneRepository: AndyMik90/Auto-Claude
Length of output: 1398
Add missing context.json translation file to French locale.
The French locale is missing apps/frontend/src/shared/i18n/locales/fr/context.json. According to project learnings, new translation keys must be added to ALL language files (minimum: en and fr). The following keys must be translated to French:
github.noIssuesMatchgithub.notConnectedgithub.configureHintgithub.openSettings
Create fr/context.json with French translations for all keys present in en/context.json and he/context.json.
🤖 Prompt for AI Agents
In
apps/frontend/src/renderer/components/github-issues/components/EmptyStates.tsx
around line 7, the component calls useTranslation('context') but the French
locale is missing the required context.json; create
apps/frontend/src/shared/i18n/locales/fr/context.json containing French
translations for every key present in en/context.json and he/context.json (at
minimum include github.noIssuesMatch, github.notConnected, github.configureHint,
github.openSettings), ensure the file is valid UTF-8 JSON with the same key
structure as the other locales and commit it.
| <div className="text-center max-w-md"> | ||
| <GitPullRequest className="h-12 w-12 mx-auto mb-4 text-muted-foreground opacity-50" /> | ||
| <h3 className="text-lg font-medium mb-2">GitHub Not Connected</h3> | ||
| <h3 className="text-lg font-medium mb-2">{t('github.notConnected')}</h3> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify translation keys exist in all language files (en, fr, he)
echo "=== Checking for translation key files ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/$locale/context.json"
echo "Checking: $file"
if [ -f "$file" ]; then
echo "✓ File exists"
else
echo "✗ File NOT found"
fi
done
echo ""
echo "=== Checking for github keys in context.json files ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/$locale/context.json"
if [ ! -f "$file" ]; then
echo "[$locale] ERROR: File not found"
continue
fi
echo "[$locale] Checking keys in $file:"
# Check for each key
for key in "notConnected" "connectHint" "openSettings"; do
if jq -e ".github.$key" "$file" > /dev/null 2>&1; then
echo " ✓ github.$key exists"
else
echo " ✗ github.$key NOT found"
fi
done
echo ""
doneRepository: AndyMik90/Auto-Claude
Length of output: 767
🏁 Script executed:
#!/bin/bash
# Check what files exist in each locale directory
echo "=== Files in en locale ==="
ls -la apps/frontend/src/shared/i18n/locales/en/ 2>/dev/null || echo "Directory not found"
echo ""
echo "=== Files in fr locale ==="
ls -la apps/frontend/src/shared/i18n/locales/fr/ 2>/dev/null || echo "Directory not found"
echo ""
echo "=== Files in he locale ==="
ls -la apps/frontend/src/shared/i18n/locales/he/ 2>/dev/null || echo "Directory not found"
echo ""
echo "=== All locales available ==="
ls -d apps/frontend/src/shared/i18n/locales/*/ 2>/dev/null | xargs -I {} basename {} | sortRepository: AndyMik90/Auto-Claude
Length of output: 3026
Add missing French translations for GitHub context keys.
The translation keys github.notConnected, github.connectHint, and github.openSettings are correctly implemented in English and Hebrew, but the French locale is missing apps/frontend/src/shared/i18n/locales/fr/context.json entirely. Per the coding guidelines, all new translation keys must exist in ALL language files (minimum: en/*.json and fr/*.json). Create the French context.json file with translations for these keys.
🤖 Prompt for AI Agents
In apps/frontend/src/renderer/components/github-prs/GitHubPRs.tsx around line
26, the UI uses translation keys github.notConnected, github.connectHint, and
github.openSettings but the French locale is missing; create the file
apps/frontend/src/shared/i18n/locales/fr/context.json and add French
translations for those three keys (e.g. "github.notConnected": "Non connecté",
"github.connectHint": "Connectez votre compte GitHub pour afficher les PR",
"github.openSettings": "Ouvrir les paramètres") ensuring valid JSON and the same
key structure as the English locale.
| <Badge variant="outline" className={IDEATION_TYPE_COLORS[idea.type]}> | ||
| <TypeIcon type={idea.type} /> | ||
| <span className="ml-1">{IDEATION_TYPE_LABELS[idea.type]}</span> | ||
| <span className="ml-1">{t(`types.${idea.type.replace(/_/g, '-')}`)}</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check ideation type keys format in translation files
echo "=== Checking ideation type keys ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/$locale/ideation.json"
if [ -f "$file" ]; then
echo -e "\n$locale/ideation.json types:"
jq '.types // empty' "$file" 2>/dev/null || echo "No types key found"
fi
doneRepository: AndyMik90/Auto-Claude
Length of output: 631
🏁 Script executed:
#!/bin/bash
# Read the relevant section of the component
head -60 apps/frontend/src/renderer/components/ideation/IdeaDetailPanel.tsx | tail -20Repository: AndyMik90/Auto-Claude
Length of output: 997
🏁 Script executed:
#!/bin/bash
# Check if French ideation file exists and show its full content
echo "=== Checking French ideation.json ==="
if [ -f "apps/frontend/src/shared/i18n/locales/fr/ideation.json" ]; then
echo "File exists. Content:"
cat "apps/frontend/src/shared/i18n/locales/fr/ideation.json"
else
echo "File does not exist"
fi
echo -e "\n=== Comparing all locale files ==="
ls -la apps/frontend/src/shared/i18n/locales/*/ideation.json 2>/dev/null || echo "No ideation.json files found"Repository: AndyMik90/Auto-Claude
Length of output: 366
Create apps/frontend/src/shared/i18n/locales/fr/ideation.json with types translations.
The type key transformation using .replace(/_/g, '-') correctly matches the hyphen format in English and Hebrew translation files. However, the French translation file is missing entirely. Add French translations for all ideation types including: code-improvements, ui-ux-improvements, documentation-gaps, security-hardening, performance-optimizations, and code-quality.
🤖 Prompt for AI Agents
In apps/frontend/src/renderer/components/ideation/IdeaDetailPanel.tsx around
line 48 the code uses t(`types.${idea.type.replace(/_/g, '-')}`) but the French
locale file is missing; create
apps/frontend/src/shared/i18n/locales/fr/ideation.json and add a JSON object
"types" with keys exactly matching the hyphenated names: "code-improvements",
"ui-ux-improvements", "documentation-gaps", "security-hardening",
"performance-optimizations", and "code-quality", mapping each to the appropriate
French translation strings; ensure valid JSON (UTF-8) and that the file is
picked up by the i18n loader (same structure as en/he locale files).
| { | ||
| "terminal": { | ||
| "openTerminal": "פתח מסוף", | ||
| "openInbuilt": "פתח במסוף מובנה", | ||
| "openExternal": "פתח במסוף חיצוני" | ||
| }, | ||
| "actions": { | ||
| "recovering": "משחזר...", | ||
| "recoverTask": "שחזר משימה", | ||
| "resumeTask": "המשך משימה", | ||
| "stopTask": "עצור משימה", | ||
| "startTask": "התחל משימה", | ||
| "completedSuccessfully": "המשימה הושלמה בהצלחה", | ||
| "deleteTask": "מחק משימה", | ||
| "deleteTitle": "מחק משימה", | ||
| "deleteConfirmTitle": "האם אתה בטוח שברצונך למחוק", | ||
| "deleteWarning": "פעולה זו לא ניתנת לביטול. כל קבצי המשימה, כולל המפרט, תוכנית היישום וכל קוד שנוצר, יימחקו לצמיתות מהפרויקט.", | ||
| "cancel": "ביטול", | ||
| "deleting": "מוחק...", | ||
| "deletePermanently": "מחק לצמיתות" | ||
| }, | ||
| "subtasks": { | ||
| "noSubtasks": "אין תתי-משימות", | ||
| "afterPlanning": "תתי-משימות יישום יופיעו כאן לאחר התכנון", | ||
| "completedOf": "{{completed}} מתוך {{total}} הושלמו" | ||
| }, | ||
| "warnings": { | ||
| "taskStuckTitle": "המשימה נראית תקועה", | ||
| "taskStuckDescription": "משימה זו מסומנת כפועלת אך לא נמצא תהליך פעיל. זה יכול לקרות אם האפליקציה קרסה או התהליך הופסק באופן בלתי צפוי.", | ||
| "recoverAndRestart": "שחזר והפעל מחדש משימה", | ||
| "taskIncompleteTitle": "משימה לא הושלמה", | ||
| "taskIncompleteDescription": "למשימה זו יש מפרט ותוכנית יישום אבל מעולם לא השלימה אף תת-משימה ({{completed}}/{{total}}). התהליך כנראה קרס במהלך יצירת המפרט. לחץ המשך כדי להמשיך ביישום." | ||
| }, | ||
| "dialogs": { | ||
| "discardChanges": "האם אתה בטוח שברצונך למחוק את כל השינויים עבור", | ||
| "deleteTask": "האם אתה בטוח שברצונך למחוק" | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify translation key consistency across all locale files
echo "=== Checking if all required taskReview.json files exist ==="
files=(
"apps/frontend/src/shared/i18n/locales/en/taskReview.json"
"apps/frontend/src/shared/i18n/locales/fr/taskReview.json"
"apps/frontend/src/shared/i18n/locales/he/taskReview.json"
)
for file in "${files[@]}"; do
if [ -f "$file" ]; then
echo "✓ $file exists"
else
echo "✗ $file NOT FOUND"
fi
done
echo ""
echo "=== Comparing top-level keys across all files ==="
echo "EN keys:"
jq -r 'keys[] | sort' apps/frontend/src/shared/i18n/locales/en/taskReview.json 2>/dev/null | sort > /tmp/en_keys.txt && cat /tmp/en_keys.txt || echo "Error reading EN file"
echo ""
echo "FR keys:"
jq -r 'keys[] | sort' apps/frontend/src/shared/i18n/locales/fr/taskReview.json 2>/dev/null | sort > /tmp/fr_keys.txt && cat /tmp/fr_keys.txt || echo "Error reading FR file"
echo ""
echo "HE keys:"
jq -r 'keys[] | sort' apps/frontend/src/shared/i18n/locales/he/taskReview.json 2>/dev/null | sort > /tmp/he_keys.txt && cat /tmp/he_keys.txt || echo "Error reading HE file"
echo ""
echo "=== Checking key consistency ==="
if diff /tmp/en_keys.txt /tmp/fr_keys.txt > /dev/null 2>&1; then
echo "✓ EN and FR have identical top-level keys"
else
echo "✗ EN and FR have different top-level keys:"
echo "In EN but not FR:"
comm -23 /tmp/en_keys.txt /tmp/fr_keys.txt
echo "In FR but not EN:"
comm -13 /tmp/en_keys.txt /tmp/fr_keys.txt
fi
if diff /tmp/en_keys.txt /tmp/he_keys.txt > /dev/null 2>&1; then
echo "✓ EN and HE have identical top-level keys"
else
echo "✗ EN and HE have different top-level keys:"
echo "In EN but not HE:"
comm -23 /tmp/en_keys.txt /tmp/he_keys.txt
echo "In HE but not EN:"
comm -13 /tmp/en_keys.txt /tmp/he_keys.txt
fi
if diff /tmp/fr_keys.txt /tmp/he_keys.txt > /dev/null 2>&1; then
echo "✓ FR and HE have identical top-level keys"
else
echo "✗ FR and HE have different top-level keys"
fiRepository: AndyMik90/Auto-Claude
Length of output: 563
🏁 Script executed:
#!/bin/bash
# Inspect actual file contents to diagnose the issue
echo "=== EN taskReview.json (first 20 lines) ==="
head -20 apps/frontend/src/shared/i18n/locales/en/taskReview.json
echo ""
echo "=== FR taskReview.json (first 20 lines) ==="
head -20 apps/frontend/src/shared/i18n/locales/fr/taskReview.json
echo ""
echo "=== HE taskReview.json (first 20 lines) ==="
head -20 apps/frontend/src/shared/i18n/locales/he/taskReview.json
echo ""
echo "=== Verify JSON validity and count keys ==="
for file in en fr he; do
echo ""
echo "$file/taskReview.json:"
jq '.' "apps/frontend/src/shared/i18n/locales/$file/taskReview.json" > /dev/null 2>&1 && echo "✓ Valid JSON" || echo "✗ Invalid JSON"
jq 'keys | length' "apps/frontend/src/shared/i18n/locales/$file/taskReview.json" 2>/dev/null || echo "Error reading keys"
jq 'keys[]' "apps/frontend/src/shared/i18n/locales/$file/taskReview.json" 2>/dev/null || echo "Error listing keys"
doneRepository: AndyMik90/Auto-Claude
Length of output: 1617
🏁 Script executed:
#!/bin/bash
# Get complete file contents
echo "=== Complete EN taskReview.json ==="
cat apps/frontend/src/shared/i18n/locales/en/taskReview.json
echo ""
echo "=== Complete FR taskReview.json ==="
cat apps/frontend/src/shared/i18n/locales/fr/taskReview.json
echo ""
echo "=== Complete HE taskReview.json ==="
cat apps/frontend/src/shared/i18n/locales/he/taskReview.jsonRepository: AndyMik90/Auto-Claude
Length of output: 2168
Add missing translation keys to EN and FR files.
The Hebrew file contains translation sections (actions, subtasks, warnings, dialogs) that do not exist in en/taskReview.json or fr/taskReview.json. Additionally, en/taskReview.json contains a diffDialog section not present in the Hebrew or French files. Per the coding guidelines, all language files must contain the same translation keys (minimum: en/*.json and fr/*.json). Ensure all five sections (terminal, diffDialog, actions, subtasks, warnings, dialogs) are present with matching key structures across all three files.
| { | ||
| "status": { | ||
| "backlog": "תכנון", | ||
| "in_progress": "בתהליך", | ||
| "ai_review": "בדיקת AI", | ||
| "human_review": "בדיקת משתמש", | ||
| "done": "הושלם", | ||
| "archived": "בארכיון" | ||
| }, | ||
| "actions": { | ||
| "start": "התחל", | ||
| "stop": "עצור", | ||
| "recover": "שחזר", | ||
| "resume": "המשך", | ||
| "archive": "העבר לארכיון", | ||
| "delete": "מחק", | ||
| "view": "צפה בפרטים" | ||
| }, | ||
| "labels": { | ||
| "running": "רץ", | ||
| "aiReview": "בדיקת AI", | ||
| "needsReview": "דורש בדיקה", | ||
| "pending": "ממתין", | ||
| "stuck": "תקוע", | ||
| "incomplete": "לא הושלם", | ||
| "recovering": "משחזר...", | ||
| "needsRecovery": "דורש שחזור", | ||
| "needsResume": "דורש המשך", | ||
| "title": "כותרת", | ||
| "description": "תיאור", | ||
| "category": "קטגוריה", | ||
| "priority": "עדיפות", | ||
| "complexity": "מורכבות", | ||
| "impact": "השפעה", | ||
| "classification": "סיווג", | ||
| "imageAdded": "תמונה נוספה בהצלחה!", | ||
| "referenceImages": "תמונות התייחסות (אופציונלי)", | ||
| "optional": "אופציונלי" | ||
| }, | ||
| "reviewReason": { | ||
| "completed": "הושלם", | ||
| "hasErrors": "יש שגיאות", | ||
| "qaIssues": "בעיות QA", | ||
| "approvePlan": "אשר תוכנית" | ||
| }, | ||
| "tooltips": { | ||
| "archiveTask": "העבר משימה לארכיון", | ||
| "archiveAllDone": "העבר את כל המשימות שהושלמו לארכיון" | ||
| }, | ||
| "creation": { | ||
| "title": "צור משימה חדשה", | ||
| "description": "תאר מה ברצונך לבנות. הבינה המלאכותית תנתח את הבקשה שלך ותיצור מפרט מפורט.", | ||
| "placeholder": "תאר את המשימה שלך...", | ||
| "draftRestored": "טיוטה שוחזרה", | ||
| "startFresh": "התחל מחדש", | ||
| "advanced": "אפשרויות מתקדמות", | ||
| "modelConfig": "תצורת מודל", | ||
| "gitOptions": "אפשרויות Git", | ||
| "requireReview": "דרוש סקירה אנושית לפני קידוד", | ||
| "requireReviewHint": "כאשר מופעל, תתבקש לסקור את המפרט ותוכנית היישום לפני ששלב הקידוד מתחיל. זה מאפשר לך לאשר, לבקש שינויים או לספק משוב.", | ||
| "createButton": "צור משימה", | ||
| "creating": "יוצר...", | ||
| "descriptionRequired": "נא לספק תיאור", | ||
| "gitOptionsOptional": "אפשרויות Git (אופציונלי)", | ||
| "baseBranch": "ערוץ בסיס (אופציונלי)", | ||
| "baseBranchPlaceholder": "השתמש בברירת מחדל של הפרויקט", | ||
| "baseBranchHint": "עקוף על הערוץ ממנו ייוצר עץ העבודה של משימה זו. השאר ריק כדי להשתמש בערוץ ברירת המחדל המוגדר של הפרויקט.", | ||
| "browseFiles": "עיון בקבצים", | ||
| "hideFiles": "הסתר קבצים" | ||
| }, | ||
| "empty": { | ||
| "title": "אין משימות עדיין", | ||
| "description": "צור את המשימה הראשונה שלך כדי להתחיל" | ||
| }, | ||
| "kanban": { | ||
| "emptyBacklog": "אין משימות מתוכננות", | ||
| "emptyBacklogHint": "הוסף משימה כדי להתחיל", | ||
| "emptyInProgress": "אין משימות רצות", | ||
| "emptyInProgressHint": "התחל משימה מרשימת המשימות", | ||
| "emptyAiReview": "אין משימות בבדיקה", | ||
| "emptyAiReviewHint": "AI יבדוק משימות שהושלמו", | ||
| "emptyHumanReview": "אין משימות לבדיקה", | ||
| "emptyHumanReviewHint": "משימות ממתינות לאישורך כאן", | ||
| "emptyDone": "אין משימות שהושלמו", | ||
| "emptyDoneHint": "משימות מאושרות מופיעות כאן", | ||
| "emptyDefault": "אין משימות", | ||
| "dropHere": "שחרר כאן", | ||
| "showArchived": "הצג משימות בארכיון" | ||
| }, | ||
| "execution": { | ||
| "phases": { | ||
| "idle": "לא פעיל", | ||
| "planning": "תכנון", | ||
| "coding": "קידוד", | ||
| "reviewing": "בודק", | ||
| "fixing": "מתקן", | ||
| "complete": "הושלם", | ||
| "failed": "נכשל" | ||
| }, | ||
| "labels": { | ||
| "interrupted": "הופרע", | ||
| "progress": "התקדמות", | ||
| "entry": "ערך", | ||
| "entries": "ערכים" | ||
| }, | ||
| "shortPhases": { | ||
| "plan": "תכנון", | ||
| "code": "קוד", | ||
| "qa": "בדיקה" | ||
| } | ||
| }, | ||
| "form": { | ||
| "descriptionPlaceholder": "תאר את התכונה, תיקון הבאג או השיפור שברצונך ליישם. היה מפורט כמה שאפשר לגבי דרישות, אילוצים והתנהגות צפויה. הקלד @ להפנות לקבצים.", | ||
| "descriptionLabel": "תיאור *", | ||
| "filesAndImagesHint": "קבצים ותמונות ניתנים להדבקה או לגרירה ושחרור אל תוך התיאור.", | ||
| "titleLabel": "כותרת (אופציונלי)", | ||
| "titleAutoGenerateHint": "כותרת קצרה ותיאורית תיווצר אוטומטית אם תישאר ריקה.", | ||
| "titlePlaceholder": "השאר ריק ליצירה אוטומטית מהתיאור", | ||
| "pasteImagesTip": "טיפ: הדבק צילומי מסך ישירות עם {{shortcut}} כדי להוסיף תמונות התייחסות.", | ||
| "classificationHint": "תוויות אלו עוזרות לארגן ולתעדף משימות. הן אופציונליות אך שימושיות לסינון.", | ||
| "imagesHint": "צרף צילומי מסך, דוגמאות או דיאגרמות כדי לספק הקשר חזותי ל-AI.", | ||
| "commitMessagePlaceholder": "הודעת commit...", | ||
| "feedbackPlaceholder": "תאר את הבעיות או השינויים הנדרשים...", | ||
| "selectCategory": "בחר קטגוריה", | ||
| "selectPriority": "בחר עדיפות", | ||
| "selectComplexity": "בחר מורכבות", | ||
| "selectImpact": "בחר השפעה" | ||
| }, | ||
| "errors": { | ||
| "failedToDelete": "מחיקת המשימה נכשלה", | ||
| "failedToUpdate": "עדכון המשימה נכשל. אנא נסה שוב.", | ||
| "failedToMerge": "מיזוג השינויים נכשל", | ||
| "failedToDiscard": "התעלמות מהשינויים נכשלה", | ||
| "failedToLoad": "הטעינה נכשלה", | ||
| "maxImagesReached": "מקסימום {{max}} תמונות מותר", | ||
| "invalidImageType": "סוג תמונה לא תקין. מותר: {{allowed}}", | ||
| "imageProcessFailed": "עיבוד התמונה נכשל", | ||
| "descriptionRequired": "תיאור הוא שדה חובה", | ||
| "updateFailed": "עדכון המשימה נכשל. אנא נסה שוב.", | ||
| "filesSkipped": "ניתן להוסיף רק {{count}} תמונה/ות נוספות. חלק מהקבצים דולגו.", | ||
| "invalidFileType": "\"{{fileName}}\" אינו סוג תמונה תקין. מותר: {{allowed}}", | ||
| "fileTooLarge": "\"{{fileName}}\" גדול מ-10MB. שקול לדחוס אותו לביצועים טובים יותר.", | ||
| "fileProcessFailed": "עיבוד \"{{fileName}}\" נכשל", | ||
| "createFailed": "יצירת המשימה נכשלה. אנא נסה שוב." | ||
| }, | ||
| "imageUpload": { | ||
| "dropOrBrowse": "גרור תמונות לכאן או לחץ לעיון", | ||
| "maxReached": "הגעת למספר התמונות המקסימלי", | ||
| "allowedTypes": "{{types}} עד 10MB לכל תמונה ({{current}}/{{max}})", | ||
| "maxMessage": "מקסימום {{max}} תמונות", | ||
| "largeFileWarning": "קובץ גדול - שקול דחיסה" | ||
| }, | ||
| "editDialog": { | ||
| "title": "ערוך משימה", | ||
| "description": "עדכן פרטי משימה כולל כותרת, תיאור, סיווג, תמונות והגדרות. השינויים יישמרו בקבצי המפרט." | ||
| }, | ||
| "tabs": { | ||
| "overview": "סקירה", | ||
| "subtasks": "תתי-משימות", | ||
| "logs": "יומנים" | ||
| }, | ||
| "metadata": { | ||
| "created": "נוצר", | ||
| "updated": "עודכן", | ||
| "source": "מקור" | ||
| }, | ||
| "buttons": { | ||
| "startTask": "התחל משימה", | ||
| "stopTask": "עצור משימה", | ||
| "deleteTask": "מחק משימה", | ||
| "close": "סגור", | ||
| "recoverTask": "שחזר משימה", | ||
| "resumeTask": "המשך משימה", | ||
| "recovering": "משחזר..." | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify that tasks.json exists in en and fr locales with matching key structure
echo "=== Checking for tasks.json in required locales ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/${locale}/tasks.json"
if [ -f "$file" ]; then
echo "✓ Found: $file"
# Count top-level keys
keys=$(jq 'keys | length' "$file" 2>/dev/null || echo "0")
echo " Top-level keys: $keys"
else
echo "✗ Missing: $file"
fi
done
echo ""
echo "=== Comparing key structure between locales ==="
# Extract all keys (nested) from each locale and count them
for locale in he en fr; do
file="apps/frontend/src/shared/i18n/locales/${locale}/tasks.json"
if [ -f "$file" ]; then
total_keys=$(jq -r 'paths(scalars) | join(".")' "$file" 2>/dev/null | wc -l)
echo "$locale: $total_keys total keys"
fi
done
echo ""
echo "=== Checking for key mismatches ==="
# Get all keys from he, en, fr and compare
he_keys=$(jq -r 'paths(scalars) | join(".")' "apps/frontend/src/shared/i18n/locales/he/tasks.json" 2>/dev/null | sort)
en_keys=$(jq -r 'paths(scalars) | join(".")' "apps/frontend/src/shared/i18n/locales/en/tasks.json" 2>/dev/null | sort)
fr_keys=$(jq -r 'paths(scalars) | join(".")' "apps/frontend/src/shared/i18n/locales/fr/tasks.json" 2>/dev/null | sort)
# Check if en has all he keys
echo "Keys in HE but NOT in EN:"
comm -23 <(echo "$he_keys") <(echo "$en_keys") | head -10
echo ""
echo "Keys in EN but NOT in HE:"
comm -13 <(echo "$he_keys") <(echo "$en_keys") | head -10
echo ""
echo "Keys in HE but NOT in FR:"
comm -23 <(echo "$he_keys") <(echo "$fr_keys") | head -10
echo ""
echo "Keys in FR but NOT in HE:"
comm -13 <(echo "$he_keys") <(echo "$fr_keys") | head -10Repository: AndyMik90/Auto-Claude
Length of output: 803
🏁 Script executed:
#!/bin/bash
# Extract keys more reliably using Python for comparison
python3 << 'EOF'
import json
import sys
def load_json(path):
try:
with open(path, 'r', encoding='utf-8') as f:
return json.load(f)
except:
return None
def get_all_keys(obj, prefix=''):
"""Recursively extract all nested keys"""
keys = set()
if isinstance(obj, dict):
for k, v in obj.items():
full_key = f"{prefix}.{k}" if prefix else k
keys.add(full_key)
if isinstance(v, dict):
keys.update(get_all_keys(v, full_key))
return keys
# Load all locale files
locales = {
'he': 'apps/frontend/src/shared/i18n/locales/he/tasks.json',
'en': 'apps/frontend/src/shared/i18n/locales/en/tasks.json',
'fr': 'apps/frontend/src/shared/i18n/locales/fr/tasks.json'
}
data = {}
for locale, path in locales.items():
data[locale] = load_json(path)
if data[locale] is None:
print(f"✗ Failed to load {path}")
sys.exit(1)
# Get all keys for each locale
keys = {}
for locale, obj in data.items():
keys[locale] = get_all_keys(obj)
print(f"{locale}: {len(keys[locale])} keys")
print("\n=== Key Comparison ===")
# Check HE keys in EN
missing_in_en = keys['he'] - keys['en']
if missing_in_en:
print(f"\n❌ Keys in HE but missing in EN ({len(missing_in_en)}):")
for key in sorted(missing_in_en):
print(f" - {key}")
else:
print("\n✓ All HE keys exist in EN")
# Check HE keys in FR
missing_in_fr = keys['he'] - keys['fr']
if missing_in_fr:
print(f"\n❌ Keys in HE but missing in FR ({len(missing_in_fr)}):")
for key in sorted(missing_in_fr):
print(f" - {key}")
else:
print("\n✓ All HE keys exist in FR")
# Check EN/FR keys not in HE
extra_in_en = keys['en'] - keys['he']
if extra_in_en:
print(f"\n⚠ Keys in EN but not in HE ({len(extra_in_en)}):")
for key in sorted(extra_in_en)[:5]:
print(f" - {key}")
if len(extra_in_en) > 5:
print(f" ... and {len(extra_in_en) - 5} more")
EOFRepository: AndyMik90/Auto-Claude
Length of output: 151
🏁 Script executed:
#!/bin/bash
# Compare top-level keys between locales
echo "=== Top-level Keys in Each Locale ==="
echo ""
echo "HE keys:"
jq 'keys' apps/frontend/src/shared/i18n/locales/he/tasks.json
echo ""
echo "EN keys:"
jq 'keys' apps/frontend/src/shared/i18n/locales/en/tasks.json
echo ""
echo "FR keys:"
jq 'keys' apps/frontend/src/shared/i18n/locales/fr/tasks.json
echo ""
echo "=== Checking Missing Top-level Keys ==="
echo ""
# Extract top-level keys as strings
he_keys=$(jq -r 'keys[]' apps/frontend/src/shared/i18n/locales/he/tasks.json | sort)
en_keys=$(jq -r 'keys[]' apps/frontend/src/shared/i18n/locales/en/tasks.json | sort)
fr_keys=$(jq -r 'keys[]' apps/frontend/src/shared/i18n/locales/fr/tasks.json | sort)
echo "Keys in HE but not in EN:"
grep -vFf <(echo "$en_keys") <(echo "$he_keys") || echo " (none)"
echo ""
echo "Keys in HE but not in FR:"
grep -vFf <(echo "$fr_keys") <(echo "$he_keys") || echo " (none)"Repository: AndyMik90/Auto-Claude
Length of output: 852
🏁 Script executed:
#!/bin/bash
# Quick check if EN has buttons, imageUpload, metadata, tabs sections
echo "=== Checking for missing top-level keys ==="
echo ""
missing_keys=("buttons" "imageUpload" "metadata" "tabs")
for key in "${missing_keys[@]}"; do
echo "Key: $key"
en_has=$(jq "has(\"$key\")" apps/frontend/src/shared/i18n/locales/en/tasks.json)
fr_has=$(jq "has(\"$key\")" apps/frontend/src/shared/i18n/locales/fr/tasks.json)
echo " EN: $en_has"
echo " FR: $fr_has"
done
echo ""
echo "=== Sample nested key check: buttons.startTask ==="
en_button=$(jq '.buttons.startTask // "NOT FOUND"' apps/frontend/src/shared/i18n/locales/en/tasks.json)
he_button=$(jq '.buttons.startTask // "NOT FOUND"' apps/frontend/src/shared/i18n/locales/he/tasks.json)
echo "EN: $en_button"
echo "HE: $he_button"Repository: AndyMik90/Auto-Claude
Length of output: 344
Add missing translation keys to en/tasks.json and fr/tasks.json.
This Hebrew translation file introduces four new top-level sections that are missing from the required locales:
buttons(contains: startTask, stopTask, deleteTask, close, recoverTask, resumeTask, recovering)imageUpload(contains: dropOrBrowse, maxReached, allowedTypes, maxMessage, largeFileWarning)metadata(contains: created, updated, source)tabs(contains: overview, subtasks, logs)
Per coding guidelines, all translation keys must be added to minimum en/tasks.json and fr/tasks.json before merging.
| { | ||
| "title": "עצי עבודה", | ||
| "description": "נהל עצי עבודה של git לביצוע מקבילי של משימות", | ||
| "selectProject": "בחר פרויקט כדי לצפות בעצי עבודה", | ||
| "refresh": "רענן", | ||
| "error": "שגיאה", | ||
| "empty": "אין עצי עבודה", | ||
| "emptyDescription": "עצי עבודה של Git מאפשרים לך לעבוד על מספר ענפים בו-זמנית. צור עצי עבודה למשימות שלך כדי לאפשר פיתוח מקבילי.", | ||
| "filesChanged": "קבצים שונו", | ||
| "commitsAhead": "קומיטים קדימה", | ||
| "mergeTo": "מזג אל", | ||
| "copyPath": "העתק נתיב", | ||
| "delete": "מחק", | ||
| "merge": "מזג עץ עבודה", | ||
| "mergeDescription": "מזג עץ עבודה זה חזרה לענף הבסיס שלו", | ||
| "sourceBranch": "ענף מקור", | ||
| "targetBranch": "ענף יעד", | ||
| "changes": "שינויים", | ||
| "commits": "קומיטים", | ||
| "files": "קבצים", | ||
| "mergeSuccessful": "המיזוג הצליח", | ||
| "mergeFailed": "המיזוג נכשל", | ||
| "conflictingFiles": "קבצים מתנגשים", | ||
| "close": "סגור", | ||
| "cancel": "ביטול", | ||
| "merging": "ממזג...", | ||
| "mergeButton": "מזג", | ||
| "deleteTitle": "מחק עץ עבודה", | ||
| "deleteDescription": "האם אתה בטוח שברצונך למחוק עץ עבודה זה?", | ||
| "cannotUndo": "לא ניתן לבטל פעולה זו. תיקיית עץ העבודה וכל השינויים שלא נשמרו יימחקו לצמיתות.", | ||
| "deleting": "מוחק..." | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if files exist and compare keys
echo "=== Checking file existence ==="
EN_FILE="apps/frontend/src/shared/i18n/locales/en/worktrees.json"
FR_FILE="apps/frontend/src/shared/i18n/locales/fr/worktrees.json"
HE_FILE="apps/frontend/src/shared/i18n/locales/he/worktrees.json"
for file in "$EN_FILE" "$FR_FILE" "$HE_FILE"; do
if [ -f "$file" ]; then
echo "✓ $file exists"
else
echo "✗ $file MISSING"
fi
done
echo -e "\n=== Key counts ==="
echo "Hebrew keys:"
HE_COUNT=$(cat "$HE_FILE" 2>/dev/null | jq 'keys | length' 2>/dev/null || echo "N/A")
echo "$HE_COUNT"
echo "English keys:"
EN_COUNT=$(cat "$EN_FILE" 2>/dev/null | jq 'keys | length' 2>/dev/null || echo "N/A")
echo "$EN_COUNT"
echo "French keys:"
FR_COUNT=$(cat "$FR_FILE" 2>/dev/null | jq 'keys | length' 2>/dev/null || echo "N/A")
echo "$FR_COUNT"
echo -e "\n=== Key comparison ==="
echo "Keys in Hebrew but not in English:"
jq -r 'keys[]' "$HE_FILE" 2>/dev/null | sort > /tmp/he_keys.txt
jq -r 'keys[]' "$EN_FILE" 2>/dev/null | sort > /tmp/en_keys.txt
comm -23 /tmp/he_keys.txt /tmp/en_keys.txt | wc -l
echo "Keys in Hebrew but not in French:"
jq -r 'keys[]' "$FR_FILE" 2>/dev/null | sort > /tmp/fr_keys.txt
comm -23 /tmp/he_keys.txt /tmp/fr_keys.txt | wc -l
echo "Keys in English but not in Hebrew:"
comm -13 /tmp/he_keys.txt /tmp/en_keys.txt | wc -l
echo "Keys in French but not in Hebrew:"
comm -13 /tmp/he_keys.txt /tmp/fr_keys.txt | wc -l
echo -e "\n=== All keys match across all three files? ==="
if diff <(jq -r 'keys[]' "$HE_FILE" 2>/dev/null | sort) <(jq -r 'keys[]' "$EN_FILE" 2>/dev/null | sort) > /dev/null && \
diff <(jq -r 'keys[]' "$HE_FILE" 2>/dev/null | sort) <(jq -r 'keys[]' "$FR_FILE" 2>/dev/null | sort) > /dev/null; then
echo "✓ YES - All keys match"
else
echo "✗ NO - Keys differ. Details:"
echo "Differing keys between HE and EN:"
diff <(jq -r 'keys[]' "$HE_FILE" 2>/dev/null | sort) <(jq -r 'keys[]' "$EN_FILE" 2>/dev/null | sort)
echo -e "\nDiffering keys between HE and FR:"
diff <(jq -r 'keys[]' "$HE_FILE" 2>/dev/null | sort) <(jq -r 'keys[]' "$FR_FILE" 2>/dev/null | sort)
fiRepository: AndyMik90/Auto-Claude
Length of output: 957
Create the missing French translation file apps/frontend/src/shared/i18n/locales/fr/worktrees.json.
The French translation file is missing entirely. The English and Hebrew worktrees translation files both contain 30 keys and are synchronized, but the French file must be created to comply with the project's coding guidelines requiring translation keys in all language files (minimum: en/*.json and fr/*.json). Create apps/frontend/src/shared/i18n/locales/fr/worktrees.json with French translations for all 30 keys.
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/fr/worktrees.json (create file,
corresponds to Hebrew file lines 1-32), the French locale is missing; add a new
JSON file containing the same 30 keys as the he/worktrees.json and provide
French translations for each key (title, description, selectProject, refresh,
error, empty, emptyDescription, filesChanged, commitsAhead, mergeTo, copyPath,
delete, merge, mergeDescription, sourceBranch, targetBranch, changes, commits,
files, mergeSuccessful, mergeFailed, conflictingFiles, close, cancel, merging,
mergeButton, deleteTitle, deleteDescription, cannotUndo, deleting). Ensure valid
JSON syntax, proper UTF-8 encoding, and that keys and pluralization match the
other locale files exactly.
| # 🚀 תוכנית שיפורים לצ'אט התבונות (Insights Chat) | ||
|
|
||
| ## 📋 סטטוס: בתהליך | ||
| תאריך יצירה: 30 דצמבר 2025 | ||
|
|
||
| --- | ||
|
|
||
| ## 🎯 שלב 1: שיפורי UI/UX בסיסיים (עדיפות גבוהה) | ||
|
|
||
| ### ✅ הושלם | ||
| - [x] הוספת רכיב MarkdownContent עם תמיכה בקוד ולינקים לקבצים | ||
| - [x] הוספת handler לפתיחת קבצים ב-VS Code | ||
|
|
||
| ### 🔨 בתהליך | ||
| - [ ] **Syntax Highlighting מתקדם** | ||
| - [ ] התקנת Prism.js או Shiki | ||
| - [ ] הוספת תמיכה בכל השפות הנפוצות | ||
| - [ ] עיצוב תואם לנושא הכהה/בהיר | ||
|
|
||
| - [ ] **Copy Button לקוד** | ||
| - [ ] כפתור העתקה בפינה של כל בלוק קוד | ||
| - [ ] הודעת הצלחה כשמעתיקים | ||
| - [ ] תמיכה בקיצורי מקלדת (Ctrl+C) | ||
|
|
||
| - [ ] **Line Numbers** | ||
| - [ ] מספור שורות בבלוקי קוד | ||
| - [ ] אפשרות להדגיש שורות ספציפיות | ||
| - [ ] תמיכה בלינק לשורה ספציפית | ||
|
|
||
| --- | ||
|
|
||
| ## 🎨 שלב 2: שיפורי חווית משתמש (עדיפות בינונית-גבוהה) | ||
|
|
||
| - [ ] **Collapsible Code Blocks** | ||
| - [ ] קיפול אוטומטי של בלוקים ארוכים (>20 שורות) | ||
| - [ ] כפתור Expand/Collapse | ||
| - [ ] שמירת מצב קיפול בין רענונים | ||
|
|
||
| - [ ] **Multi-file Context View** | ||
| - [ ] פאנל צדדי עם רשימת קבצים שנקראו | ||
| - [ ] אינדיקטור כמות קבצים לכל הודעה | ||
| - [ ] לחיצה על קובץ פותחת אותו | ||
| - [ ] הצגת סטטיסטיקות: כמה שורות נקראו, גודל | ||
|
|
||
| - [ ] **Code Diff View** | ||
| - [ ] הצגת שינויים מוצעים בפורמט diff | ||
| - [ ] תמיכה ב-side-by-side או unified view | ||
| - [ ] כפתור "Apply Changes" | ||
|
|
||
| - [ ] **Quick Actions Menu** | ||
| - [ ] Create Task מהמלצות | ||
| - [ ] Open File | ||
| - [ ] Copy to Clipboard | ||
| - [ ] Run Code (אם רלוונטי) | ||
|
|
||
| --- | ||
|
|
||
| ## 📊 שלב 3: Context & Analytics (עדיפות בינונית) | ||
|
|
||
| - [ ] **Token Counter** | ||
| - [ ] ספירה בזמן אמת של tokens בשיחה | ||
| - [ ] התראה כשמתקרבים לגבול | ||
| - [ ] הצגה ויזואלית (progress bar) | ||
|
|
||
| - [ ] **Cost Estimator** | ||
| - [ ] חישוב עלות משוערת לפי מודל | ||
| - [ ] הצגת עלות כוללת לסשן | ||
| - [ ] השוואה בין מודלים | ||
|
|
||
| - [ ] **File Dependency Graph** | ||
| - [ ] גרף ויזואלי של קבצים שנקראו | ||
| - [ ] קשרים בין קבצים | ||
| - [ ] זום והזזה בגרף | ||
|
|
||
| - [ ] **Conversation Bookmarks** | ||
| - [ ] סימניות להודעות חשובות | ||
| - [ ] ניווט מהיר בין סימניות | ||
| - [ ] תיוגים וצבעים | ||
|
|
||
| --- | ||
|
|
||
| ## 🔍 שלב 4: חיפוש וניווט (עדיפות בינונית-נמוכה) | ||
|
|
||
| - [ ] **Search in Conversation** | ||
| - [ ] חיפוש טקסט בשיחה הנוכחית | ||
| - [ ] Highlight תוצאות | ||
| - [ ] ניווט בין תוצאות | ||
|
|
||
| - [ ] **Jump to Tool Usage** | ||
| - [ ] רשימת כל הכלים שהופעלו | ||
| - [ ] קפיצה מהירה לשימוש ספציפי | ||
| - [ ] סינון לפי סוג כלי | ||
|
|
||
| - [ ] **Session Timeline** | ||
| - [ ] ציר זמן ויזואלי של השיחה | ||
| - [ ] נקודות ציון חשובות | ||
| - [ ] זום אין/אאוט | ||
|
|
||
| --- | ||
|
|
||
| ## 🚀 שלב 5: פיצ'רים מתקדמים (עדיפות נמוכה) | ||
|
|
||
| - [ ] **Interactive Code Execution** | ||
| - [ ] הרצת Python בסנדבוקס | ||
| - [ ] הצגת פלט ישירות בצ'אט | ||
| - [ ] תמיכה בגרפים וויזואליזציות | ||
|
|
||
| - [ ] **Voice Input** | ||
| - [ ] הקלטת שאילתות בקול | ||
| - [ ] תמיכה בעברית ואנגלית | ||
| - [ ] המרה לטקסט אוטומטית | ||
|
|
||
| - [ ] **Image Upload** | ||
| - [ ] העלאת screenshots | ||
| - [ ] העלאת תרשימים | ||
| - [ ] OCR אוטומטי | ||
|
|
||
| - [ ] **Follow-up Suggestions** | ||
| - [ ] הצעות אוטומטיות להמשך שיחה | ||
| - [ ] ML-based suggestions | ||
| - [ ] התאמה אישית | ||
|
|
||
| --- | ||
|
|
||
| ## 💾 שלב 6: Export & Share (עדיפות נמוכה) | ||
|
|
||
| - [ ] **Export to Markdown** | ||
| - [ ] ייצוא השיחה המלאה | ||
| - [ ] שמירת קוד וקבצים מקושרים | ||
| - [ ] HTML אלטרנטיבי | ||
|
|
||
| - [ ] **Share Conversation** | ||
| - [ ] יצירת קישור לשיתוף | ||
| - [ ] הגנת פרטיות | ||
| - [ ] תאריך תפוגה | ||
|
|
||
| - [ ] **Generate Summary** | ||
| - [ ] סיכום אוטומטי של השיחה | ||
| - [ ] נקודות עיקריות | ||
| - [ ] action items | ||
|
|
||
| - [ ] **Code Snippets Library** | ||
| - [ ] שמירת קטעי קוד שימושיים | ||
| - [ ] תיוג וקטגוריות | ||
| - [ ] חיפוש בספרייה | ||
|
|
||
| --- | ||
|
|
||
| ## 📝 הערות טכניות | ||
|
|
||
| ### תלויות חדשות נדרשות: | ||
| - `prismjs` או `shiki` - Syntax highlighting | ||
| - `react-diff-view` - Diff viewer | ||
| - `react-markdown` - Markdown parsing משופר | ||
| - `d3` או `vis.js` - File dependency graph | ||
| - `clipboard-polyfill` - Copy to clipboard | ||
|
|
||
| ### שיקולי ביצועים: | ||
| - Virtualization לשיחות ארוכות | ||
| - Lazy loading של הדגשת תחביר | ||
| - Debouncing בחיפוש | ||
| - Caching של גרפים | ||
|
|
||
| ### נגישות: | ||
| - תמיכה במקלדת מלאה | ||
| - Screen reader support | ||
| - High contrast mode | ||
| - כיוון RTL לעברית | ||
|
|
||
| --- | ||
|
|
||
| ## 🎯 המשימה הבאה | ||
| **נתחיל עם: Syntax Highlighting + Copy Button** | ||
|
|
||
| סיבות: | ||
| 1. השיפור הכי נראה לעין | ||
| 2. חיוני לחווית משתמש טובה | ||
| 3. יחסית קל ליישום | ||
| 4. בסיס לשיפורים נוספים | ||
|
|
||
| --- | ||
|
|
||
| ## 📊 מטריקות הצלחה | ||
|
|
||
| - [ ] זמן טעינה < 100ms להדגשת קוד | ||
| - [ ] 0 באגים בפרודקשן | ||
| - [ ] 95%+ satisfaction score מהמשתמשים | ||
| - [ ] תמיכה ב-20+ שפות תכנות | ||
| - [ ] Accessibility score 100/100 | ||
|
|
||
| --- | ||
|
|
||
| **עודכן לאחרונה:** 30 דצמבר 2025 | ||
| **סטטוס כללי:** 2/50 משימות הושלמו (4%) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider adding blank lines around headings for markdown consistency.
The static analysis tool flagged several instances where headings lack surrounding blank lines (lines 3, 10, 14, 151, 158, 164, 172). While this doesn't affect functionality, adding blank lines improves markdown rendering consistency across different parsers.
Example fix for heading spacing
## 📋 סטטוס: בתהליך
תאריך יצירה: 30 דצמבר 2025
+
---Apply similar spacing after other headings flagged by the linter.
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
3-3: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
10-10: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
14-14: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
151-151: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
158-158: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
164-164: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
172-172: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
173-173: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
🤖 Prompt for AI Agents
INSIGHTS_IMPROVEMENTS.md lines 1-194: several Markdown headings (notably at/near
lines 3, 10, 14, 151, 158, 164, 172) lack blank lines around them; update the
file to insert a single blank line before and after each affected heading so
headings are separated from surrounding paragraphs/lists (ensure consistent
spacing across the document and re-run the linter to verify all flagged headings
are fixed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review continued from previous batch...
| ipcMain.handle( | ||
| 'open-file', | ||
| async (_, params: { filePath: string; lineStart?: number; lineEnd?: number }): Promise<IPCResult<void>> => { | ||
| try { | ||
| const { filePath, lineStart, lineEnd } = params; | ||
|
|
||
| // Build VS Code URL with line numbers if provided | ||
| let url = `vscode://file/${filePath}`; | ||
| if (lineStart) { | ||
| url += `:${lineStart}`; | ||
| if (lineEnd && lineEnd !== lineStart) { | ||
| url += `:${lineEnd}`; | ||
| } | ||
| } | ||
|
|
||
| // Open the file in VS Code | ||
| await shell.openExternal(url); | ||
|
|
||
| return { success: true, data: undefined }; | ||
| } catch (error) { | ||
| return { | ||
| success: false, | ||
| error: error instanceof Error ? error.message : 'Failed to open file' | ||
| }; | ||
| } | ||
| } | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Use IPC channel constant instead of hardcoded string.
Line 69 uses the hardcoded string 'open-file' directly. This should be defined in IPC_CHANNELS (from apps/frontend/src/shared/constants/ipc.ts) and referenced here for consistency and maintainability.
🔎 Proposed fix
In apps/frontend/src/shared/constants/ipc.ts, add:
export const IPC_CHANNELS = {
// ... existing channels
+ FILE_OPEN: 'open-file',
} as const;Then in this file:
ipcMain.handle(
- 'open-file',
+ IPC_CHANNELS.FILE_OPEN,
async (_, params: { filePath: string; lineStart?: number; lineEnd?: number }): Promise<IPCResult<void>> => {Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/frontend/src/main/ipc-handlers/file-handlers.ts around lines 68 to 94,
replace the hardcoded IPC channel string 'open-file' with the constant from
apps/frontend/src/shared/constants/ipc.ts: import IPC_CHANNELS (or the default
export) at the top of the file and use the appropriate key (e.g.
IPC_CHANNELS.OPEN_FILE) in the ipcMain.handle call; update the import statements
and any affected linting imports but do not change runtime behavior.
| label: t(`agentProfile.profiles.${profile.id}.name`), | ||
| description: t(`agentProfile.profiles.${profile.id}.description`) | ||
| }; | ||
| } | ||
| // Default to auto profile (the actual default) | ||
| return { | ||
| icon: Sparkles, | ||
| label: 'Auto (Optimized)', | ||
| description: 'Uses Opus across all phases with optimized thinking levels' | ||
| label: t('agentProfile.profiles.auto.name'), | ||
| description: t('agentProfile.profiles.auto.description') | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify agentProfile translation keys exist for all profiles
echo "=== Checking agentProfile.profiles keys in English settings.json ==="
if [ -f "apps/frontend/src/shared/i18n/locales/en/settings.json" ]; then
rg -n '"profiles"' apps/frontend/src/shared/i18n/locales/en/settings.json -A 50 | head -80
else
echo "English settings.json not found"
fi
echo ""
echo "=== Checking if French settings.json has matching structure ==="
if [ -f "apps/frontend/src/shared/i18n/locales/fr/settings.json" ]; then
rg -n '"profiles"' apps/frontend/src/shared/i18n/locales/fr/settings.json -A 50 | head -80
else
echo "French settings.json not found"
fi
echo ""
echo "=== Checking all available locale files ==="
fd -e json apps/frontend/src/shared/i18n/locales/ -type fRepository: AndyMik90/Auto-Claude
Length of output: 2049
🏁 Script executed:
#!/bin/bash
echo "=== Listing all locale files ==="
find apps/frontend/src/shared/i18n/locales -name "*.json" -type f
echo ""
echo "=== Checking English settings.json structure ==="
if [ -f "apps/frontend/src/shared/i18n/locales/en/settings.json" ]; then
cat apps/frontend/src/shared/i18n/locales/en/settings.json | python3 -m json.tool | grep -A 20 '"profiles"'
else
echo "English settings.json not found"
fi
echo ""
echo "=== Checking French settings.json structure ==="
if [ -f "apps/frontend/src/shared/i18n/locales/fr/settings.json" ]; then
cat apps/frontend/src/shared/i18n/locales/fr/settings.json | python3 -m json.tool | grep -A 20 '"profiles"'
else
echo "French settings.json not found"
fi
echo ""
echo "=== Checking which profile IDs are used in AgentProfileSelector.tsx ==="
rg -n 'profile\.id|profiles\.' apps/frontend/src/renderer/components/AgentProfileSelector.tsx | head -20Repository: AndyMik90/Auto-Claude
Length of output: 151
🏁 Script executed:
#!/bin/bash
echo "=== Check if French settings.json exists ==="
ls -la apps/frontend/src/shared/i18n/locales/fr/settings.json 2>&1
echo ""
echo "=== Check French profiles section directly ==="
rg -n "profiles" apps/frontend/src/shared/i18n/locales/fr/settings.json --max-count=1 2>&1
echo ""
echo "=== View first 100 lines of French settings.json to see structure ==="
head -100 apps/frontend/src/shared/i18n/locales/fr/settings.json 2>&1 | tail -50Repository: AndyMik90/Auto-Claude
Length of output: 3335
🏁 Script executed:
#!/bin/bash
echo "=== Search for agentProfile in French settings.json ==="
rg -n "agentProfile" apps/frontend/src/shared/i18n/locales/fr/settings.json 2>&1
echo ""
echo "=== Search for agentProfile in English settings.json ==="
rg -n "agentProfile" apps/frontend/src/shared/i18n/locales/en/settings.json 2>&1
echo ""
echo "=== Check the line count of both files ==="
wc -l apps/frontend/src/shared/i18n/locales/en/settings.json apps/frontend/src/shared/i18n/locales/fr/settings.jsonRepository: AndyMik90/Auto-Claude
Length of output: 404
🏁 Script executed:
#!/bin/bash
echo "=== View agentProfile section in French settings.json (lines 169-200) ==="
sed -n '169,210p' apps/frontend/src/shared/i18n/locales/fr/settings.json
echo ""
echo "=== View agentProfile section in English settings.json (lines 213-260) ==="
sed -n '213,260p' apps/frontend/src/shared/i18n/locales/en/settings.jsonRepository: AndyMik90/Auto-Claude
Length of output: 4219
🏁 Script executed:
#!/bin/bash
echo "=== Check all locale files for agentProfile.profiles ==="
for file in $(find apps/frontend/src/shared/i18n/locales -name "settings.json" -type f); do
echo ""
echo "File: $file"
rg -c '"profiles"' "$file" 2>/dev/null || echo "profiles section: NOT FOUND"
done
echo ""
echo "=== Verify component uses settings namespace ==="
rg -n "useTranslation" apps/frontend/src/renderer/components/AgentProfileSelector.tsx | head -3Repository: AndyMik90/Auto-Claude
Length of output: 487
French translation file is missing the required profiles section.
The agentProfile.profiles translations are present in English (en/settings.json) and Hebrew (he/settings.json), but completely missing from French (fr/settings.json). The component uses dynamic keys like t(\agentProfile.profiles.${profile.id}.name`)` which will fail to resolve in the French locale.
Add the following to apps/frontend/src/shared/i18n/locales/fr/settings.json within the agentProfile object:
"profiles": {
"auto": {
"name": "[French translation for Auto (Optimized)]",
"description": "[French translation for Uses Opus across all phases...]"
},
"complex": {
"name": "[French translation for Complex Tasks]",
"description": "[French translation for For intricate, multi-step...]"
},
"balanced": {
"name": "[French translation for Balanced]",
"description": "[French translation for Good balance of speed...]"
},
"quick": {
"name": "[French translation for Quick Edits]",
"description": "[French translation for Fast iterations...]"
}
}🤖 Prompt for AI Agents
In apps/frontend/src/renderer/components/AgentProfileSelector.tsx around lines
151-160 the component uses dynamic i18n keys under agentProfile.profiles but the
French locale file is missing that profiles section; open
apps/frontend/src/shared/i18n/locales/fr/settings.json and add a profiles object
under agentProfile mirroring the keys used (auto, complex, balanced, quick) with
appropriate French "name" and "description" strings so
t(`agentProfile.profiles.${profile.id}.name`) and description resolve correctly
at runtime.
| "firstSpec": { | ||
| "title": "Create Your First Task", | ||
| "subtitle": "Describe what you want to build and let Auto Claude handle the rest", | ||
| "taskCreatorOpened": "Task Creator Opened", | ||
| "taskCreatorOpenedMessage": "Great! You can create your first task now or continue with the wizard. You can always create tasks later from the main dashboard.", | ||
| "tipsTitle": "Tips for Great Tasks", | ||
| "tips": { | ||
| "beDescriptive": { | ||
| "title": "Be Descriptive", | ||
| "description": "Clearly describe what you want to build. Include requirements, constraints, and expected behavior." | ||
| }, | ||
| "startSmall": { | ||
| "title": "Start Small", | ||
| "description": "Begin with a focused task like adding a feature or fixing a bug. Smaller tasks are easier to verify." | ||
| }, | ||
| "includeContext": { | ||
| "title": "Include Context", | ||
| "description": "Mention relevant files, APIs, or patterns. The more context you provide, the better the results." | ||
| }, | ||
| "letAiHelp": { | ||
| "title": "Let AI Help", | ||
| "description": "The AI can generate titles and classify tasks. Focus on describing what you want, not the details." | ||
| } | ||
| }, | ||
| "exampleTitle": "Example Task Description:", | ||
| "exampleDescription": "Add a dark mode toggle to the settings page. It should persist the user's preference in localStorage and apply the theme immediately without page reload. Use the existing color variables in styles/theme.css.", | ||
| "openTaskCreator": "Open Task Creator", | ||
| "continueMessage": "You can continue with the wizard now or create more tasks.", | ||
| "skipMessage": "You can skip this step and create tasks later from the dashboard.", | ||
| "back": "Back", | ||
| "skip": "Skip", | ||
| "continue": "Continue" | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if firstSpec keys exist in Hebrew and French onboarding files
echo "=== Checking Hebrew onboarding.json for firstSpec ==="
rg -A 5 '"firstSpec"' apps/frontend/src/shared/i18n/locales/he/onboarding.json 2>/dev/null || echo "firstSpec not found in Hebrew"
echo ""
echo "=== Checking French onboarding.json for firstSpec ==="
rg -A 5 '"firstSpec"' apps/frontend/src/shared/i18n/locales/fr/onboarding.json 2>/dev/null || echo "firstSpec not found in French"
# Also check what locale files exist
echo ""
echo "=== Available locale files in onboarding directory ==="
fd 'onboarding.json' apps/frontend/src/shared/i18n/locales/Repository: AndyMik90/Auto-Claude
Length of output: 805
French locale missing required firstSpec translation keys.
The new firstSpec section has been added to en/onboarding.json but is missing from fr/onboarding.json. Per coding guidelines, all new translation keys must be added to a minimum of en/*.json and fr/*.json. Hebrew already has the translations.
Add the complete firstSpec section and all other new keys to apps/frontend/src/shared/i18n/locales/fr/onboarding.json.
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/fr/onboarding.json (corresponding to
lines ~49-81 of the en file), the new "firstSpec" section is missing; add the
complete "firstSpec" object with the exact same keys and structure as in
en/onboarding.json and provide French translations for each string (titles,
subtitles, messages, tips and nested tip descriptions, exampleTitle,
exampleDescription, buttons like openTaskCreator/back/skip/continue). Ensure key
names and nesting match exactly so keys remain present in both locales and
validate JSON syntax after insertion.
| "ollama": { | ||
| "checkingModels": "Checking Ollama models...", | ||
| "notRunning": "Ollama not running", | ||
| "notRunningDescription": "Start Ollama to use local embedding models. Memory will still work with keyword search.", | ||
| "retry": "Retry", | ||
| "installed": "Installed", | ||
| "downloading": "Downloading...", | ||
| "download": "Download", | ||
| "selectModel": "Select an installed model for semantic search. Memory works with keyword search even without embeddings.", | ||
| "googleLightweight": "Google's lightweight embedding model (Recommended)", | ||
| "popularGeneral": "Popular general-purpose embeddings", | ||
| "mixedBreadLarge": "MixedBread AI large embeddings" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if ollama keys exist in Hebrew and French onboarding files
echo "=== Checking Hebrew onboarding.json for ollama ==="
rg -A 10 '"ollama"' apps/frontend/src/shared/i18n/locales/he/onboarding.json 2>/dev/null || echo "ollama not found in Hebrew"
echo ""
echo "=== Checking French onboarding.json for ollama ==="
rg -A 10 '"ollama"' apps/frontend/src/shared/i18n/locales/fr/onboarding.json 2>/dev/null || echo "ollama not found in French"Repository: AndyMik90/Auto-Claude
Length of output: 743
Add Ollama translation keys to French locale.
The new Ollama keys are present in Hebrew but missing from apps/frontend/src/shared/i18n/locales/fr/onboarding.json. All new translation keys must be added to all language files per guidelines (minimum: English and French).
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/fr/onboarding.json (mirror the change
from en file around the new "ollama" block at lines ~130-142), add the missing
"ollama" object with the same keys: checkingModels, notRunning,
notRunningDescription, retry, installed, downloading, download, selectModel,
googleLightweight, popularGeneral, mixedBreadLarge; populate each key with
French translations or, if translation is not available yet, copy the English
text as a placeholder, ensure proper JSON syntax (commas, quotes) and that the
new block is added in the correct location in the onboarding.json file so all
locales contain the same keys.
- Added Hebrew translations for all remaining UI components - Translated task detail panels (Overview, Subtasks, Logs) - Translated task buttons (Start, Stop, Delete, Recover, Resume, Close) - Translated task metadata labels (Created, Updated) - Added translations for IntegrationSettings error/success messages - Added translations for OAuth authentication flows - Added translations for FeatureDetailPanel headers - Fixed JSON syntax errors in translation files Hebrew translation coverage: ~98%
- Add language matching instruction to Insights AI prompt - Add type='button' to MarkdownContent file link button - Fix JSON syntax error in he/settings.json (extra closing brace) - Add pluralization forms to changelog.json (en/he) - Add missing translation key for auth description - Use IPC constant instead of hardcoded string - Fix markdown heading spacing in INSIGHTS_IMPROVEMENTS.md
8b70374 to
325a25f
Compare
SummaryThis PR adds complete Hebrew (he) translation support to the Auto-Claude UI, including: Translation Coverage
Code Quality Fixes
Technical Details
Note on Workflow ApprovalsI notice that 7 workflows are awaiting approval from maintainers. As a first-time contributor, I don't have permission to trigger these checks myself. The code is ready for review, and I'm happy to make any additional changes based on feedback. Looking forward to your review! 🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 29
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (39)
apps/frontend/src/renderer/components/github-prs/GitHubPRs.tsx (3)
205-205: Replace hardcoded string with translation key.The hardcoded string
"Select a pull request to view details"violates the coding guidelines that require all user-facing text to use translation keys.🔎 Proposed fix
First, add the translation key to all locale files (
en/,fr/,he/). For example, inapps/frontend/src/shared/i18n/locales/en/context.json:{ "github": { "notConnected": "GitHub Not Connected", "connectHint": "Connect your GitHub account to view and review pull requests.", "openSettings": "Open Settings", "selectPR": "Select a pull request to view details" } }Then update the component:
+ const { t } = useTranslation('context'); + return ( <div className="flex-1 flex flex-col h-full"> {/* ... */} <div className="w-1/2 flex flex-col"> {selectedPR ? ( <PRDetail /* ... */ /> ) : ( - <EmptyState message="Select a pull request to view details" /> + <EmptyState message={t('github.selectPR')} /> )} </div>Based on learnings.
143-146: Replace hardcoded header text with translation key.The hardcoded string
"Pull Requests"violates the coding guidelines that require all user-facing text to use translation keys.🔎 Proposed fix
First, add the translation key to all locale files. For example, in
apps/frontend/src/shared/i18n/locales/en/context.json:{ "github": { "pullRequests": "Pull Requests" } }Then update the component to use
useTranslation:export function GitHubPRs({ onOpenSettings }: GitHubPRsProps) { + const { t } = useTranslation('context'); const projects = useProjectStore((state) => state.projects); // ... return ( <div className="flex-1 flex flex-col h-full"> <div className="flex items-center justify-between px-4 py-3 border-b border-border"> <div className="flex items-center gap-3"> <h2 className="text-sm font-medium flex items-center gap-2"> <GitPullRequest className="h-4 w-4" /> - Pull Requests + {t('github.pullRequests')} </h2>Based on learnings.
158-160: Replace hardcoded count label with translation key.The hardcoded string
"open"in{prs.length} openviolates the coding guidelines that require all user-facing text to use translation keys.🔎 Proposed fix
First, add the translation key to all locale files. For example, in
apps/frontend/src/shared/i18n/locales/en/context.json:{ "github": { "openCount": "{{count}} open" } }Then update the component (ensure
useTranslationis already added to the main component as suggested in the previous comment):<span className="text-xs text-muted-foreground"> - {prs.length} open + {t('github.openCount', { count: prs.length })} </span>Based on learnings.
apps/frontend/src/renderer/components/AppUpdateNotification.tsx (2)
114-114: Replace hardcoded error strings with translation keys.Lines 114 and 119 contain hardcoded English strings for error messages. These are user-facing and displayed in the UI (line 203), so they must use translation keys to maintain i18n consistency.
🔎 Proposed fix
- setDownloadError(result.error || 'Failed to download update'); + setDownloadError(result.error || t('appUpdate.downloadError'));- setDownloadError('Failed to download update'); + setDownloadError(t('appUpdate.downloadError'));Don't forget to add the
appUpdate.downloadErrorkey to all language files:
apps/frontend/src/shared/i18n/locales/en/dialogs.jsonapps/frontend/src/shared/i18n/locales/fr/dialogs.jsonapps/frontend/src/shared/i18n/locales/he/dialogs.jsonBased on coding guidelines and learnings: Never use hardcoded strings in JSX/TSX files for user-facing text - always reference translation keys from
apps/frontend/src/shared/i18n/locales/.Also applies to: 119-119
142-243: French translation file missing appUpdate keys.All user-facing strings correctly use translation keys from the
dialogs:appUpdatenamespace. However, the required French translation file is missing the entireappUpdatesection inapps/frontend/src/shared/i18n/locales/fr/dialogs.json.English and Hebrew translations contain all 10 keys (title, description, newVersion, released, downloading, downloadError, downloadSuccess, remindLater, installLater, installAndRestart, downloadUpdate), but French is missing them entirely. Per project guidelines, translation keys must be added to ALL language files including French before merge.
apps/frontend/src/renderer/components/task-detail/task-review/DiscardDialog.tsx (2)
1-11: Missing import for translation function.Line 45 uses
t('dialogs.discardChanges'), but there is no import statement for the translation function. You need to add theuseTranslationhook import and call it in the component.🔎 Add the required import and hook
+import { useTranslation } from 'react-i18next'; import { FolderX, Loader2 } from 'lucide-react'; import { AlertDialog,Then inside the component function (after line 33):
}: DiscardDialogProps) { + const { t } = useTranslation(); return (
40-40: Incomplete internationalization: multiple hardcoded strings remain.While line 45 now uses translation, the component still contains numerous hardcoded English strings that must be replaced with translation keys per the coding guidelines.
Hardcoded strings found:
- Line 40: "Discard Build"
- Lines 48-49: "This will permanently delete..." message
- Line 54: "Files changed:"
- Line 58: "Lines:"
- Line 68: "Cancel"
- Line 80: "Discarding..."
- Line 85: "Discard Build"
As per coding guidelines: "Always use translation keys with
useTranslation()for all user-facing text" and "Never use hardcoded strings in JSX/TSX files for user-facing text."🔎 Example translation structure needed
All these strings should reference translation keys. For example:
- Discard Build + {t('dialogs.discardBuild.title')}- This will permanently delete the isolated workspace and all uncommitted changes. - The task will be moved back to Planning status. + {t('dialogs.discardBuild.warningMessage')}Remember to add these keys to all language files (
en/*.json,fr/*.json, andhe/*.json) as noted in the learnings.Also applies to: 48-49, 54-54, 58-58, 68-68, 80-80, 85-85
apps/frontend/src/renderer/components/SDKRateLimitModal.tsx (1)
351-351: Translate thearia-labelfor accessibility.The
aria-label="Recommended"is hardcoded in English. Screen reader users in non-English locales will hear this label in English, which degrades accessibility.🔎 Proposed fix
- <Star className="h-3 w-3 text-yellow-500" aria-label="Recommended" /> + <Star className="h-3 w-3 text-yellow-500" aria-label={t('switching.recommended.ariaLabel')} />Add the key
switching.recommended.ariaLabelto all locale files with appropriate translations (e.g., "Recommended", "Recommandé", "מומלץ").Based on learnings, all translation keys must be added to ALL language files.
apps/frontend/src/renderer/components/task-detail/task-review/ConflictDetailsDialog.tsx (1)
36-124: Critical: Incomplete i18n implementation - multiple hardcoded strings remain.The component only translates the Close button while numerous user-facing strings remain hardcoded. Per coding guidelines, all user-facing text in JSX/TSX must use translation keys from
apps/frontend/src/shared/i18n/locales/.Hardcoded strings that need translation (lines):
- Line 43: "Merge Conflicts Preview"
- Line 46: "potential conflict", "can be auto-merged"
- Lines 79, 83: "auto-merge"
- Line 90: "Location:"
- Line 92: "Reason:"
- Line 94: "Strategy:"
- Line 104: "No conflicts detected"
- Line 119: "Stage with AI Merge" / "Merge with AI"
Recommended approach
Add all strings to the translation files (minimum
en/tasks.jsonoren/taskReview.jsonand correspondingfr/files), then replace hardcoded strings with translation keys:-<AlertDialogTitle className="flex items-center gap-2"> - <AlertTriangle className="h-5 w-5 text-warning" /> - Merge Conflicts Preview -</AlertDialogTitle> +<AlertDialogTitle className="flex items-center gap-2"> + <AlertTriangle className="h-5 w-5 text-warning" /> + {t('conflictDialog.title')} +</AlertDialogTitle>Apply similar changes for all hardcoded strings identified above.
Based on coding guidelines: "Never use hardcoded strings in JSX/TSX files for user-facing text - always reference translation keys from
apps/frontend/src/shared/i18n/locales/"apps/frontend/src/renderer/components/EnvConfigModal.tsx (4)
49-51: Default prop values contain hardcoded English strings.The
titleanddescriptionprops have hardcoded English defaults. If these props are not provided, the component displays untranslated text.🔎 Proposed fix
Move defaults inside the component using translations:
export function EnvConfigModal({ open, onOpenChange, onConfigured, - title = 'Claude Authentication Required', - description = 'A Claude Code OAuth token is required to use AI features like Ideation and Roadmap generation.', + title, + description, projectId }: EnvConfigModalProps) { const { t } = useTranslation('ideation'); + const displayTitle = title || t('auth.title'); + const displayDescription = description || t('auth.description');
383-387: Hardcoded "Saving..." text should use translation key.Line 386 contains hardcoded text that should be translated.
🔎 Proposed fix
{isSaving ? ( <> <Loader2 className="mr-2 h-5 w-5 animate-spin" /> - Saving... + {t('auth.saving')} </>
396-404: Hardcoded "or" divider text should use translation key.The divider text "or" on line 402 is hardcoded. This also appears on line 463.
🔎 Proposed fix
<div className="relative flex justify-center text-xs uppercase"> - <span className="bg-background px-2 text-muted-foreground">or</span> + <span className="bg-background px-2 text-muted-foreground">{t('auth.or')}</span> </div>
495-510: Add explicittype="button"to prevent form submission.Per static analysis, the copy button lacks an explicit
typeattribute. In a form context, buttons default totype="submit"which could cause unintended form submissions.🔎 Proposed fix
<button + type="button" onClick={handleCopyCommand} className="inline-flex items-center text-info hover:text-info/80" >apps/frontend/src/renderer/components/ideation/IdeaDetailPanel.tsx (1)
67-78: Remaining hardcoded strings violate coding guidelines.Lines 68, 76, 95, and 103 contain hardcoded user-facing text ("Description", "Rationale", "Convert to Auto-Build Task", "Dismiss Idea") that should use translation keys. Additionally, line 52 renders
idea.statusdirectly without translation.As per coding guidelines, never use hardcoded strings in JSX/TSX files for user-facing text.
🔎 Suggested translations
{/* Description */} <div> - <h3 className="text-sm font-medium mb-2">Description</h3> + <h3 className="text-sm font-medium mb-2">{t('detail.description')}</h3> <p className="text-sm text-muted-foreground">{idea.description}</p> </div> {/* Rationale */} <div> <h3 className="text-sm font-medium mb-2 flex items-center gap-2"> <Lightbulb className="h-4 w-4" /> - Rationale + {t('detail.rationale')} </h3>Similar changes needed for "Convert to Auto-Build Task" and "Dismiss Idea" button labels.
apps/frontend/src/renderer/components/KanbanBoard.tsx (1)
28-28:TASK_STATUS_LABELSimport appears unused.The
TASK_STATUS_LABELSconstant is imported but no longer used in this file since status labels are now fetched viat(\status.${status}`)`. Consider removing the unused import.🔎 Suggested fix
-import { TASK_STATUS_COLUMNS, TASK_STATUS_LABELS } from '../../shared/constants'; +import { TASK_STATUS_COLUMNS } from '../../shared/constants';apps/frontend/src/renderer/components/TaskFileExplorerDrawer.tsx (1)
3-105: Add missing translation keys toapps/frontend/src/shared/i18n/locales/fr/common.json.All keys exist in the English locale, but the following translation keys are missing from the French common locale file and must be added:
fileExplorer.titlefileExplorer.dragReferencestooltips.refreshtooltips.closePer the project guidelines, translation keys must be added to ALL language files (minimum:
en/*.jsonandfr/*.json).apps/frontend/src/renderer/components/ideation/IdeaCard.tsx (2)
142-142: Hardcoded strings in TooltipContent violate i18n guidelines.Several tooltip strings remain hardcoded instead of using translation keys:
- Line 142:
"Convert to Task"- Line 158:
"Dismiss"- Line 179:
"Go to Task"- Line 200:
"Go to Task"As per coding guidelines, never use hardcoded strings for user-facing text.
🔎 Proposed fix
</TooltipTrigger> - <TooltipContent>Convert to Task</TooltipContent> + <TooltipContent>{t('card.convertToTask')}</TooltipContent> </Tooltip> <Tooltip> ... </TooltipTrigger> - <TooltipContent>Dismiss</TooltipContent> + <TooltipContent>{t('card.dismiss')}</TooltipContent> </Tooltip>And for "Go to Task" at lines 179 and 200:
- <TooltipContent>Go to Task</TooltipContent> + <TooltipContent>{t('card.goToTask')}</TooltipContent>Add these keys to
en/ideation.jsonandfr/ideation.json:"card": { "convertToTask": "Convert to Task", "dismiss": "Dismiss", "goToTask": "Go to Task" }Also applies to: 158-158, 179-179, 200-200
14-16: Remove unused constant imports.After migrating to translation keys,
UIUX_CATEGORY_LABELSandDOCUMENTATION_CATEGORY_LABELSare no longer used in this component. The code now usest('uiuxCategories.*')andt('documentationCategories.*')instead.🔎 Proposed fix
import { IDEATION_TYPE_COLORS, IDEATION_STATUS_COLORS, IDEATION_EFFORT_COLORS, IDEATION_IMPACT_COLORS, SECURITY_SEVERITY_COLORS, - UIUX_CATEGORY_LABELS, - DOCUMENTATION_CATEGORY_LABELS, CODE_QUALITY_SEVERITY_COLORS } from '../../../shared/constants';apps/frontend/src/renderer/components/context/MemoriesTab.tsx (2)
66-93: Hardcoded user-facing strings remain.Several strings in this section are not using translation keys, violating the coding guideline that requires all user-facing text to use
t():
- Line 69:
"Connected"badge text- Line 83:
"Database"label- Line 84:
"Path"label- Line 86:
"Episodes"label- Line 91:
"Last session: #"text🔎 Suggested fix
{memoryStatus?.available ? ( <Badge variant="outline" className="bg-success/10 text-success border-success/30"> <CheckCircle className="h-3 w-3 mr-1" /> - Connected + {t('memories.connected')} </Badge> ) : ( ... <div className="grid gap-3 sm:grid-cols-3 text-sm"> - <InfoItem label="Database" value={memoryStatus.database || 'auto_claude_memory'} /> - <InfoItem label="Path" value={memoryStatus.dbPath || '~/.auto-claude/graphs'} /> + <InfoItem label={t('memories.database')} value={memoryStatus.database || 'auto_claude_memory'} /> + <InfoItem label={t('memories.path')} value={memoryStatus.dbPath || '~/.auto-claude/graphs'} /> {memoryState && ( - <InfoItem label="Episodes" value={memoryState.episode_count.toString()} /> + <InfoItem label={t('memories.episodes')} value={memoryState.episode_count.toString()} /> )} </div> {memoryState?.last_session && ( <p className="text-xs text-muted-foreground"> - Last session: #{memoryState.last_session} + {t('memories.lastSession', { session: memoryState.last_session })} </p> )}As per coding guidelines, never use hardcoded strings in JSX/TSX files for user-facing text.
124-147: Additional hardcoded strings in search results section.The search results rendering contains untranslated user-facing text:
- Line 127:
"{searchResults.length} result{searchResults.length !== 1 ? 's' : ''} found"- should use pluralization with i18next- Line 137:
"Score:"label🔎 Suggested fix
<p className="text-sm text-muted-foreground"> - {searchResults.length} result{searchResults.length !== 1 ? 's' : ''} found + {t('memories.resultsFound', { count: searchResults.length })} </p> ... <span className="text-xs text-muted-foreground"> - Score: {result.score.toFixed(2)} + {t('memories.score')}: {result.score.toFixed(2)} </span>As per coding guidelines, always use translation keys with
useTranslation()for all user-facing text.apps/frontend/src/renderer/components/onboarding/MemoryStep.tsx (2)
34-45: Hardcoded provider names and descriptions.The
EMBEDDING_PROVIDERSarray contains hardcoded user-facing strings that should use translation keys:{ id: 'ollama', name: 'Ollama (Local)', description: 'Free, local embeddings', ... }🔎 Suggested approach
const EMBEDDING_PROVIDERS: Array<{ id: GraphitiEmbeddingProvider; - name: string; - description: string; requiresApiKey: boolean; }> = [ - { id: 'ollama', name: 'Ollama (Local)', description: 'Free, local embeddings', requiresApiKey: false }, - { id: 'openai', name: 'OpenAI', description: 'text-embedding-3-small', requiresApiKey: true }, + { id: 'ollama', requiresApiKey: false }, + { id: 'openai', requiresApiKey: true }, // ... etc ]; // Then in render, use: // t(`onboarding.memory.providers.${p.id}.name`) // t(`onboarding.memory.providers.${p.id}.description`)As per coding guidelines, never use hardcoded strings for user-facing text.
168-173: Hardcoded error message fallbacks.Error fallback messages should use translation keys for consistency:
🔎 Suggested fix
if (result?.success) { // ... } else { - setError(result?.error || 'Failed to save memory configuration'); + setError(result?.error || t('onboarding.memory.errors.saveFailed')); } } catch (err) { - setError(err instanceof Error ? err.message : 'Unknown error occurred'); + setError(err instanceof Error ? err.message : t('onboarding.memory.errors.unknown')); } finally {apps/frontend/src/renderer/components/Worktrees.tsx (2)
80-88: Hardcoded error messages should use translation keys.Several error messages are hardcoded and should be translated:
- Lines 81, 84:
'Failed to load worktrees'- Line 106:
'Task not found for this worktree'🔎 Suggested fix
if (result.success && result.data) { setWorktrees(result.data.worktrees); } else { - setError(result.error || 'Failed to load worktrees'); + setError(result.error || t('errors.loadFailed')); } } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to load worktrees'); + setError(err instanceof Error ? err.message : t('errors.loadFailed')); } finally { ... const task = findTaskForWorktree(selectedWorktree.specName); if (!task) { - setError('Task not found for this worktree'); + setError(t('errors.taskNotFound')); return; }As per coding guidelines, always use translation keys for user-facing text.
Also applies to: 105-108
120-129: Additional hardcoded error messages in merge/delete handlers.More error messages need translation keys:
- Lines 122, 128:
'Merge failed'- Line 141:
'Task not found for this worktree'(duplicate)- Lines 154, 157:
'Failed to delete worktree'🔎 Suggested fix
} else { setMergeResult({ success: false, - message: result.error || 'Merge failed' + message: result.error || t('errors.mergeFailed') }); } } catch (err) { setMergeResult({ success: false, - message: err instanceof Error ? err.message : 'Merge failed' + message: err instanceof Error ? err.message : t('errors.mergeFailed') }); } ... if (!task) { - setError('Task not found for this worktree'); + setError(t('errors.taskNotFound')); return; } ... if (result.success) { // ... } else { - setError(result.error || 'Failed to delete worktree'); + setError(result.error || t('errors.deleteFailed')); } } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to delete worktree'); + setError(err instanceof Error ? err.message : t('errors.deleteFailed')); }Also applies to: 139-158
apps/frontend/src/renderer/components/changelog/GitHubReleaseCard.tsx (1)
36-41: Hardcoded error message fallbacks.Error fallback messages should use translation keys:
🔎 Suggested fix
if (result.success && result.data) { setReleaseUrl(result.data.url); } else { - setReleaseError(result.error || 'Failed to create release'); + setReleaseError(result.error || t('release.createFailed')); } } catch (err) { - setReleaseError(err instanceof Error ? err.message : 'Failed to create release'); + setReleaseError(err instanceof Error ? err.message : t('release.createFailed')); }As per coding guidelines, always use translation keys for user-facing text.
apps/frontend/src/renderer/components/settings/ThemeSelector.tsx (1)
113-126: Hardcoded tooltip titles on color swatches.The
titleattributes on the color preview divs contain hardcoded strings:
- Line 118:
title="Background color"- Line 123:
title="Accent color"🔎 Suggested fix
<div className="w-6 h-6 rounded-full border-2 border-background shadow-sm" style={{ backgroundColor: bgColor }} - title="Background color" + title={t('theme.backgroundColor')} /> <div className="w-6 h-6 rounded-full border-2 border-background shadow-sm" style={{ backgroundColor: accentColor }} - title="Accent color" + title={t('theme.accentColor')} />As per coding guidelines, never use hardcoded strings for user-facing text.
apps/frontend/src/renderer/components/changelog/ChangelogList.tsx (1)
52-63: Inconsistent pluralization approach - use i18next plural features consistently.The
getSummaryLabelfunction uses manual ternary-based pluralization (count !== 1 ? t('commits.tasks') : t('commits.task')), which won't work correctly for languages like Hebrew that have dual forms and more complex plural rules. This approach is also inconsistent with how other parts of the codebase might handle pluralization.🔎 Recommended approach using i18next pluralization
Update the function to use i18next's count-based pluralization:
const getSummaryLabel = () => { - const count = getSummaryCount(); switch (sourceMode) { case 'tasks': - return count !== 1 ? t('commits.tasks') : t('commits.task'); + return t('commits.task', { count: getSummaryCount() }); case 'git-history': case 'branch-diff': - return count !== 1 ? t('commits.commits') : t('commits.commit'); + return t('commits.commit', { count: getSummaryCount() }); default: return 'item'; } };Then update the translation files to use plural forms:
{ "commits": { "task_one": "task", "task_other": "tasks", "commit_one": "commit", "commit_other": "commits" } }For Hebrew, you'd add additional plural forms as needed (e.g.,
task_twofor dual form).apps/frontend/src/renderer/components/task-detail/TaskDetailModal.tsx (2)
285-294: Replace hardcoded review reason labels with translation keys.Lines 290-292 contain hardcoded English strings for review reason badges ('Completed', 'Has Errors', 'Approve Plan', 'QA Issues'). Per coding guidelines, all user-facing text must use translation keys.
🔎 Proposed fix
{task.status === 'human_review' && task.reviewReason && ( <Badge variant={task.reviewReason === 'completed' ? 'success' : task.reviewReason === 'errors' ? 'destructive' : 'warning'} className="text-xs" > - {task.reviewReason === 'completed' ? 'Completed' : - task.reviewReason === 'errors' ? 'Has Errors' : - task.reviewReason === 'plan_review' ? 'Approve Plan' : 'QA Issues'} + {t(`reviewReason.${task.reviewReason}`)} </Badge> )}Add to
apps/frontend/src/shared/i18n/locales/en/tasks.json(and French):{ "reviewReason": { "completed": "Completed", "errors": "Has Errors", "plan_review": "Approve Plan", "qa_issues": "QA Issues" } }As per coding guidelines.
501-519: Internationalize delete dialog button labels.Lines 501, 513, and 518 contain hardcoded English text ('Cancel', 'Deleting...', 'Delete Permanently'). These should use translation keys.
🔎 Proposed fix
<AlertDialogFooter> - <AlertDialogCancel disabled={state.isDeleting}>Cancel</AlertDialogCancel> + <AlertDialogCancel disabled={state.isDeleting}>{t('buttons.cancel')}</AlertDialogCancel> <AlertDialogAction onClick={(e) => { e.preventDefault(); handleDelete(); }} disabled={state.isDeleting} className="bg-destructive text-destructive-foreground hover:bg-destructive/90" > {state.isDeleting ? ( <> <Loader2 className="mr-2 h-4 w-4 animate-spin" /> - Deleting... + {t('buttons.deleting')} </> ) : ( <> <Trash2 className="mr-2 h-4 w-4" /> - Delete Permanently + {t('buttons.deletePermanently')} </> )} </AlertDialogAction> </AlertDialogFooter>apps/frontend/src/renderer/components/roadmap/FeatureDetailPanel.tsx (2)
194-206: Untranslated severity text in competitor insights badge.Line 204 contains the hardcoded English word "severity" that should be translated.
🔎 Proposed fix
<Badge variant="outline" className={`text-xs ${ insight.severity === 'high' ? 'text-red-500 border-red-500/50' : insight.severity === 'medium' ? 'text-yellow-500 border-yellow-500/50' : 'text-green-500 border-green-500/50' }`} > - {insight.severity} severity + {t(`featureDetail.severity.${insight.severity}`)} </Badge>
216-232: Hardcoded button labels violate i18n guidelines.Lines 220 and 228 contain hardcoded English text ("Go to Task" and "Convert to Auto-Build Task") that should use translation keys.
To fix this:
- Add
"goToTask": "Go to Task"and"convertToTask": "Convert to Auto-Build Task"to thefeatureDetailsection inapps/frontend/src/shared/i18n/locales/en/roadmap.json- Add the same keys to
apps/frontend/src/shared/i18n/locales/he/roadmap.json(thefeatureDetailsection already exists)- Create
apps/frontend/src/shared/i18n/locales/fr/roadmap.jsonwith the completefeatureDetailsection including these keys, or note that French will not support this featureThen update the buttons to use
{t('featureDetail.goToTask')}and{t('featureDetail.convertToTask')}respectively.apps/frontend/src/renderer/components/ExistingCompetitorAnalysisDialog.tsx (1)
46-53: Hardcoded locale in date formatting.Line 48 hardcodes
'en-US'for date formatting, which won't respect the user's selected language. This should use the current i18n locale.🔎 Proposed fix
+ const { t, i18n } = useTranslation('roadmap'); + const formatDate = (date?: Date) => { if (!date) return t('competitorAnalysis.recently'); - return new Intl.DateTimeFormat('en-US', { + return new Intl.DateTimeFormat(i18n.language, { month: 'short', day: 'numeric', year: 'numeric', }).format(date); };apps/frontend/src/renderer/components/context/ProjectIndexTab.tsx (1)
89-194: Multiple untranslated UI labels in project index display.The code contains hardcoded English strings throughout the project index content section that must use translation keys:
- Section headings: "Overview" (94), "Services" (118), "Infrastructure" (132), "Conventions" (169)
- Infrastructure labels: "Docker Compose" (138), "CI/CD" (141), "Deployment" (144), "Docker Services" (149)
- Convention labels: "Python Linting" (175), "JS Linting" (178), "Formatting" (181), "Git Hooks" (184), "TypeScript" (187), "Enabled" (187)
- Dynamic pluralization: "service/services" logic (103-104)
The
projectIndexkeys in locale files (en, he) only cover basic UI elements (title, refresh, analyze, empty, error) and lack the required translation keys for all section headings and labels. Additional translation keys must be added to ALL language files.apps/frontend/src/renderer/components/settings/AgentProfileSettings.tsx (1)
150-163: Add missing French translations foragentProfile.profilesandagentProfile.thinkingLevels.The code uses dynamic translation keys
t(agentProfile.profiles.${profile.id}.name),t(agentProfile.profiles.${profile.id}.description), and references toagentProfile.thinkingLevelswhich are missing fromapps/frontend/src/shared/i18n/locales/fr/settings.json. The French locale file has the generic section metadata but lacks theprofilesandthinkingLevelsobjects defined in the English version. Add French translations for all four profiles (auto, complex, balanced, quick) and all five thinking levels (none, low, medium, high, ultrathink) to match the English structure.apps/frontend/src/renderer/components/onboarding/OAuthStep.tsx (1)
43-43: Add missing OAuth error translations to English and French locale files.The component uses
oauth.errors.*keys that do not exist in English (en/onboarding.json). Additionally, French (fr/onboarding.json) is missing multiple keys required by the component. Hebrew has the completeerrorsobject.English missing keys in
apps/frontend/src/shared/i18n/locales/en/onboarding.json:
oauth.errors.account,oauth.errors.authComplete,oauth.errors.profileAuthSuccess,oauth.errors.canUseProfileoauth.errors.profileDeleteFailed,oauth.errors.profileRenameFailed,oauth.errors.setActiveFailedoauth.errors.tokenSaveFailed,oauth.errors.tryAgain,oauth.errors.tokenSaveFailedGenericFrench missing keys in
apps/frontend/src/shared/i18n/locales/fr/onboarding.json:
- All keys listed above for English, plus:
oauth.setupTitle,oauth.setupDescription,oauth.infoMessage,oauth.accountNamePlaceholder,oauth.addAccount,oauth.default,oauth.active,oauth.authenticated,oauth.needsAuth,oauth.authenticate,oauth.setActive,oauth.validationMessageapps/frontend/src/renderer/components/Insights.tsx (3)
436-440: Hardcoded strings "You" and "Assistant" should use translation keys.Per coding guidelines, all user-facing text must use translation keys. These labels should be localized.
🔎 Proposed fix
First, add the keys to
insights.json:{ "you": "You", "assistant": "Assistant" }Then update the component:
<div className="text-sm font-medium text-foreground"> - {isUser ? 'You' : 'Assistant'} + {isUser ? t('you') : t('assistant')} </div>Note:
MessageBubblewould need access to thetfunction, either by addinguseTranslationhook or passingtas a prop.As per coding guidelines, never use hardcoded strings in JSX/TSX files for user-facing text.
452-511: Multiple hardcoded strings in task suggestion card need translation.The following strings should use translation keys:
- Line 454:
"Suggested Task"- Line 499:
"Creating..."- Line 504:
"Task Created"- Line 509:
"Create Task"🔎 Proposed fix
Add keys to
insights.json:{ "suggestedTask": "Suggested Task", "creatingTask": "Creating...", "taskCreated": "Task Created", "createTask": "Create Task" }Then update the JSX (requires passing
ttoMessageBubbleor usinguseTranslationinside it):<span className="text-sm font-medium text-primary"> - Suggested Task + {t('suggestedTask')} </span> ... {isCreatingTask ? ( <> <Loader2 className="mr-2 h-4 w-4 animate-spin" /> - Creating... + {t('creatingTask')} </> ) : taskCreated ? ( <> <CheckCircle2 className="mr-2 h-4 w-4" /> - Task Created + {t('taskCreated')} </> ) : ( <> <Plus className="mr-2 h-4 w-4" /> - Create Task + {t('createTask')} </> )}As per coding guidelines, always use translation keys for all user-facing text.
584-584: Hardcoded "tool/tools used" text should use translation keys.The text
{tools.length} tool{tools.length !== 1 ? 's' : ''} usedcontains hardcoded English strings with manual pluralization.🔎 Proposed fix
Use i18next's pluralization feature:
// insights.json { "toolsUsed_one": "{{count}} tool used", "toolsUsed_other": "{{count}} tools used" }- <span>{tools.length} tool{tools.length !== 1 ? 's' : ''} used</span> + <span>{t('toolsUsed', { count: tools.length })}</span>Note:
ToolUsageHistorywould need access to thetfunction viauseTranslationhook.apps/frontend/src/shared/i18n/locales/en/tasks.json (1)
1-161: Add missing translation keys to French locale file.The French translation file (
fr/tasks.json) is missing 7 new keys that were added to the English version:
buttonseditDialogerrorsformimageUploadmetadatatabsPer coding guidelines, new translation keys must be added to all language files (minimum:
en/*.jsonandfr/*.json). The Hebrew locale file (he/tasks.json) has all required keys.
| ) : ( | ||
| <div className="text-muted-foreground"> | ||
| Select a project to get started | ||
| {t('common:labels.selectProjectToStart')} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify the selectProjectToStart translation key exists in common.json for all locales
echo "=== Checking labels.selectProjectToStart in common.json for all locales ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/$locale/common.json"
if [ -f "$file" ]; then
echo "✓ $locale/common.json exists"
if jq -e '.labels.selectProjectToStart' "$file" > /dev/null 2>&1; then
echo " ✓ labels.selectProjectToStart: $(jq -r '.labels.selectProjectToStart' "$file")"
else
echo " ✗ labels.selectProjectToStart: MISSING"
fi
else
echo "✗ $locale/common.json: FILE NOT FOUND"
fi
echo ""
doneRepository: AndyMik90/Auto-Claude
Length of output: 376
Add missing French translation for labels.selectProjectToStart.
The translation key common:labels.selectProjectToStart exists in en/common.json and he/common.json, but is missing from fr/common.json. Add this key to apps/frontend/src/shared/i18n/locales/fr/common.json under the labels section to maintain consistency with the minimum required locales (en and fr).
🤖 Prompt for AI Agents
In apps/frontend/src/renderer/App.tsx around line 646 the UI uses
common:labels.selectProjectToStart but that key is missing from the French
locale; open apps/frontend/src/shared/i18n/locales/fr/common.json and under the
"labels" section add the key "selectProjectToStart" with a French value (e.g.
"Sélectionnez un projet pour commencer"), ensuring valid JSON syntax (proper
commas/quoting) and consistent placement with other labels, then save and run
any i18n/lint/tests to verify the translation is picked up.
| CHANGELOG_SOURCE_MODE_DESCRIPTIONS | ||
| } from '../../../shared/constants'; | ||
| import { cn } from '../../lib/utils'; | ||
| import { useTranslation } from 'react-i18next'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, verify that the translation files exist
echo "=== Checking translation files ==="
if [ -f "apps/frontend/src/shared/i18n/locales/en/changelog.json" ]; then
echo "✓ en/changelog.json exists"
else
echo "✗ en/changelog.json is MISSING"
fi
if [ -f "apps/frontend/src/shared/i18n/locales/fr/changelog.json" ]; then
echo "✓ fr/changelog.json exists"
else
echo "✗ fr/changelog.json is MISSING"
fi
echo ""
echo "=== Comparing key counts ==="
if [ -f "apps/frontend/src/shared/i18n/locales/en/changelog.json" ] && [ -f "apps/frontend/src/shared/i18n/locales/fr/changelog.json" ]; then
en_keys=$(jq -r 'paths(scalars) | join(".")' apps/frontend/src/shared/i18n/locales/en/changelog.json 2>/dev/null | wc -l)
fr_keys=$(jq -r 'paths(scalars) | join(".")' apps/frontend/src/shared/i18n/locales/fr/changelog.json 2>/dev/null | wc -l)
echo "EN keys: $en_keys, FR keys: $fr_keys"
if [ "$en_keys" -eq "$fr_keys" ]; then
echo "✓ Key counts match"
else
echo "✗ Key counts DO NOT match"
fi
fiRepository: AndyMik90/Auto-Claude
Length of output: 187
🏁 Script executed:
# Examine ChangelogFilters.tsx to verify i18n implementation
echo "=== Examining ChangelogFilters.tsx ==="
wc -l apps/frontend/src/renderer/components/changelog/ChangelogFilters.tsx
echo ""
echo "=== Checking for useTranslation usage ==="
rg "useTranslation" apps/frontend/src/renderer/components/changelog/ChangelogFilters.tsx -A 2 -B 2
echo ""
echo "=== Checking for hardcoded strings in JSX ==="
# Look for suspicious patterns of hardcoded text
sed -n '1,150p' apps/frontend/src/renderer/components/changelog/ChangelogFilters.tsx | grep -E "(className=|title=|placeholder=|aria-label=|<.*>.*[A-Z].*<)" | head -20Repository: AndyMik90/Auto-Claude
Length of output: 1770
🏁 Script executed:
cat -n apps/frontend/src/renderer/components/changelog/ChangelogFilters.tsx | head -100Repository: AndyMik90/Auto-Claude
Length of output: 4282
🏁 Script executed:
cat -n apps/frontend/src/renderer/components/changelog/ChangelogFilters.tsx | tail -250Repository: AndyMik90/Auto-Claude
Length of output: 12337
fr/changelog.json translation file is missing and must be created.
The component correctly implements i18n with useTranslation('changelog') and all user-facing text properly uses translation keys. However, the coding guidelines require translation keys to be added to ALL language files (minimum: en/*.json and fr/*.json). The fr/changelog.json file is missing, which blocks this change.
Create apps/frontend/src/shared/i18n/locales/fr/changelog.json with French translations for all keys used in the component (source, gitOptions, branches, branchDiff, actions namespaces).
| {t('competitorViewer.title')} | ||
| </DialogTitle> | ||
| <DialogDescription> | ||
| Analyzed {analysis.competitors.length} competitors to identify market gaps and opportunities | ||
| {t('competitorViewer.description', { count: analysis.competitors.length })} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify competitorViewer keys exist in required locale files
echo "=== Checking competitorViewer keys in roadmap.json ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/${locale}/roadmap.json"
if [ -f "$file" ]; then
echo "Checking $locale:"
has_competitor=$(jq 'has("competitorViewer")' "$file" 2>/dev/null)
echo " Has competitorViewer section: $has_competitor"
if [ "$has_competitor" = "true" ]; then
key_count=$(jq '.competitorViewer | keys | length' "$file" 2>/dev/null)
echo " Keys in competitorViewer: $key_count"
fi
else
echo "✗ Missing: $file"
fi
done
echo ""
echo "=== Checking specific keys in FR ==="
required_keys=("title" "description" "visit" "painPointsTitle" "noPainPoints" "source" "frequency" "opportunity" "insightsSummary" "topPainPoints" "differentiatorOpportunities" "marketTrends")
fr_file="apps/frontend/src/shared/i18n/locales/fr/roadmap.json"
if [ -f "$fr_file" ]; then
for key in "${required_keys[@]}"; do
has_key=$(jq ".competitorViewer | has(\"$key\")" "$fr_file" 2>/dev/null)
if [ "$has_key" = "true" ]; then
echo "✓ $key"
else
echo "✗ MISSING: $key"
fi
done
else
echo "FR roadmap.json not found"
fi
echo ""
echo "=== Checking specific keys in EN ==="
en_file="apps/frontend/src/shared/i18n/locales/en/roadmap.json"
if [ -f "$en_file" ]; then
for key in "${required_keys[@]}"; do
has_key=$(jq ".competitorViewer | has(\"$key\")" "$en_file" 2>/dev/null)
if [ "$has_key" = "true" ]; then
echo "✓ $key"
else
echo "✗ MISSING: $key"
fi
done
else
echo "EN roadmap.json not found"
fiRepository: AndyMik90/Auto-Claude
Length of output: 625
Create apps/frontend/src/shared/i18n/locales/fr/roadmap.json with all competitorViewer translations.
The French translation file for roadmap is missing. The English file contains all 12 required competitorViewer keys, but the French translations are not provided. Per coding guidelines, all new translation keys must exist in both en/roadmap.json and fr/roadmap.json (minimum). Add translations for:
- competitorViewer.title
- competitorViewer.description
- competitorViewer.visit
- competitorViewer.painPointsTitle
- competitorViewer.noPainPoints
- competitorViewer.source
- competitorViewer.frequency
- competitorViewer.opportunity
- competitorViewer.insightsSummary
- competitorViewer.topPainPoints
- competitorViewer.differentiatorOpportunities
- competitorViewer.marketTrends
🤖 Prompt for AI Agents
In apps/frontend/src/renderer/components/CompetitorAnalysisViewer.tsx around
lines 34 to 37, the component uses 12 competitorViewer i18n keys but
apps/frontend/src/shared/i18n/locales/fr/roadmap.json is missing those French
translations; create or update that file to include French equivalents for the
following keys: competitorViewer.title, competitorViewer.description,
competitorViewer.visit, competitorViewer.painPointsTitle,
competitorViewer.noPainPoints, competitorViewer.source,
competitorViewer.frequency, competitorViewer.opportunity,
competitorViewer.insightsSummary, competitorViewer.topPainPoints,
competitorViewer.differentiatorOpportunities, and competitorViewer.marketTrends
matching the structure of en/roadmap.json so all keys exist in both locales.
| <TabsTrigger value="index" className="gap-2"> | ||
| <FolderTree className="h-4 w-4" /> | ||
| Project Index | ||
| {t('tabs.projectIndex')} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, check if the locale files exist and their contents
echo "=== Checking context.json files ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/$locale/context.json"
if [ -f "$file" ]; then
echo "✓ $locale/context.json exists"
echo "Content:"
cat "$file"
echo ""
else
echo "✗ $locale/context.json: FILE NOT FOUND"
echo ""
fi
done
# Also check the structure of the locales directory
echo "=== Directory structure ==="
find apps/frontend/src/shared/i18n/locales -type f -name "*.json" | head -20Repository: AndyMik90/Auto-Claude
Length of output: 4996
🏁 Script executed:
#!/bin/bash
# Check the Context.tsx file around lines 39-43
echo "=== Context.tsx lines 35-50 ==="
sed -n '35,50p' apps/frontend/src/renderer/components/context/Context.tsxRepository: AndyMik90/Auto-Claude
Length of output: 735
Add missing French locale file for context translations.
The translation keys tabs.projectIndex and tabs.memories are correctly defined in en/context.json and he/context.json, but fr/context.json is entirely missing. According to project guidelines, context translations must exist in both English and French minimum. Create apps/frontend/src/shared/i18n/locales/fr/context.json with translations for all keys present in the English version.
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/fr/context.json (create this file) to
address missing French translations referenced at
apps/frontend/src/renderer/components/context/Context.tsx line 39: copy every
key/structure from apps/frontend/src/shared/i18n/locales/en/context.json
(including tabs.projectIndex, tabs.memories and any other keys) and provide
accurate French translations for each string, preserve the exact JSON key names
and nesting, save as UTF-8, and ensure the new file is included in the i18n
locale loading (same directory and naming convention) so the French locale is
available at runtime.
| { | ||
| "title": "תובנות", | ||
| "subtitle": "שאל שאלות על בסיס הקוד שלך", | ||
| "chatHistory": "היסטוריית צ'אט", | ||
| "newChat": "צ'אט חדש", | ||
| "noConversations": "עדיין אין שיחות", | ||
| "deleteConversation": "למחוק שיחה?", | ||
| "deleteConversationDescription": "פעולה זו תמחק לצמיתות את השיחה הזו ואת כל ההודעות שלה. לא ניתן לבטל פעולה זו.", | ||
| "cancel": "ביטול", | ||
| "delete": "מחק", | ||
| "rename": "שנה שם", | ||
| "message": "הודעה", | ||
| "messages": "הודעות", | ||
| "today": "היום", | ||
| "yesterday": "אתמול", | ||
| "thisWeek": "השבוע", | ||
| "older": "ישנים יותר", | ||
| "placeholder": "שאל על בסיס הקוד שלך...", | ||
| "sendHint": "לחץ Enter לשליחה, Shift+Enter לשורה חדשה", | ||
| "stop": "עצור", | ||
| "profileSelector": { | ||
| "label": "פרופיל סוכן", | ||
| "custom": "מותאם אישית...", | ||
| "customDescription": "בחר מודל ורמת חשיבה" | ||
| }, | ||
| "tools": { | ||
| "reading": "קורא קובץ", | ||
| "searching": "מחפש קבצים", | ||
| "searchingCode": "מחפש בקוד" | ||
| }, | ||
| "thinking": "חושב...", | ||
| "assistant": "עוזר", | ||
| "suggestions": { | ||
| "architecture": "מה הארכיטקטורה של הפרויקט הזה?", | ||
| "improvements": "הצע שיפורים לאיכות הקוד", | ||
| "features": "אילו תכונות אוכל להוסיף לאחר מכן?", | ||
| "security": "האם יש חששות אבטחה?" | ||
| }, | ||
| "empty": { | ||
| "title": "אין היסטוריית צ'אט", | ||
| "description": "התחל שיחה כדי לנתח את בסיס הקוד שלך" | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify that insights translation keys exist in all required locales
echo "=== Checking for insights.json in all locales ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/$locale/insights.json"
if [ -f "$file" ]; then
echo "✓ $locale/insights.json exists"
echo " Top-level keys:"
jq 'keys' "$file" 2>/dev/null | head -20
else
echo "✗ $locale/insights.json NOT FOUND"
fi
echo ""
done
echo "=== Detailed key structure comparison ==="
if [ -f "apps/frontend/src/shared/i18n/locales/he/insights.json" ]; then
echo "Hebrew keys (all paths):"
jq -r 'paths(scalars) as $p | $p | join(".")' apps/frontend/src/shared/i18n/locales/he/insights.json | sort > /tmp/he_keys.txt
cat /tmp/he_keys.txt
fi
echo ""
if [ -f "apps/frontend/src/shared/i18n/locales/fr/insights.json" ]; then
echo "French keys (all paths):"
jq -r 'paths(scalars) as $p | $p | join(".")' apps/frontend/src/shared/i18n/locales/fr/insights.json | sort > /tmp/fr_keys.txt
cat /tmp/fr_keys.txt
fi
echo ""
echo "=== Key comparison ==="
if [ -f /tmp/he_keys.txt ] && [ -f /tmp/fr_keys.txt ]; then
echo "Keys in Hebrew but NOT in French:"
comm -23 /tmp/he_keys.txt /tmp/fr_keys.txt
echo ""
echo "Keys in French but NOT in Hebrew:"
comm -13 /tmp/he_keys.txt /tmp/fr_keys.txt
fiRepository: AndyMik90/Auto-Claude
Length of output: 1401
Add French translations for insights feature.
The French locale is missing apps/frontend/src/shared/i18n/locales/fr/insights.json entirely. Per coding guidelines, all new translation keys must be added to ALL language files (minimum: en/*.json and fr/*.json). Create the French insights translations file with all 32 keys present in the Hebrew and English versions.
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/fr/insights.json (create new file
corresponding to lines 1-43 of the Hebrew file), the French locale for the
insights feature is missing; add a new JSON file containing the same 32 keys
present in the Hebrew (and English) insights.json and provide correct French
translations for each key (title, subtitle, chatHistory, newChat,
noConversations, deleteConversation, deleteConversationDescription, cancel,
delete, rename, message, messages, today, yesterday, thisWeek, older,
placeholder, sendHint, stop, profileSelector (label, custom, customDescription),
tools (reading, searching, searchingCode), thinking, assistant, suggestions
(architecture, improvements, features, security), empty (title, description)).
Ensure the file is valid UTF-8 JSON, keys exactly match other locales,
punctuation and escaping match JSON rules, and run the i18n lint/validation step
to verify consistency with en/*.json.
| { | ||
| "wizard": { | ||
| "title": "אשף הגדרה", | ||
| "description": "הגדר את סביבת Auto Claude שלך בכמה שלבים פשוטים", | ||
| "helpText": "אשף זה יעזור לך להגדיר את הסביבה שלך בכמה שלבים בלבד. תוכל להגדיר את אסימון OAuth של Claude, להגדיר תכונות זיכרון וליצור את המשימה הראשונה שלך." | ||
| }, | ||
| "welcome": { | ||
| "title": "ברוכים הבאים ל-Auto Claude", | ||
| "subtitle": "בנה תוכנה באופן אוטונומי עם סוכני AI", | ||
| "getStarted": "התחל", | ||
| "skip": "דלג על ההגדרה", | ||
| "features": { | ||
| "aiPowered": { | ||
| "title": "פיתוח מבוסס AI", | ||
| "description": "צור קוד ובנה תכונות באמצעות סוכני Claude Code" | ||
| }, | ||
| "specDriven": { | ||
| "title": "זרימת עבודה מונחית מפרט", | ||
| "description": "הגדר משימות עם מפרטים ברורים ותן ל-Auto Claude לטפל ביישום" | ||
| }, | ||
| "memory": { | ||
| "title": "זיכרון והקשר", | ||
| "description": "זיכרון מתמשך בין הפעלות עם Graphiti" | ||
| }, | ||
| "parallel": { | ||
| "title": "ביצוע מקבילי", | ||
| "description": "הרץ מספר סוכנים במקביל למחזורי פיתוח מהירים יותר" | ||
| } | ||
| } | ||
| }, | ||
| "oauth": { | ||
| "title": "אימות Claude", | ||
| "description": "חבר את חשבון Claude שלך כדי להפעיל תכונות AI", | ||
| "setupTitle": "הגדר אימות Claude", | ||
| "setupDescription": "הוסף את חשבונות Claude שלך כדי להפעיל תכונות AI", | ||
| "infoMessage": "הוסף מספר מנויי Claude כדי לעבור ביניהם אוטומטית כשאתה מגיע למגבלות קצב.", | ||
| "keychainTitle": "אחסון מאובטח", | ||
| "keychainDescription": "האסימונים שלך מוצפנים באמצעות מחזיק המפתחות של המערכת שלך. ייתכן שתראה בקשת סיסמה ממערכת הפעלה - לחץ על \"אפשר תמיד\" כדי להימנע מלראות אותה שוב.", | ||
| "accountNamePlaceholder": "שם חשבון (למשל, עבודה, אישי)", | ||
| "addAccount": "הוסף", | ||
| "default": "ברירת מחדל", | ||
| "active": "פעיל", | ||
| "authenticated": "מאומת", | ||
| "needsAuth": "דורש אימות", | ||
| "authenticate": "אמת", | ||
| "setActive": "הגדר כפעיל", | ||
| "validationMessage": "יש לך לפחות חשבון Claude מאומת אחד. אתה יכול להמשיך לשלב הבא.", | ||
| "errors": { | ||
| "profileAuthSuccess": "הפרופיל אומת בהצלחה!", | ||
| "account": "חשבון:", | ||
| "authComplete": "האימות הושלם.", | ||
| "canUseProfile": "כעת תוכל להשתמש בפרופיל זה.", | ||
| "authFailedStart": "אתחול האימות נכשל:", | ||
| "tryAgain": "אנא נסה שוב.", | ||
| "profileAddFailed": "הוספת הפרופיל נכשלה. אנא נסה שוב.", | ||
| "authFailed": "אתחול האימות נכשל. אנא נסה שוב.", | ||
| "tokenSaveFailed": "שמירת האסימון נכשלה:", | ||
| "tokenSaveFailedGeneric": "שמירת האסימון נכשלה. אנא נסה שוב.", | ||
| "profileDeleteFailed": "מחיקת הפרופיל נכשלה", | ||
| "profileRenameFailed": "שינוי שם הפרופיל נכשל", | ||
| "setActiveFailed": "הגדרת הפרופיל הפעיל נכשלה" | ||
| } | ||
| }, | ||
| "firstSpec": { | ||
| "title": "צור את המשימה הראשונה שלך", | ||
| "subtitle": "תאר מה אתה רוצה לבנות ותן ל-Auto Claude לטפל בשאר", | ||
| "taskCreatorOpened": "יוצר המשימות נפתח", | ||
| "taskCreatorOpenedMessage": "מצוין! אתה יכול ליצור את המשימה הראשונה שלך עכשיו או להמשיך עם האשף. אתה תמיד יכול ליצור משימות מאוחר יותר מלוח הבקרה הראשי.", | ||
| "tipsTitle": "טיפים למשימות מעולות", | ||
| "tips": { | ||
| "beDescriptive": { | ||
| "title": "היה תיאורי", | ||
| "description": "תאר בבירור מה אתה רוצה לבנות. כלול דרישות, אילוצים והתנהגות צפויה." | ||
| }, | ||
| "startSmall": { | ||
| "title": "התחל בקטן", | ||
| "description": "התחל עם משימה ממוקדת כמו הוספת תכונה או תיקון באג. משימות קטנות יותר קלות לאימות." | ||
| }, | ||
| "includeContext": { | ||
| "title": "כלול הקשר", | ||
| "description": "ציין קבצים רלוונטיים, APIs או תבניות. ככל שתספק יותר הקשר, כך התוצאות יהיו טובות יותר." | ||
| }, | ||
| "letAiHelp": { | ||
| "title": "תן ל-AI לעזור", | ||
| "description": "ה-AI יכול לייצר כותרות ולסווג משימות. התמקד בתיאור מה אתה רוצה, לא בפרטים." | ||
| } | ||
| }, | ||
| "exampleTitle": "דוגמת תיאור משימה:", | ||
| "exampleDescription": "הוסף מתג מצב כהה לעמוד ההגדרות. זה צריך לשמור את העדפת המשתמש ב-localStorage ולהחיל את הערכה מיד ללא רענון דף. השתמש במשתני הצבע הקיימים ב-styles/theme.css.", | ||
| "openTaskCreator": "פתח יוצר משימות", | ||
| "continueMessage": "אתה יכול להמשיך עם האשף עכשיו או ליצור עוד משימות.", | ||
| "skipMessage": "אתה יכול לדלג על השלב הזה וליצור משימות מאוחר יותר מלוח הבקרה.", | ||
| "back": "חזור", | ||
| "skip": "דלג", | ||
| "continue": "המשך" | ||
| }, | ||
| "memory": { | ||
| "title": "זיכרון", | ||
| "description": "זיכרון Auto Claude עוזר לזכור הקשר לאורך הפעלות הקידוד שלך", | ||
| "whatDoesMemoryDo": "מה זיכרון עושה?", | ||
| "whatDoesMemoryDoDescription": "זיכרון שומר תגליות, דפוסים ותובנות על בסיס הקוד שלך כך שהפעלות עתידיות מתחילות עם הקשר שכבר נטען.", | ||
| "remembersPatterns": "זוכר דפוסים בין הפעלות", | ||
| "understandsCodebase": "מבין את בסיס הקוד שלך לאורך זמן", | ||
| "worksOffline": "עובד במצב לא מקוון - אין צורך בענן", | ||
| "memoryDatabase": "מסד נתוני זיכרון", | ||
| "storedIn": "שמור ב-~/.auto-claude/memories/", | ||
| "embeddingProvider": "ספק הטמעה (לחיפוש סמנטי)", | ||
| "selectEmbeddingModel": "בחר מודל הטמעה", | ||
| "noEmbeddingProvider": "אין ספק הטמעה? זיכרון עדיין עובד עם חיפוש מילות מפתח. חיפוש סמנטי הוא שדרוג.", | ||
| "databaseCreatedAutomatically": "מסד הנתונים ייווצר אוטומטית", | ||
| "databaseCreatedDescription": "זיכרון משתמש במסד נתונים מוטמע - אין צורך ב-Docker. הוא ייווצר כשתשתמש לראשונה בתכונות זיכרון.", | ||
| "back": "חזור", | ||
| "saving": "שומר...", | ||
| "saveContinue": "שמור והמשך" | ||
| }, | ||
| "completion": { | ||
| "title": "הכול מוכן!", | ||
| "subtitle": "Auto Claude מוכן לעזור לך לבנות תוכנה מדהימה", | ||
| "setupComplete": "ההגדרה הושלמה", | ||
| "setupCompleteDescription": "הסביבה שלך מוגדרת ומוכנה. אתה יכול להתחיל ליצור משימות מיד או לחקור את האפליקציה בקצב שלך.", | ||
| "whatsNext": "מה הלאה?", | ||
| "createTask": { | ||
| "title": "צור משימה", | ||
| "description": "התחל ביצירת המשימה הראשונה שלך כדי לראות את Auto Claude בפעולה.", | ||
| "action": "פתח יוצר משימות" | ||
| }, | ||
| "customizeSettings": { | ||
| "title": "התאם הגדרות", | ||
| "description": "כוון את ההעדפות שלך, הגדר אינטגרציות או הפעל מחדש את האשף הזה.", | ||
| "action": "פתח הגדרות" | ||
| }, | ||
| "exploreDocs": { | ||
| "title": "חקור תיעוד", | ||
| "description": "למד עוד על תכונות מתקדמות, שיטות עבודה מומלצות ופתרון בעיות." | ||
| }, | ||
| "finish": "סיים והתחל לבנות", | ||
| "rerunHint": "אתה תמיד יכול להפעיל מחדש את האשף הזה מהגדרות → אפליקציה" | ||
| }, | ||
| "steps": { | ||
| "welcome": "ברוכים הבאים", | ||
| "auth": "אימות", | ||
| "memory": "זיכרון", | ||
| "done": "סיום" | ||
| }, | ||
| "ollama": { | ||
| "checkingModels": "בודק מודלים של Ollama...", | ||
| "notRunning": "Ollama לא פועל", | ||
| "notRunningDescription": "הפעל Ollama כדי להשתמש במודלים מקומיים. הזיכרון עדיין יעבוד עם חיפוש מילות מפתח.", | ||
| "retry": "נסה שוב", | ||
| "installed": "מותקן", | ||
| "downloading": "מוריד...", | ||
| "download": "הורד", | ||
| "selectModel": "בחר מודל מותקן לחיפוש סמנטי. הזיכרון עובד עם חיפוש מילות מפתח גם בלי embeddings.", | ||
| "googleLightweight": "מודל embedding קל ממשקל של Google (מומלץ)", | ||
| "popularGeneral": "embeddings רב-תכליתיים פופולריים", | ||
| "mixedBreadLarge": "embeddings גדולים של MixedBread AI" | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify French onboarding.json exists and has matching structure
echo "=== Checking onboarding.json across locales ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/$locale/onboarding.json"
if [ -f "$file" ]; then
echo "✓ Found: $file"
echo " Top-level keys: $(jq -r 'keys | join(", ")' "$file" 2>/dev/null || echo "Error reading JSON")"
echo " Line count: $(wc -l < "$file")"
else
echo "✗ Missing: $file"
fi
done
echo ""
echo "=== Detailed comparison of locale files ==="
# Compare keys between en and fr if both exist
en_file="apps/frontend/src/shared/i18n/locales/en/onboarding.json"
fr_file="apps/frontend/src/shared/i18n/locales/fr/onboarding.json"
if [ -f "$en_file" ] && [ -f "$fr_file" ]; then
en_keys=$(jq -r 'keys[]' "$en_file" 2>/dev/null | sort)
fr_keys=$(jq -r 'keys[]' "$fr_file" 2>/dev/null | sort)
if [ "$en_keys" = "$fr_keys" ]; then
echo "✓ Top-level keys match between en and fr"
else
echo "✗ Top-level keys differ between en and fr"
echo "English only: $(comm -23 <(echo "$en_keys") <(echo "$fr_keys") | tr '\n' ' ')"
echo "French only: $(comm -13 <(echo "$en_keys") <(echo "$fr_keys") | tr '\n' ' ')"
fi
fiRepository: AndyMik90/Auto-Claude
Length of output: 846
French onboarding.json is incomplete and missing translation keys required for consistency.
The fr/onboarding.json file exists but is missing two top-level sections that are present in both en/onboarding.json and the new he/onboarding.json:
firstSpec(task creation guidance)ollama(embedding model selection)
Per the coding guideline requiring translation keys in ALL language files (minimum en/*.json and fr/*.json), these sections must be added to fr/onboarding.json with French translations before merging.
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/he/onboarding.json lines 1-158: the
review points out that the French locale
(apps/frontend/src/shared/i18n/locales/fr/onboarding.json) is missing two
top-level sections required for parity—firstSpec and ollama; update
fr/onboarding.json by adding both sections with all keys present in
en/onboarding.json (use the Hebrew file as reference for full key structure) and
provide accurate French translations for each string so fr/onboarding.json
matches the structure and keys of en/onboarding.json before merging.
| "competitorInsights": "מטפל בנקודות כאב של מתחרים" | ||
| }} No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Malformed JSON structure at end of file.
The file ends with }} on line 95, indicating a missing newline or formatting issue. This appears related to the formatting concern flagged in a previous review.
🔎 Suggested fix
"competitorInsights": "מטפל בנקודות כאב של מתחרים"
- }}
+ }
+}📝 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.
| "competitorInsights": "מטפל בנקודות כאב של מתחרים" | |
| }} | |
| "competitorInsights": "מטפל בנקודות כאב של מתחרים" | |
| } | |
| } |
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/he/roadmap.json around lines 94 to 95,
the file ends with an extra closing brace sequence "}}", producing malformed
JSON; open the file and change the trailing "}}" to a single closing brace "}"
(and ensure the file ends with a single newline), so the JSON object closes
correctly and the file parses.
- Added RTL text direction detection and bidirectional text handling - Implemented FormattingToolbar for rich text editing in Insights - Extended message editing capabilities with draft auto-save - Added sessionKey authentication support (browser-based, more reliable than OAuth) - Completed Hebrew translations for all UI components - Added agentTools translations for MCP server documentation - Improved Python command priority (python before py -3) - Enhanced AI response language detection and localization - Fixed text alignment for mixed RTL/LTR content Co-authored-by: Koperberg
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 31
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (8)
apps/frontend/src/preload/api/task-api.ts (1)
84-91: Use IPC_CHANNELS constant instead of hardcoded string.Line 91 uses the hardcoded string
'task:create'instead of theIPC_CHANNELS.TASK_CREATEconstant. This is inconsistent with all other methods in this file (lines 82, 94, 100, 103, etc.) and could cause IPC channel mismatches.🔎 Proposed fix
createTask: ( projectId: string, title: string, description: string, metadata?: TaskMetadata, language?: string ): Promise<IPCResult<Task>> => - ipcRenderer.invoke('task:create', projectId, title, description, metadata, language), + ipcRenderer.invoke(IPC_CHANNELS.TASK_CREATE, projectId, title, description, metadata, language),apps/frontend/src/main/python-env-manager.ts (1)
242-245: Consider applying UTF-8 environment variables to venv creation as well.The
createVenv()method spawns a Python process without the UTF-8 environment variables that were added tobootstrapPip()andinstallDeps(). For consistency and to prevent potential encoding issues during venv creation (especially on Windows), consider applying the same environment setup here.🔎 Suggested update (after applying the refactor above)
const proc = spawn(systemPython, ['-m', 'venv', venvPath], { cwd: this.autoBuildSourcePath!, - stdio: 'pipe' + stdio: 'pipe', + env: { + ...process.env, + ...this.getPythonEnv() + } });apps/frontend/src/renderer/components/context/ServiceCard.tsx (1)
37-37: Replace hardcoded 'unknown' string with translation key.The hardcoded string
'unknown'is user-facing text displayed in a Badge component and violates the coding guideline requiring all user-facing text to use translation keys.As per coding guidelines: Never use hardcoded strings in JSX/TSX files for user-facing text - always reference translation keys from
apps/frontend/src/shared/i18n/locales/.🔎 Proposed fix
- <Badge variant="outline" className={cn('capitalize text-xs', colorClass)}> - {service.type || 'unknown'} - </Badge> + <Badge variant="outline" className={cn('capitalize text-xs', colorClass)}> + {service.type || t('projectIndex.service.unknown')} + </Badge>apps/backend/core/auth.py (1)
196-208: Consider documenting SDK token type compatibility.When
ensure_claude_code_oauth_token()copies a sessionKey toCLAUDE_CODE_OAUTH_TOKEN, the environment variable name becomes misleading. While this is likely necessary for SDK compatibility, documenting this behavior would improve code clarity.💡 Suggested documentation
def ensure_claude_code_oauth_token() -> None: """ Ensure CLAUDE_CODE_OAUTH_TOKEN is set (for SDK compatibility). If not set but other auth tokens are available, copies the value to CLAUDE_CODE_OAUTH_TOKEN so the underlying SDK can use it. + + Note: This may copy non-OAuth tokens (e.g., sessionKey) to an env var + named "OAUTH_TOKEN" for SDK compatibility. The SDK accepts various + token types despite the OAuth-specific naming. """apps/frontend/src/renderer/components/project-settings/ClaudeAuthSection.tsx (1)
1-133: Implement i18n in ClaudeAuthSection component.This component contains hardcoded English strings and does not use the
useTranslation()hook, violating the i18n guidelines. While some translation keys already exist in thesettingsnamespace (projectSections.claude), the component must be refactored to use them.Required changes:
- Import
useTranslation()fromreact-i18next- Use existing translation keys from
settings:projectSections.claude.*:
sessionKeyLabel,sessionKeyDescription,sessionKeyPlaceholderoauthTokenLabel,oauthTokenDescription,oauthTokenPlaceholderoverrideGlobal- Add missing translation keys to both
en/settings.jsonandhe/settings.json:
- "Connected", "Not Connected"
- "Claude Authentication", "Claude CLI"
- "Loading configuration...", "Checking...", "Authenticated via OAuth", "Not authenticated", "Status unknown"
- "Re-authenticate", "Setup OAuth"
- "Using global token"
- Replace all hardcoded strings with
t('settings:projectSections.claude.key')callsapps/frontend/src/renderer/components/Insights.tsx (2)
608-676: Replace hardcoded task-related strings with translation keys.Lines 615, 660, 665, and 670 contain hardcoded strings ("Suggested Task", "Creating...", "Task Created", "Create Task") that should use translation keys.
🔎 Proposed fix
Add these keys to
apps/frontend/src/shared/i18n/locales/*/insights.json:{ "suggestedTask": { "title": "Suggested Task", "createButton": "Create Task", "creating": "Creating...", "created": "Task Created" } }Then update the code:
+ const { t } = useTranslation('insights'); <div className="mb-2 flex items-center gap-2"> <Sparkles className="h-4 w-4 text-primary" /> <span className="text-sm font-medium text-primary"> - Suggested Task + {t('suggestedTask.title')} </span> </div> {/* ... */} <Button size="sm" onClick={onCreateTask} disabled={isCreatingTask || taskCreated} > {isCreatingTask ? ( <> <Loader2 className="mr-2 h-4 w-4 animate-spin" /> - Creating... + {t('suggestedTask.creating')} </> ) : taskCreated ? ( <> <CheckCircle2 className="mr-2 h-4 w-4" /> - Task Created + {t('suggestedTask.created')} </> ) : ( <> <Plus className="mr-2 h-4 w-4" /> - Create Task + {t('suggestedTask.createButton')} </> )} </Button>As per coding guidelines, always use translation keys for all user-facing text.
728-771: Use i18next pluralization for "tools used" text.Line 745 contains hardcoded pluralization logic:
{tools.length} tool{tools.length !== 1 ? 's' : ''} used. This should use i18next's built-in pluralization support for proper internationalization.🔎 Proposed fix
Add pluralization keys to
apps/frontend/src/shared/i18n/locales/*/insights.json:{ "toolsUsed_one": "{{count}} tool used", "toolsUsed_other": "{{count}} tools used" }Then update the code:
function ToolUsageHistory({ tools }: ToolUsageHistoryProps) { + const { t } = useTranslation('insights'); const [expanded, setExpanded] = useState(false); // ... existing code ... return ( <div className="mt-2"> <button onClick={() => setExpanded(!expanded)} className="flex items-center gap-2 text-xs text-muted-foreground hover:text-foreground transition-colors" > <span className="flex items-center gap-1"> {/* ... icon rendering ... */} </span> - <span>{tools.length} tool{tools.length !== 1 ? 's' : ''} used</span> + <span>{t('toolsUsed', { count: tools.length })}</span> <span className="text-[10px]">{expanded ? '▲' : '▼'}</span> </button> {/* ... rest of component ... */} </div> ); }As per coding guidelines, never use hardcoded strings in JSX/TSX files for user-facing text. Additionally, i18next provides proper pluralization support that works across different languages with varying plural rules.
apps/frontend/src/main/cli-tool-manager.ts (1)
170-170: Update comment to match the new detection order.The comment mentions "py -3, python3, python" but the actual code at line 233 now uses a different order:
python,python3,py -3,py.🔎 Proposed fix
- * 4. System PATH (py -3, python3, python) + * 4. System PATH (python, python3, py -3, py)
♻️ Duplicate comments (10)
apps/frontend/src/shared/i18n/locales/he/insights.json (1)
1-68: French translation file for insights is missing.Per coding guidelines, all new translation keys must be added to ALL language files (minimum:
en/*.jsonandfr/*.json). The French localeapps/frontend/src/shared/i18n/locales/fr/insights.jsonis missing and must be created with all keys present in this Hebrew file.Based on learnings, all translation keys must exist in both English and French locale files at minimum.
apps/frontend/src/shared/i18n/locales/en/roadmap.json (1)
1-106: Missing featureDetail section and French translation file.Two issues identified:
- This English file is missing the
featureDetailsection (lines 106-115 in the Hebrew file) containing keys likedescription,rationale,complexity,impact,dependencies,userStories,acceptanceCriteria, andcompetitorInsights.- The French translation file
apps/frontend/src/shared/i18n/locales/fr/roadmap.jsonis missing entirely.Per coding guidelines, all translation keys must exist in ALL language files (minimum:
en/*.jsonandfr/*.json).🔎 Add missing featureDetail section
"delete": "Delete" - } + }, + "featureDetail": { + "description": "Description", + "rationale": "Rationale", + "complexity": "Complexity", + "impact": "Impact", + "dependencies": "Dependencies", + "userStories": "User Stories", + "acceptanceCriteria": "Acceptance Criteria", + "competitorInsights": "Addresses competitor pain points" + } }Based on learnings, all translation keys must exist in both English and French locale files at minimum.
apps/frontend/src/shared/i18n/locales/he/roadmap.json (1)
115-115: Critical: Malformed JSON - extra closing brace.Line 115 contains
}}which creates invalid JSON. The file should end with a single closing brace.🔎 Fix JSON syntax
"competitorInsights": "מטפל בנקודות כאב של מתחרים" - }} + } +}apps/frontend/src/shared/i18n/locales/en/ideation.json (1)
1-217: French translation file for ideation is missing.Per coding guidelines, all new translation keys must be added to ALL language files (minimum:
en/*.jsonandfr/*.json). The French localeapps/frontend/src/shared/i18n/locales/fr/ideation.jsonis missing and must be created.Based on learnings, all translation keys must exist in both English and French locale files at minimum.
apps/frontend/src/shared/i18n/locales/he/context.json (1)
1-113: Hebrew context translations are comprehensive.The file provides complete Hebrew translations for the context namespace including project index, memories, and GitHub sections. The structure aligns with the English version.
Per coding guidelines and a previous review, the corresponding French translation file (
fr/context.json) must also be created with French translations for all these keys.apps/frontend/src/shared/i18n/index.ts (1)
31-38: Critical: French translations still incorrectly import English files.Lines 31-38 import French resources from the English locale directory (
./locales/en/) instead of the French directory (./locales/fr/). This causes French users to see English text for these namespaces.🔎 Proposed fix
-import frChangelog from './locales/en/changelog.json'; -import frContext from './locales/en/context.json'; -import frInsights from './locales/en/insights.json'; -import frRoadmap from './locales/en/roadmap.json'; -import frIdeation from './locales/en/ideation.json'; -import frRateLimit from './locales/en/rateLimit.json'; -import frWorktrees from './locales/en/worktrees.json'; -import frAgentTools from './locales/en/agentTools.json'; +import frChangelog from './locales/fr/changelog.json'; +import frContext from './locales/fr/context.json'; +import frInsights from './locales/fr/insights.json'; +import frRoadmap from './locales/fr/roadmap.json'; +import frIdeation from './locales/fr/ideation.json'; +import frRateLimit from './locales/fr/rateLimit.json'; +import frWorktrees from './locales/fr/worktrees.json'; +import frAgentTools from './locales/fr/agentTools.json';Note: You'll also need to create the corresponding French translation files in
apps/frontend/src/shared/i18n/locales/fr/if they don't exist yet. Based on learnings, new translation keys must be added to ALL language files (minimum:en/*.jsonandfr/*.json).apps/frontend/src/shared/i18n/locales/en/settings.json (1)
438-491: Ensure French translations exist for new sections.The
projectSettings(lines 438-460) andgithubOAuth(lines 461-491) sections are new additions to the English locale. Per coding guidelines and past review comments, these keys must be added toapps/frontend/src/shared/i18n/locales/fr/settings.jsonbefore merging.Based on learnings and coding guidelines.
apps/frontend/src/shared/i18n/locales/he/tasks.json (1)
176-228: Add missing translation sections toen/tasks.jsonandfr/tasks.jsonfirst.This Hebrew translation file introduces four new top-level sections that don't exist in the required English and French locale files:
imageUpload(lines 176-182)tabs(lines 187-191)metadata(lines 215-219)buttons(lines 220-228)Per coding guidelines, translation keys must be added to ALL language files (minimum:
en/*.jsonandfr/*.json) before adding them to Hebrew. Add these sections to the English and French files first to maintain consistency across all locales.Based on coding guidelines.
apps/frontend/src/shared/i18n/locales/he/ideation.json (1)
1-217: French translation file is required.Per coding guidelines and past review comments,
apps/frontend/src/shared/i18n/locales/fr/ideation.jsonis missing and must be created with matching keys before merging this Hebrew translation.Based on coding guidelines and past review comments.
apps/frontend/src/shared/i18n/locales/en/insights.json (1)
1-68: French translation file is required.This new English insights locale file requires a corresponding
apps/frontend/src/shared/i18n/locales/fr/insights.jsonwith matching keys per coding guidelines and past review comments.Based on coding guidelines and past review comments.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (47)
apps/backend/core/auth.pyapps/backend/prompts_pkg/prompt_generator.pyapps/frontend/src/main/cli-tool-manager.tsapps/frontend/src/main/ipc-handlers/task/crud-handlers.tsapps/frontend/src/main/python-detector.tsapps/frontend/src/main/python-env-manager.tsapps/frontend/src/preload/api/task-api.tsapps/frontend/src/renderer/components/AgentTools.tsxapps/frontend/src/renderer/components/FormattingToolbar.tsxapps/frontend/src/renderer/components/Insights.tsxapps/frontend/src/renderer/components/MarkdownContent.tsxapps/frontend/src/renderer/components/RoadmapGenerationProgress.tsxapps/frontend/src/renderer/components/context/MemoriesTab.tsxapps/frontend/src/renderer/components/context/ProjectIndexTab.tsxapps/frontend/src/renderer/components/context/ServiceCard.tsxapps/frontend/src/renderer/components/context/service-sections/APIRoutesSection.tsxapps/frontend/src/renderer/components/context/service-sections/DatabaseSection.tsxapps/frontend/src/renderer/components/context/service-sections/DependenciesSection.tsxapps/frontend/src/renderer/components/context/service-sections/EnvironmentSection.tsxapps/frontend/src/renderer/components/context/service-sections/ExternalServicesSection.tsxapps/frontend/src/renderer/components/context/service-sections/MonitoringSection.tsxapps/frontend/src/renderer/components/ideation/GenerationProgressScreen.tsxapps/frontend/src/renderer/components/project-settings/ClaudeAuthSection.tsxapps/frontend/src/renderer/components/task-detail/TaskLogs.tsxapps/frontend/src/renderer/lib/rtl-utils.tsapps/frontend/src/renderer/stores/insights-store.tsapps/frontend/src/renderer/stores/task-store.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/shared/i18n/locales/en/agentTools.jsonapps/frontend/src/shared/i18n/locales/en/context.jsonapps/frontend/src/shared/i18n/locales/en/ideation.jsonapps/frontend/src/shared/i18n/locales/en/insights.jsonapps/frontend/src/shared/i18n/locales/en/roadmap.jsonapps/frontend/src/shared/i18n/locales/en/settings.jsonapps/frontend/src/shared/i18n/locales/en/tasks.jsonapps/frontend/src/shared/i18n/locales/he/agentTools.jsonapps/frontend/src/shared/i18n/locales/he/context.jsonapps/frontend/src/shared/i18n/locales/he/ideation.jsonapps/frontend/src/shared/i18n/locales/he/insights.jsonapps/frontend/src/shared/i18n/locales/he/navigation.jsonapps/frontend/src/shared/i18n/locales/he/roadmap.jsonapps/frontend/src/shared/i18n/locales/he/settings.jsonapps/frontend/src/shared/i18n/locales/he/tasks.jsonapps/frontend/src/shared/types/insights.tsapps/frontend/src/shared/types/ipc.tsapps/frontend/src/shared/types/project.tsapps/frontend/src/shared/types/settings.ts
🧰 Additional context used
📓 Path-based instructions (4)
apps/frontend/src/shared/i18n/locales/**/*.json
📄 CodeRabbit inference engine (CLAUDE.md)
Add new translation keys to ALL language files (minimum:
en/*.jsonandfr/*.json) inapps/frontend/src/shared/i18n/locales/
Files:
apps/frontend/src/shared/i18n/locales/he/context.jsonapps/frontend/src/shared/i18n/locales/he/ideation.jsonapps/frontend/src/shared/i18n/locales/he/roadmap.jsonapps/frontend/src/shared/i18n/locales/he/insights.jsonapps/frontend/src/shared/i18n/locales/en/insights.jsonapps/frontend/src/shared/i18n/locales/he/navigation.jsonapps/frontend/src/shared/i18n/locales/en/agentTools.jsonapps/frontend/src/shared/i18n/locales/he/tasks.jsonapps/frontend/src/shared/i18n/locales/he/settings.jsonapps/frontend/src/shared/i18n/locales/he/agentTools.jsonapps/frontend/src/shared/i18n/locales/en/roadmap.jsonapps/frontend/src/shared/i18n/locales/en/settings.jsonapps/frontend/src/shared/i18n/locales/en/context.jsonapps/frontend/src/shared/i18n/locales/en/tasks.jsonapps/frontend/src/shared/i18n/locales/en/ideation.json
apps/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/frontend/src/**/*.{ts,tsx}: Always use translation keys withuseTranslation()for all user-facing text in React/TypeScript frontend components - use formatnamespace:section.key(e.g.,navigation:items.githubPRs)
Never use hardcoded strings in JSX/TSX files for user-facing text - always reference translation keys fromapps/frontend/src/shared/i18n/locales/
Files:
apps/frontend/src/shared/types/insights.tsapps/frontend/src/renderer/components/context/service-sections/EnvironmentSection.tsxapps/frontend/src/renderer/components/context/ProjectIndexTab.tsxapps/frontend/src/renderer/stores/task-store.tsapps/frontend/src/renderer/components/context/service-sections/APIRoutesSection.tsxapps/frontend/src/renderer/components/context/service-sections/DependenciesSection.tsxapps/frontend/src/preload/api/task-api.tsapps/frontend/src/main/python-env-manager.tsapps/frontend/src/renderer/components/context/service-sections/DatabaseSection.tsxapps/frontend/src/renderer/components/context/MemoriesTab.tsxapps/frontend/src/main/ipc-handlers/task/crud-handlers.tsapps/frontend/src/shared/types/project.tsapps/frontend/src/shared/types/ipc.tsapps/frontend/src/renderer/lib/rtl-utils.tsapps/frontend/src/renderer/stores/insights-store.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/renderer/components/context/service-sections/ExternalServicesSection.tsxapps/frontend/src/renderer/components/context/service-sections/MonitoringSection.tsxapps/frontend/src/renderer/components/MarkdownContent.tsxapps/frontend/src/renderer/components/task-detail/TaskLogs.tsxapps/frontend/src/main/python-detector.tsapps/frontend/src/renderer/components/FormattingToolbar.tsxapps/frontend/src/shared/types/settings.tsapps/frontend/src/renderer/components/project-settings/ClaudeAuthSection.tsxapps/frontend/src/renderer/components/Insights.tsxapps/frontend/src/renderer/components/ideation/GenerationProgressScreen.tsxapps/frontend/src/renderer/components/context/ServiceCard.tsxapps/frontend/src/main/cli-tool-manager.tsapps/frontend/src/renderer/components/AgentTools.tsxapps/frontend/src/renderer/components/RoadmapGenerationProgress.tsx
apps/frontend/**/*.{ts,tsx}
⚙️ CodeRabbit configuration file
apps/frontend/**/*.{ts,tsx}: Review React patterns and TypeScript type safety.
Check for proper state management and component composition.
Files:
apps/frontend/src/shared/types/insights.tsapps/frontend/src/renderer/components/context/service-sections/EnvironmentSection.tsxapps/frontend/src/renderer/components/context/ProjectIndexTab.tsxapps/frontend/src/renderer/stores/task-store.tsapps/frontend/src/renderer/components/context/service-sections/APIRoutesSection.tsxapps/frontend/src/renderer/components/context/service-sections/DependenciesSection.tsxapps/frontend/src/preload/api/task-api.tsapps/frontend/src/main/python-env-manager.tsapps/frontend/src/renderer/components/context/service-sections/DatabaseSection.tsxapps/frontend/src/renderer/components/context/MemoriesTab.tsxapps/frontend/src/main/ipc-handlers/task/crud-handlers.tsapps/frontend/src/shared/types/project.tsapps/frontend/src/shared/types/ipc.tsapps/frontend/src/renderer/lib/rtl-utils.tsapps/frontend/src/renderer/stores/insights-store.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/renderer/components/context/service-sections/ExternalServicesSection.tsxapps/frontend/src/renderer/components/context/service-sections/MonitoringSection.tsxapps/frontend/src/renderer/components/MarkdownContent.tsxapps/frontend/src/renderer/components/task-detail/TaskLogs.tsxapps/frontend/src/main/python-detector.tsapps/frontend/src/renderer/components/FormattingToolbar.tsxapps/frontend/src/shared/types/settings.tsapps/frontend/src/renderer/components/project-settings/ClaudeAuthSection.tsxapps/frontend/src/renderer/components/Insights.tsxapps/frontend/src/renderer/components/ideation/GenerationProgressScreen.tsxapps/frontend/src/renderer/components/context/ServiceCard.tsxapps/frontend/src/main/cli-tool-manager.tsapps/frontend/src/renderer/components/AgentTools.tsxapps/frontend/src/renderer/components/RoadmapGenerationProgress.tsx
apps/backend/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
apps/backend/**/*.py: Always use the Claude Agent SDK (create_client()fromcore.client) for AI interactions - NEVER useanthropic.Anthropic()directly
Usecreate_client()fromapps/backend/core/client.pywith proper parameters:project_dir,spec_dir,model,agent_type, and optionalmax_thinking_tokens
Files:
apps/backend/prompts_pkg/prompt_generator.pyapps/backend/core/auth.py
⚙️ CodeRabbit configuration file
apps/backend/**/*.py: Focus on Python best practices, type hints, and async patterns.
Check for proper error handling and security considerations.
Verify compatibility with Python 3.12+.
Files:
apps/backend/prompts_pkg/prompt_generator.pyapps/backend/core/auth.py
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/frontend/src/shared/i18n/locales/**/*.json : Add new translation keys to ALL language files (minimum: `en/*.json` and `fr/*.json`) in `apps/frontend/src/shared/i18n/locales/`
📚 Learning: 2025-12-25T18:29:32.954Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/frontend/src/shared/i18n/locales/**/*.json : Add new translation keys to ALL language files (minimum: `en/*.json` and `fr/*.json`) in `apps/frontend/src/shared/i18n/locales/`
Applied to files:
apps/frontend/src/shared/i18n/locales/he/context.jsonapps/frontend/src/shared/i18n/locales/he/ideation.jsonapps/frontend/src/shared/i18n/locales/he/roadmap.jsonapps/frontend/src/renderer/components/context/ProjectIndexTab.tsxapps/frontend/src/renderer/components/context/service-sections/DependenciesSection.tsxapps/frontend/src/shared/i18n/locales/he/insights.jsonapps/frontend/src/shared/i18n/locales/en/insights.jsonapps/frontend/src/shared/i18n/locales/he/navigation.jsonapps/frontend/src/shared/i18n/index.tsapps/frontend/src/renderer/components/context/service-sections/ExternalServicesSection.tsxapps/frontend/src/shared/i18n/locales/en/agentTools.jsonapps/frontend/src/renderer/components/task-detail/TaskLogs.tsxapps/frontend/src/shared/i18n/locales/he/tasks.jsonapps/frontend/src/shared/i18n/locales/he/settings.jsonapps/frontend/src/shared/i18n/locales/he/agentTools.jsonapps/frontend/src/renderer/components/ideation/GenerationProgressScreen.tsxapps/frontend/src/renderer/components/context/ServiceCard.tsxapps/frontend/src/shared/i18n/locales/en/roadmap.jsonapps/frontend/src/shared/i18n/locales/en/settings.jsonapps/frontend/src/shared/i18n/locales/en/context.jsonapps/frontend/src/shared/i18n/locales/en/tasks.jsonapps/frontend/src/renderer/components/AgentTools.tsxapps/frontend/src/renderer/components/RoadmapGenerationProgress.tsxapps/frontend/src/shared/i18n/locales/en/ideation.json
📚 Learning: 2025-12-25T18:29:32.954Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/frontend/src/**/*.{ts,tsx} : Never use hardcoded strings in JSX/TSX files for user-facing text - always reference translation keys from `apps/frontend/src/shared/i18n/locales/`
Applied to files:
apps/frontend/src/shared/i18n/locales/he/context.jsonapps/frontend/src/shared/i18n/locales/he/ideation.jsonapps/frontend/src/renderer/components/context/service-sections/EnvironmentSection.tsxapps/frontend/src/renderer/components/context/ProjectIndexTab.tsxapps/frontend/src/renderer/components/context/service-sections/APIRoutesSection.tsxapps/frontend/src/renderer/components/context/service-sections/DependenciesSection.tsxapps/frontend/src/shared/i18n/locales/en/insights.jsonapps/frontend/src/renderer/components/context/service-sections/DatabaseSection.tsxapps/frontend/src/renderer/components/context/MemoriesTab.tsxapps/frontend/src/renderer/lib/rtl-utils.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/renderer/components/context/service-sections/ExternalServicesSection.tsxapps/frontend/src/renderer/components/context/service-sections/MonitoringSection.tsxapps/frontend/src/renderer/components/task-detail/TaskLogs.tsxapps/frontend/src/shared/i18n/locales/he/tasks.jsonapps/frontend/src/renderer/components/Insights.tsxapps/frontend/src/renderer/components/ideation/GenerationProgressScreen.tsxapps/frontend/src/renderer/components/context/ServiceCard.tsxapps/frontend/src/shared/i18n/locales/en/roadmap.jsonapps/frontend/src/shared/i18n/locales/en/context.jsonapps/frontend/src/renderer/components/AgentTools.tsxapps/frontend/src/renderer/components/RoadmapGenerationProgress.tsxapps/frontend/src/shared/i18n/locales/en/ideation.json
📚 Learning: 2025-12-25T18:29:32.954Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/frontend/src/**/*.{ts,tsx} : Always use translation keys with `useTranslation()` for all user-facing text in React/TypeScript frontend components - use format `namespace:section.key` (e.g., `navigation:items.githubPRs`)
Applied to files:
apps/frontend/src/shared/i18n/locales/he/context.jsonapps/frontend/src/shared/i18n/locales/he/ideation.jsonapps/frontend/src/renderer/components/context/service-sections/EnvironmentSection.tsxapps/frontend/src/renderer/components/context/ProjectIndexTab.tsxapps/frontend/src/renderer/components/context/service-sections/APIRoutesSection.tsxapps/frontend/src/renderer/components/context/service-sections/DependenciesSection.tsxapps/frontend/src/shared/i18n/locales/he/navigation.jsonapps/frontend/src/renderer/components/context/service-sections/DatabaseSection.tsxapps/frontend/src/renderer/components/context/MemoriesTab.tsxapps/frontend/src/shared/i18n/index.tsapps/frontend/src/renderer/components/context/service-sections/ExternalServicesSection.tsxapps/frontend/src/renderer/components/context/service-sections/MonitoringSection.tsxapps/frontend/src/renderer/components/task-detail/TaskLogs.tsxapps/frontend/src/shared/i18n/locales/he/tasks.jsonapps/frontend/src/shared/i18n/locales/he/settings.jsonapps/frontend/src/renderer/components/Insights.tsxapps/frontend/src/renderer/components/ideation/GenerationProgressScreen.tsxapps/frontend/src/renderer/components/context/ServiceCard.tsxapps/frontend/src/shared/i18n/locales/en/roadmap.jsonapps/frontend/src/shared/i18n/locales/en/context.jsonapps/frontend/src/renderer/components/AgentTools.tsxapps/frontend/src/renderer/components/RoadmapGenerationProgress.tsxapps/frontend/src/shared/i18n/locales/en/ideation.json
📚 Learning: 2025-12-25T18:29:32.954Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Create spec directory structure with: `spec.md`, `requirements.json`, `context.json`, `implementation_plan.json`, `qa_report.md`, and optional `QA_FIX_REQUEST.md`
Applied to files:
apps/backend/prompts_pkg/prompt_generator.py
📚 Learning: 2025-12-25T18:29:32.954Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/backend/agents/{qa_reviewer,qa_fixer}.py : QA agents should use Electron MCP tools like `click_by_text`, `fill_input`, `take_screenshot`, and `get_page_structure` for automated frontend testing
Applied to files:
apps/frontend/src/renderer/components/AgentTools.tsx
📚 Learning: 2025-12-25T18:29:32.954Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/backend/agents/{qa_reviewer,qa_fixer}.py : For frontend bug fixes and feature implementations, use the Electron MCP server for automated E2E testing when the app is running with `--remote-debugging-port=9222`
Applied to files:
apps/frontend/src/renderer/components/AgentTools.tsx
📚 Learning: 2025-12-25T18:29:32.954Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/backend/.env* : Enable Electron MCP in `apps/backend/.env` with `ELECTRON_MCP_ENABLED=true` and `ELECTRON_DEBUG_PORT=9222` to allow QA agents to interact with running Electron app
Applied to files:
apps/frontend/src/renderer/components/AgentTools.tsx
🧬 Code graph analysis (11)
apps/frontend/src/renderer/components/context/ProjectIndexTab.tsx (2)
.design-system/src/components/Button.tsx (1)
Button(10-44).design-system/src/components/Card.tsx (1)
Card(10-24)
apps/frontend/src/renderer/stores/task-store.ts (1)
apps/frontend/src/renderer/components/settings/utils/hookProxyFactory.ts (1)
settings(15-15)
apps/frontend/src/renderer/components/context/MemoriesTab.tsx (2)
.design-system/src/components/Badge.tsx (1)
Badge(9-27).design-system/src/components/Input.tsx (1)
Input(4-24)
apps/frontend/src/renderer/stores/insights-store.ts (1)
apps/frontend/src/shared/types/insights.ts (1)
InsightsChatStatus(217-221)
apps/frontend/src/renderer/components/context/service-sections/ExternalServicesSection.tsx (1)
.design-system/src/lib/icons.ts (1)
ChevronRight(23-23)
apps/frontend/src/renderer/components/MarkdownContent.tsx (2)
.design-system/src/lib/utils.ts (1)
cn(4-6)apps/frontend/src/renderer/lib/rtl-utils.ts (1)
getTextDirection(71-73)
apps/frontend/src/renderer/components/task-detail/TaskLogs.tsx (2)
.design-system/src/components/Badge.tsx (1)
Badge(9-27).design-system/src/lib/icons.ts (1)
ChevronRight(23-23)
apps/frontend/src/renderer/components/project-settings/ClaudeAuthSection.tsx (1)
apps/frontend/src/renderer/components/settings/utils/hookProxyFactory.ts (1)
envConfig(23-23)
apps/frontend/src/renderer/components/Insights.tsx (4)
apps/frontend/src/renderer/stores/insights-store.ts (3)
useInsightsStore(60-241)sendMessage(280-308)stopInsights(401-416)apps/frontend/src/renderer/components/FormattingToolbar.tsx (3)
handleFormattingShortcut(163-223)FormatType(15-25)FormattingToolbar(45-72)apps/frontend/src/renderer/lib/rtl-utils.ts (2)
getTextDirection(71-73)getDirAttribute(99-114)apps/frontend/src/renderer/components/MarkdownContent.tsx (1)
MarkdownContent(121-195)
apps/frontend/src/renderer/components/ideation/GenerationProgressScreen.tsx (2)
.design-system/src/components/Badge.tsx (1)
Badge(9-27).design-system/src/components/Button.tsx (1)
Button(10-44)
apps/frontend/src/renderer/components/RoadmapGenerationProgress.tsx (4)
apps/frontend/src/renderer/components/terminal/types.ts (1)
PHASE_CONFIG(36-44).design-system/src/lib/icons.ts (1)
Sparkles(33-33).design-system/src/lib/utils.ts (1)
cn(4-6).design-system/src/components/Button.tsx (1)
Button(10-44)
🪛 Biome (2.1.2)
apps/frontend/src/shared/i18n/locales/he/ideation.json
[error] 75-75: The key generation was already declared.
This where a duplicated key was declared again.
If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.
(lint/suspicious/noDuplicateObjectKeys)
apps/frontend/src/renderer/components/MarkdownContent.tsx
[error] 178-178: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
apps/frontend/src/renderer/components/FormattingToolbar.tsx
[error] 121-121: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 127-127: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 133-133: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
apps/frontend/src/shared/i18n/locales/en/tasks.json
[error] 173-173: The key tabs was already declared.
This where a duplicated key was declared again.
If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.
(lint/suspicious/noDuplicateObjectKeys)
apps/frontend/src/shared/i18n/locales/en/ideation.json
[error] 54-54: The key generation was already declared.
This where a duplicated key was declared again.
If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.
(lint/suspicious/noDuplicateObjectKeys)
🔇 Additional comments (44)
apps/frontend/src/main/ipc-handlers/task/crud-handlers.ts (2)
38-39: LGTM: Language parameter added correctly.The optional
languageparameter is properly typed and will enable language-aware task creation.
168-169: Good default language fallback.Setting
preferred_languageto 'en' when no language is provided ensures the AI always has a language preference in the requirements.apps/frontend/src/shared/types/ipc.ts (2)
135-135: LGTM: Type signature correctly extended.The
languageparameter is properly typed as optional, maintaining backward compatibility.
528-528: LGTM: Insights control flow API additions.The new
stopInsightsmethod andonInsightsStoppedlistener correctly extend the Insights API surface for stopping insights sessions.Also applies to: 540-542
apps/frontend/src/renderer/stores/task-store.ts (1)
211-215: Language preference correctly wired from settings.The implementation properly retrieves the current language from user settings and passes it to the task creation API. If settings retrieval fails,
languagewill beundefined, which is safe since the backend defaults to 'en'.apps/frontend/src/preload/api/task-api.ts (1)
24-26: LGTM: Interface correctly extended.The
languageparameter is properly added to thecreateTaskmethod signature with correct optional typing.apps/frontend/src/renderer/components/context/service-sections/DependenciesSection.tsx (1)
3-3: LGTM! Proper i18n setup.The import and hook initialization follow the correct pattern for internationalization. Using the 'context' namespace helps organize translation keys logically.
Also applies to: 16-16
apps/frontend/src/renderer/components/context/ServiceCard.tsx (1)
2-2: LGTM! i18n integration properly implemented.The useTranslation hook is correctly imported and initialized with the 'context' namespace, following React i18next best practices.
Also applies to: 24-24
apps/frontend/src/renderer/components/context/service-sections/EnvironmentSection.tsx (1)
3-3: LGTM - Clean i18n integration.The import and hook initialization follow React i18n best practices, using the appropriate 'context' namespace.
Also applies to: 17-17
apps/frontend/src/renderer/components/context/service-sections/APIRoutesSection.tsx (1)
3-3: LGTM!The
useTranslationhook is correctly imported and initialized with the'context'namespace, which aligns with this component's location in the context service sections.Also applies to: 17-17
apps/frontend/src/renderer/components/RoadmapGenerationProgress.tsx (4)
225-228: LGTM!The translation key pattern
generation.${phase}andgeneration.${phase}Descriptionis clean and consistent. The dynamic key construction correctly maps phase values to their corresponding translations.
286-289: LGTM!Button and tooltip text are properly internationalized with appropriate loading state handling (
generation.stoppingvsgeneration.stop).
97-98: LGTM!The
useTranslationhook is correctly placed at the top of the component, following React hooks rules. The namespace'roadmap'is consistently used throughout.
195-198: Add missing French translation file for roadmap namespace.The component uses
generation.progress,generation.stop, andgeneration.stoppingkeys from theroadmapnamespace. While these keys exist inen/roadmap.jsonandhe/roadmap.json, per the project requirements, translation keys must be added to all supported language files (minimumenandfr). Thefr/roadmap.jsonfile is missing and must be created with all required generation keys to match the English and Hebrew translations.⛔ Skipped due to learnings
Learnt from: CR Repo: AndyMik90/Auto-Claude PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-25T18:29:32.954Z Learning: Applies to apps/frontend/src/shared/i18n/locales/**/*.json : Add new translation keys to ALL language files (minimum: `en/*.json` and `fr/*.json`) in `apps/frontend/src/shared/i18n/locales/`Learnt from: CR Repo: AndyMik90/Auto-Claude PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-25T18:29:32.954Z Learning: Applies to apps/frontend/src/**/*.{ts,tsx} : Always use translation keys with `useTranslation()` for all user-facing text in React/TypeScript frontend components - use format `namespace:section.key` (e.g., `navigation:items.githubPRs`)Learnt from: CR Repo: AndyMik90/Auto-Claude PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-25T18:29:32.954Z Learning: Applies to apps/frontend/src/**/*.{ts,tsx} : Never use hardcoded strings in JSX/TSX files for user-facing text - always reference translation keys from `apps/frontend/src/shared/i18n/locales/`apps/backend/core/auth.py (1)
97-100: Docstring accurately reflects the new priority order.The updated documentation clearly describes the authentication token resolution order with sessionKey as the primary source.
Note: Validation concerns for sessionKey are addressed in the comment for lines 16-22.
apps/frontend/src/shared/types/settings.ts (1)
229-230: LGTM! Clear and consistent authentication type definitions.The addition of
claudeSessionKeyandclaudeOAuthTokenfields follows a consistent pattern across the settings types. The comments clearly indicate that sessionKey is the recommended approach, and both fields are appropriately optional for backward compatibility.Also applies to: 272-273
apps/frontend/src/shared/types/project.ts (1)
276-277: LGTM! Consistent credential field additions.The addition of
claudeSessionKeyand positioning it beforeclaudeOAuthTokenappropriately reflects the recommended authentication method. The comments provide clear guidance for implementers.apps/frontend/src/renderer/components/project-settings/ClaudeAuthSection.tsx (1)
102-107: Verify consistent empty-string behavior for global token override.The logic shows an empty string for the input when
claudeTokenIsGlobalis true (for security), but ensure this doesn't cause confusion if users expect to see a masked version of the global value. The placeholders correctly indicate "Enter to override", which should be sufficient.Consider adding a help tooltip or link explaining what "global token" means and how to manage it, especially for new users who may not understand the override concept.
Also applies to: 119-124
apps/frontend/src/renderer/components/context/service-sections/MonitoringSection.tsx (2)
3-3: LGTM - Correct i18next import.The import follows the standard pattern for react-i18next integration.
16-16: LGTM - Proper hook initialization.The
useTranslationhook with the 'context' namespace is correctly initialized and follows React best practices.apps/frontend/src/renderer/components/context/service-sections/DatabaseSection.tsx (1)
3-3: LGTM! Clean i18n integration.The useTranslation hook is properly initialized with the 'context' namespace, which correctly matches this component's location in the context sections.
Also applies to: 17-17
apps/frontend/src/renderer/components/context/service-sections/ExternalServicesSection.tsx (2)
3-3: LGTM: i18n integration correctly implemented.The component properly initializes
useTranslation('context')and uses the translation function throughout.Also applies to: 17-17
33-33: LGTM: All user-facing text properly localized.All hardcoded strings have been replaced with translation keys following the required
namespace:section.keyformat (e.g.,t('projectIndex.sections.externalServices')).As per coding guidelines, all user-facing text now references translation keys from locale files.
Also applies to: 40-40, 53-53, 66-66, 79-79
apps/frontend/src/shared/types/insights.ts (1)
183-185: LGTM: Optional properties correctly added for message editing.The addition of
edited?: booleanandeditedAt?: Dateas optional properties safely extends theInsightsChatMessageinterface to support the new editing functionality without breaking existing code.apps/frontend/src/renderer/components/context/ProjectIndexTab.tsx (2)
2-2: LGTM: i18n integration correctly implemented.The component properly imports and initializes
useTranslation('context')for the context namespace.Also applies to: 26-26
34-189: LGTM: Comprehensive localization of all UI text.All user-facing text has been correctly replaced with translation keys using the
namespace:section.keyformat. The implementation includes:
- Header titles and descriptions
- Button labels and tooltips
- Error, loading, and empty states
- Section headings (Overview, Services, Infrastructure, Conventions)
- Dynamic content with proper pluralization
As per coding guidelines, all hardcoded strings have been properly replaced with translation keys from the context namespace.
apps/frontend/src/renderer/components/context/MemoriesTab.tsx (1)
15-16: LGTM! Comprehensive i18n implementation.The component correctly uses the
useTranslation('context')hook and all user-facing strings are now translated using thet()function with proper namespace-prefixed keys. The translation key structure follows thenamespace:section.keyconvention as required by the coding guidelines.Also applies to: 40-40, 64-64, 69-69, 74-74, 83-86, 91-91, 97-99, 109-109, 113-113, 127-127, 137-137, 153-153, 166-166
apps/frontend/src/shared/i18n/index.ts (1)
40-56: Hebrew locale integration looks correct.The Hebrew imports (Lines 40-56) correctly reference
./locales/he/paths, and the Hebrew resources are properly wired into theresourcesobject (Lines 97-114). The namespace registration in thensarray at Line 124 includes all the new namespaces.Also applies to: 97-114
apps/frontend/src/renderer/stores/insights-store.ts (5)
57-58: Draft persistence implementation looks good.The
getDraftKeyhelper andsetDraftMessagemethod correctly implement localStorage-based draft persistence with proper error handling via try-catch. The draft is keyed byprojectIdwhich allows separate drafts per project.Also applies to: 84-95
99-117: Message editing implementation is clean.The
editMessagemethod correctly:
- Returns early if no session exists
- Marks edited messages with
edited: trueandeditedAttimestamp- Resets
editingMessageIdafter edit- Updates session's
updatedAttimestamp
270-277: Draft loading on session load.Draft loading is wrapped in try-catch which is good for resilience. However, note that
setDraftMessagewill re-save the loaded draft back to localStorage (since it auto-saves). This is harmless but slightly redundant.
398-416: Stop insights implementation looks correct.The
stopInsightsfunction properly:
- Calls the IPC method to stop the backend process
- Clears streaming state on success
- Resets tool state and status to idle
- Returns boolean success indicator
494-510: IPC stopped listener properly integrated.The
onInsightsStoppedlistener correctly resets all streaming-related state and the cleanup function properly unsubscribes from all listeners including the newunsubStopped.apps/frontend/src/shared/i18n/locales/he/navigation.json (1)
1-32: Hebrew navigation translations complete with full French locale parity.The file provides translations for all navigation sections, items, actions, tooltips, and messages with consistent key structure. Verification confirms the French locale (
fr/navigation.json) contains all matching keys with no discrepancies.apps/frontend/src/shared/i18n/locales/en/agentTools.json (1)
1-136: Ensure French translation exists for agentTools.This new English locale file for agentTools must have a corresponding French translation file at
apps/frontend/src/shared/i18n/locales/fr/agentTools.jsonwith matching keys per coding guidelines.Based on coding guidelines.
apps/frontend/src/renderer/components/ideation/GenerationProgressScreen.tsx (5)
2-2: LGTM: Proper i18n integration.The component correctly implements internationalization by importing
useTranslationfrom react-i18next and initializing it with theideationnamespace. This follows the coding guidelines for React/TypeScript frontend components.Based on coding guidelines.
Also applies to: 52-52
99-127: LGTM: Hardcoded strings replaced with translation keys.All user-facing strings in the header section are properly localized using translation keys (
generation.title,generation.complete,generation.inProgress,generation.hideLogs,generation.showLogs,generation.stopping,generation.stop,generation.stopGeneration). This follows the coding guideline to always use translation keys for user-facing text.Based on coding guidelines.
150-150: LGTM: Dynamic type translation with proper key transformation.The code correctly translates ideation type labels using
t(\types.${type.replace(/_/g, '-')}`), which properly converts underscore-separated type names (e.g.,code_improvements) to dash-separated translation keys (e.g.,code-improvements`) as expected by the locale files.Also applies to: 199-199
60-71: LGTM: Robust stop handler with error handling.The
handleStopClickfunction properly implements:
- Double-click prevention using
isStoppingstate- Async/await error handling with try-catch
- Console error logging for debugging
- State cleanup in finally block
This is a solid implementation that prevents race conditions during the stop operation.
1-270: Verify translation dependencies before merging.This component relies on the
ideationnamespace. Before merging:
- Fix the duplicate
generationkey inhe/ideation.json(lines 54-81 and 164-176)- Create
fr/ideation.jsonwith matching keys per coding guidelinesWithout these fixes, the component will fail to display translated text correctly for Hebrew (due to data loss from duplicate key) and French (due to missing translations).
Based on coding guidelines and past review comments.
apps/frontend/src/renderer/components/task-detail/TaskLogs.tsx (3)
2-2: LGTM: Proper i18n integration in both components.Both the
TaskLogscomponent (line 118) and the nestedPhaseLogSectioncomponent (line 176) correctly initialize theuseTranslationhook with thetasksnamespace. This follows the coding guidelines for React/TypeScript frontend components.Based on coding guidelines.
Also applies to: 118-118, 176-176
156-157: LGTM: Comprehensive localization of user-facing text.All user-facing strings have been properly replaced with translation keys:
- Empty state messages:
logs.noLogs,logs.loadingLogs- Status badges:
execution.labels.interrupted,labels.running,execution.phases.complete,execution.phases.failed,labels.pending- Phase labels:
phaseLabels.${phase}with dynamic lookup- Pluralization: Correctly uses
logs.entryvslogs.entriesbased on countThis implementation follows the coding guideline to never use hardcoded strings for user-facing text.
Based on coding guidelines.
Also applies to: 188-216, 244-247
371-376: LGTM: Localized collapsible output controls.The show/hide output toggle buttons correctly use translation keys (
logs.hideOutputandlogs.showOutput), ensuring these UI controls are properly localized.Based on coding guidelines.
apps/frontend/src/main/python-detector.ts (1)
89-89: Excellent consistency withcli-tool-manager.ts.The Python detection order change is properly coordinated between this file and
cli-tool-manager.ts(line 233). This ensures consistent Python selection behavior across both detection paths.
| # Auto Claude is designed to use Claude Code OAuth tokens or browser session keys. | ||
| # This prevents silent billing to user's API credits when OAuth fails. | ||
| AUTH_TOKEN_ENV_VARS = [ | ||
| "CLAUDE_SESSION_KEY", # Browser sessionKey (most reliable, same as browser extension) | ||
| "CLAUDE_CODE_OAUTH_TOKEN", # OAuth token from Claude Code CLI | ||
| "ANTHROPIC_AUTH_TOKEN", # CCR/proxy token (for enterprise setups) | ||
| ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, read the auth.py file to understand the full context
cat -n apps/backend/core/auth.py | head -100Repository: AndyMik90/Auto-Claude
Length of output: 3811
🏁 Script executed:
# Search for sessionKey validation patterns in the codebase
rg -n 'sessionKey|CLAUDE_SESSION_KEY' --type=py -A 2 -B 2Repository: AndyMik90/Auto-Claude
Length of output: 2886
🏁 Script executed:
# Search for OAuth token validation patterns
rg -n 'sk-ant-oat01-|CLAUDE_CODE_OAUTH_TOKEN' --type=py -A 2 -B 2Repository: AndyMik90/Auto-Claude
Length of output: 4916
🏁 Script executed:
# Look for any documentation or comments about reliability or security model
rg -n 'most reliable|sessionKey|browser session|security' --type=py apps/backend/core/Repository: AndyMik90/Auto-Claude
Length of output: 1958
🏁 Script executed:
# Check if there's a validate_ function or pattern for auth tokens
rg -n 'def validate.*token|def.*validate.*auth' --type=pyRepository: AndyMik90/Auto-Claude
Length of output: 162
🏁 Script executed:
# Read lines 92-130 to see full get_auth_token implementation
sed -n '92,130p' apps/backend/core/auth.pyRepository: AndyMik90/Auto-Claude
Length of output: 1285
🏁 Script executed:
# Check the _validate_oauth_token function
cat -n apps/backend/runners/ai_analyzer/claude_client.py | sed -n '35,50p'Repository: AndyMik90/Auto-Claude
Length of output: 652
Add sessionKey validation and document security model.
sessionKey is now the highest-priority authentication source, but unlike OAuth tokens (validated at line 82 in get_token_from_keychain()), get_auth_token() accepts any non-empty token without format validation. This creates inconsistent validation: OAuth tokens require the sk-ant-oat01- prefix, but sessionKeys bypass all checks.
Issues:
get_auth_token()returns any token without type-specific validation—invalid sessionKeys are silently accepted if non-empty.- The claim that sessionKey is "most reliable" (lines 19, 97, 144) lacks documentation or justification.
- Security properties of browser sessionKeys (expiration, scope, permissions) are not explained—they differ from OAuth tokens but this isn't documented.
ensure_claude_code_oauth_token()copies sessionKeys toCLAUDE_CODE_OAUTH_TOKENenv var (line 208), which is misleading naming.
Consider adding format validation for sessionKey similar to the OAuth token check, and document why sessionKey is preferred and its security model.
🤖 Prompt for AI Agents
In apps/backend/core/auth.py around lines 16 to 22, get_auth_token currently
accepts any non-empty sessionKey and treats it as highest priority without
format validation or documentation; update the function and surrounding code to
(1) add explicit format/structure validation for sessionKey (mirror the OAuth
token prefix check or use a documented regex) and reject or log malformed
values, (2) add clear inline comments and docstring text explaining why
sessionKey is preferred (reliability tradeoffs) and the sessionKey security
model (expiration, scope, and permissions compared to OAuth tokens), and (3)
stop reusing the CLAUDE_CODE_OAUTH_TOKEN env var for sessionKeys—either write
sessionKeys to a separate env var or avoid copying them and update
ensure_claude_code_oauth_token to preserve correct naming and semantics so token
types are not conflated.
| "No authentication token found.\n\n" | ||
| "Auto Claude supports multiple authentication methods:\n" | ||
| "1. Browser sessionKey (recommended - most reliable)\n" | ||
| "2. Claude Code OAuth token\n" | ||
| "Direct API keys (ANTHROPIC_API_KEY) are not supported.\n\n" | ||
| ) | ||
| # Provide platform-specific guidance | ||
| if platform.system() == "Darwin": | ||
| error_msg += ( | ||
| "To authenticate:\n" | ||
| " 1. Run: claude setup-token\n" | ||
| " 2. The token will be saved to macOS Keychain automatically\n\n" | ||
| "Or set CLAUDE_CODE_OAUTH_TOKEN in your .env file." | ||
| " Option 1 (Recommended): Copy sessionKey from browser\n" | ||
| " - Open claude.ai in browser\n" | ||
| " - Open DevTools (F12) → Application → Cookies\n" | ||
| " - Copy 'sessionKey' value\n" | ||
| " - Set CLAUDE_SESSION_KEY in your .env file\n\n" | ||
| " Option 2: Use OAuth token\n" | ||
| " - Run: claude setup-token\n" | ||
| " - Token will be saved to macOS Keychain automatically\n" | ||
| " - Or set CLAUDE_CODE_OAUTH_TOKEN in your .env file" | ||
| ) | ||
| else: | ||
| error_msg += ( | ||
| "To authenticate:\n" | ||
| " 1. Run: claude setup-token\n" | ||
| " 2. Set CLAUDE_CODE_OAUTH_TOKEN in your .env file" | ||
| " Option 1 (Recommended): Copy sessionKey from browser\n" | ||
| " - Open claude.ai in browser\n" | ||
| " - Open DevTools (F12) → Application → Cookies\n" | ||
| " - Copy 'sessionKey' value\n" | ||
| " - Set CLAUDE_SESSION_KEY in your .env file\n\n" | ||
| " Option 2: Use OAuth token\n" | ||
| " - Run: claude setup-token\n" | ||
| " - Set CLAUDE_CODE_OAUTH_TOKEN in your .env file" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Add security warnings to sessionKey instructions.
The expanded error messages significantly improve UX by providing clear, platform-specific authentication instructions. However, the instructions guide users to extract browser session cookies without warning about security implications.
Suggested improvement:
Add a brief security note when recommending sessionKey extraction:
error_msg += (
"To authenticate:\n"
" Option 1 (Recommended): Copy sessionKey from browser\n"
" - Open claude.ai in browser\n"
" - Open DevTools (F12) → Application → Cookies\n"
" - Copy 'sessionKey' value\n"
- " - Set CLAUDE_SESSION_KEY in your .env file\n\n"
+ " - Set CLAUDE_SESSION_KEY in your .env file\n"
+ " - ⚠️ Keep this key secure - treat it like a password\n\n"The improved error messages and authentication guidance are excellent.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/backend/core/auth.py around lines 142 to 173, the sessionKey extraction
instructions lack any security warnings; add a concise security note to both the
macOS and non-macOS instruction blocks immediately after the "To authenticate:"
header (or before step list) that warns users about the sensitivity of
sessionKey: advise using a private/personal device, never sharing/pasting the
sessionKey in public logs or repos, storing it securely (e.g., environment
variables or OS keychain), and deleting/rotating the key after use; also add a
brief recommendation to prefer the OAuth token method if users are unsure about
security.
| lang_names = { | ||
| "he": "Hebrew (עברית)", | ||
| "ar": "Arabic (العربية)", | ||
| "es": "Spanish (Español)", | ||
| "fr": "French (Français)", | ||
| "de": "German (Deutsch)", | ||
| "zh": "Chinese (中文)", | ||
| "ja": "Japanese (日本語)", | ||
| "ko": "Korean (한국어)", | ||
| "ru": "Russian (Русский)", | ||
| "pt": "Portuguese (Português)" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider extracting language mapping to module-level constant.
The language name mapping is defined inline within the function. Moving it to a module-level constant would improve maintainability and enable reuse if other functions need language name lookups.
🔎 Proposed refactor
At the top of the file (after imports):
# Language code to human-readable name mapping
LANGUAGE_NAMES = {
"he": "Hebrew (עברית)",
"ar": "Arabic (العربية)",
"es": "Spanish (Español)",
"fr": "French (Français)",
"de": "German (Deutsch)",
"zh": "Chinese (中文)",
"ja": "Japanese (日本語)",
"ko": "Korean (한국어)",
"ru": "Russian (Русский)",
"pt": "Portuguese (Português)",
}Then in the function:
preferred_lang = requirements.get("preferred_language")
if preferred_lang and preferred_lang != "en":
- # Map language codes to readable names
- lang_names = {
- "he": "Hebrew (עברית)",
- "ar": "Arabic (العربية)",
- "es": "Spanish (Español)",
- "fr": "French (Français)",
- "de": "German (Deutsch)",
- "zh": "Chinese (中文)",
- "ja": "Japanese (日本語)",
- "ko": "Korean (한국어)",
- "ru": "Russian (Русский)",
- "pt": "Portuguese (Português)"
- }
- lang_name = lang_names.get(preferred_lang, preferred_lang.upper())
+ lang_name = LANGUAGE_NAMES.get(preferred_lang, preferred_lang.upper())
language_instruction = f"\n\n**IMPORTANT:** Write all your progress messages, status updates, and explanations in {lang_name}. The user interface language is set to {lang_name}.\n"Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/backend/prompts_pkg/prompt_generator.py around lines 67 to 78, the
language name mapping is defined inline inside the function; move this
dictionary to a module-level constant (e.g., LANGUAGE_NAMES) directly after the
imports so it can be reused and maintained centrally, then replace the inline
dict in the function with a reference to that constant (use
LANGUAGE_NAMES.get(code, code) or similar if fallback behavior is needed).
| const candidates = | ||
| process.platform === 'win32' | ||
| ? ['py -3', 'python', 'python3', 'py'] | ||
| ? ['python', 'python3', 'py -3', 'py'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, locate the file and examine the area around line 233
find . -name "cli-tool-manager.ts" -type f 2>/dev/nullRepository: AndyMik90/Auto-Claude
Length of output: 109
🏁 Script executed:
# Also search for python-detector.ts
find . -name "python-detector.ts" -type f 2>/dev/nullRepository: AndyMik90/Auto-Claude
Length of output: 108
🏁 Script executed:
# Check if the files exist in the repository
git ls-files | grep -E "(cli-tool-manager|python-detector)" | head -20Repository: AndyMik90/Auto-Claude
Length of output: 149
🏁 Script executed:
# Check the size of the files before reading
wc -l apps/frontend/src/main/cli-tool-manager.ts
wc -l apps/frontend/src/main/python-detector.tsRepository: AndyMik90/Auto-Claude
Length of output: 157
🏁 Script executed:
# Read the relevant section of cli-tool-manager.ts around line 233
sed -n '220,250p' apps/frontend/src/main/cli-tool-manager.tsRepository: AndyMik90/Auto-Claude
Length of output: 972
🏁 Script executed:
# Read the relevant section of python-detector.ts around line 89
sed -n '75,105p' apps/frontend/src/main/python-detector.tsRepository: AndyMik90/Auto-Claude
Length of output: 1099
🏁 Script executed:
# Search for version validation (3.10+) mentioned in the comment
rg -n "3\.10|version.*validat|validat.*version" apps/frontend/src/main/cli-tool-manager.ts apps/frontend/src/main/python-detector.tsRepository: AndyMik90/Auto-Claude
Length of output: 3053
🏁 Script executed:
# Search for documentation or comments about Python detection strategy
rg -n -C5 "detect|candidate|priorit" apps/frontend/src/main/cli-tool-manager.ts apps/frontend/src/main/python-detector.ts | head -80Repository: AndyMik90/Auto-Claude
Length of output: 5776
🏁 Script executed:
# Check if there are any README or documentation files mentioning Python setup
find . -type f \( -name "README*" -o -name "*.md" \) | xargs rg -l "Python.*detect|python.*windows" 2>/dev/null | head -10Repository: AndyMik90/Auto-Claude
Length of output: 79
🏁 Script executed:
# Look for test files related to python detection
find . -name "*.test.ts" -o -name "*.spec.ts" | xargs grep -l "python\|Python" 2>/dev/null | head -5Repository: AndyMik90/Auto-Claude
Length of output: 151
🏁 Script executed:
# Check the CHANGELOG for information about Python detection changes
head -200 CHANGELOG.md | grep -A 10 -B 2 -i "python\|detect"Repository: AndyMik90/Auto-Claude
Length of output: 3630
🏁 Script executed:
# Also look for any comments in the code about why the order was changed
rg -n "py -3|python3.*python|priorit" apps/frontend/src/main/cli-tool-manager.ts -B 3 -A 3Repository: AndyMik90/Auto-Claude
Length of output: 1551
🏁 Script executed:
# Check git history to see what the change was and when
git log --oneline --all -- apps/frontend/src/main/cli-tool-manager.ts apps/frontend/src/main/python-detector.ts | head -20Repository: AndyMik90/Auto-Claude
Length of output: 890
🏁 Script executed:
# Look for the specific commit that changed the Python detection order
git log -p --all -- apps/frontend/src/main/cli-tool-manager.ts | grep -A 20 -B 5 "python.*python3.*py -3" | head -50Repository: AndyMik90/Auto-Claude
Length of output: 47
🏁 Script executed:
# Check the specific commit that improved CLI tool detection
git show aaa8313 -- apps/frontend/src/main/cli-tool-manager.ts apps/frontend/src/main/python-detector.ts | grep -A 30 -B 5 "candidates\|python.*python3"Repository: AndyMik90/Auto-Claude
Length of output: 47
🏁 Script executed:
# Also check commit d51f456 about CLI tool path management
git show d51f456 -- apps/frontend/src/main/cli-tool-manager.ts | grep -A 30 -B 5 "candidates\|python.*python3" | head -80Repository: AndyMik90/Auto-Claude
Length of output: 2473
🏁 Script executed:
# Check what the comment says in python-detector.ts about the detection order
sed -n '86,95p' apps/frontend/src/main/python-detector.tsRepository: AndyMik90/Auto-Claude
Length of output: 403
🏁 Script executed:
# Check the entire comment block for detectPython in cli-tool-manager.ts
sed -n '163,175p' apps/frontend/src/main/cli-tool-manager.tsRepository: AndyMik90/Auto-Claude
Length of output: 418
Update the documentation comment to reflect the new Python detection order.
The code consistently implements ['python', 'python3', 'py -3', 'py'] on Windows across both cli-tool-manager.ts and python-detector.ts, with proper version validation (3.10+). However, the comment in cli-tool-manager.ts at line 170 still references the old order: "4. System PATH (py -3, python3, python)". Update this comment to match the current implementation: "4. System PATH (python, python3, py -3, py)".
🤖 Prompt for AI Agents
In apps/frontend/src/main/cli-tool-manager.ts around line 170 (and ensure
consistency near line 233), the inline documentation comment still states the
old Windows Python detection order ("4. System PATH (py -3, python3, python)");
update that comment to the new order "4. System PATH (python, python3, py -3,
py)" so it matches the implemented detection array ['python', 'python3', 'py
-3', 'py'] and its version validation behavior.
| "categories": { | ||
| "feature": "Feature", | ||
| "bug_fix": "Bug Fix", | ||
| "refactoring": "Refactoring", | ||
| "documentation": "Docs", | ||
| "security": "Security", | ||
| "performance": "Performance", | ||
| "ui_ux": "UI/UX", | ||
| "infrastructure": "Infrastructure", | ||
| "testing": "Testing" | ||
| }, | ||
| "complexity": { | ||
| "trivial": "Trivial", | ||
| "small": "Small", | ||
| "medium": "Medium", | ||
| "large": "Large", | ||
| "complex": "Complex" | ||
| }, | ||
| "impact": { | ||
| "low": "Low Impact", | ||
| "medium": "Medium Impact", | ||
| "high": "High Impact", | ||
| "critical": "Critical Impact" | ||
| }, | ||
| "priority": { | ||
| "low": "Low", | ||
| "medium": "Medium", | ||
| "high": "High", | ||
| "urgent": "Urgent" | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if fr/tasks.json and he/tasks.json have the new keys
echo "=== Checking new keys in French tasks.json ==="
for key in categories complexity impact priority; do
if jq -e ".$key" apps/frontend/src/shared/i18n/locales/fr/tasks.json > /dev/null 2>&1; then
echo "✓ fr/tasks.json has '$key'"
else
echo "✗ fr/tasks.json MISSING '$key'"
fi
done
echo ""
echo "=== Checking new keys in Hebrew tasks.json ==="
for key in categories complexity impact priority; do
if jq -e ".$key" apps/frontend/src/shared/i18n/locales/he/tasks.json > /dev/null 2>&1; then
echo "✓ he/tasks.json has '$key'"
else
echo "✗ he/tasks.json MISSING '$key'"
fi
doneRepository: AndyMik90/Auto-Claude
Length of output: 427
Add missing translation keys to fr/tasks.json.
The new task classification keys (categories, complexity, impact, priority) are missing from the French locale file. Per coding guidelines, new translation keys must be added to all language files (minimum: en/*.json and fr/*.json). Hebrew locale has these keys, but French does not.
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/en/tasks.json around lines 2-31, you
added the new task classification keys (categories, complexity, impact,
priority); the French locale file
apps/frontend/src/shared/i18n/locales/fr/tasks.json is missing these keys—add
the same keys and structure to fr/tasks.json with appropriate French
translations for each entry (categories: feature, bug_fix, refactoring,
documentation, security, performance, ui_ux, infrastructure, testing;
complexity: trivial, small, medium, large, complex; impact: low, medium, high,
critical; priority: low, medium, high, urgent), preserving JSON structure and
keys exactly as in the English file so i18n lookups succeed.
| "tabs": { | ||
| "overview": "Overview", | ||
| "subtasks": "Subtasks", | ||
| "logs": "Logs" | ||
| }, | ||
| "metadata": { | ||
| "created": "Created", | ||
| "updated": "Updated", | ||
| "source": "Source" | ||
| }, | ||
| "tabs": { | ||
| "overview": "Overview", | ||
| "subtasks": "Subtasks", | ||
| "logs": "Logs" | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate tabs key in JSON.
The tabs key is defined twice (Lines 173-177 and Lines 183-187). In JSON, duplicate keys cause the second definition to overwrite the first. While both definitions are identical in this case, this is still incorrect and should be fixed by removing the duplicate.
🔎 Proposed fix
Remove the duplicate tabs block (Lines 183-187):
"metadata": {
"created": "Created",
"updated": "Updated",
"source": "Source"
},
- "tabs": {
- "overview": "Overview",
- "subtasks": "Subtasks",
- "logs": "Logs"
- },
"phases": {📝 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.
| "tabs": { | |
| "overview": "Overview", | |
| "subtasks": "Subtasks", | |
| "logs": "Logs" | |
| }, | |
| "metadata": { | |
| "created": "Created", | |
| "updated": "Updated", | |
| "source": "Source" | |
| }, | |
| "tabs": { | |
| "overview": "Overview", | |
| "subtasks": "Subtasks", | |
| "logs": "Logs" | |
| }, | |
| "tabs": { | |
| "overview": "Overview", | |
| "subtasks": "Subtasks", | |
| "logs": "Logs" | |
| }, | |
| "metadata": { | |
| "created": "Created", | |
| "updated": "Updated", | |
| "source": "Source" | |
| }, |
🧰 Tools
🪛 Biome (2.1.2)
[error] 173-173: The key tabs was already declared.
This where a duplicated key was declared again.
If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.
(lint/suspicious/noDuplicateObjectKeys)
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/en/tasks.json around lines 173-187
there is a duplicate "tabs" key (defined at 173-177 and again at 183-187);
remove the second "tabs" block (lines 183-187) so only one "tabs" definition
remains, then ensure surrounding commas are adjusted so the JSON stays valid (no
trailing commas).
| { | ||
| "title": "סקירת שרת MCP", | ||
| "subtitle": "הצג אילו שרתי MCP וכלים זמינים עבור כל שלב של הסוכן", | ||
| "availableServers": "שרתי MCP זמינים", | ||
| "toolsAvailable": "כלים זמינים", | ||
| "agentsCount": "סוכנים", | ||
| "mcpServersSection": "MCP Servers", | ||
| "availableToolsSection": "כלים זמינים", | ||
| "noMcpServers": "לא נדרשים שרתי MCP", | ||
| "textOnly": "טקסט בלבד (ללא כלים)", | ||
| "conditional": "משולב", | ||
| "more": "נוספים", | ||
| "mcpServers": { | ||
| "context7": { | ||
| "name": "Context7", | ||
| "description": "חיפוש תיעוד לספריות ו-frameworks דרך @upstash/context7-mcp" | ||
| }, | ||
| "graphiti": { | ||
| "name": "זיכרון Graphiti", | ||
| "description": "גרף ידע עבור הקשר בין-סשנים. דורש משתנה סביבה GRAPHITI_MCP_URL" | ||
| }, | ||
| "autoClaude": { | ||
| "name": "כלי Auto-Claude", | ||
| "description": "מעקב אחר התקדמות בנייה, הקשר סשן, רישום גילויים ומלכודות" | ||
| }, | ||
| "linear": { | ||
| "name": "Linear", | ||
| "description": "ניהול פרויקט דרך Linear API. דורש משתנה סביבה LINEAR_API_KEY" | ||
| }, | ||
| "electron": { | ||
| "name": "Electron MCP", | ||
| "description": "אוטומציה של אפליקציות דסקטופ דרך Chrome DevTools Protocol. דורש ELECTRON_MCP_ENABLED=true" | ||
| }, | ||
| "puppeteer": { | ||
| "name": "Puppeteer MCP", | ||
| "description": "אוטומציה של דפדפן אינטרנט עבור front-ends שאינם Electron" | ||
| } | ||
| }, | ||
| "categories": { | ||
| "spec": "יצירת מפרט", | ||
| "build": "בנייה", | ||
| "qa": "בקרת איכות", | ||
| "utility": "כלים עזר", | ||
| "ideation": "רעיונות" | ||
| }, | ||
| "agents": { | ||
| "specGatherer": { | ||
| "label": "אוסף מפרט", | ||
| "description": "אוסף דרישות ראשוניות מהמשתמש" | ||
| }, | ||
| "specResearcher": { | ||
| "label": "חוקר מפרט", | ||
| "description": "מאמת אינטגרציות חיצוניות ו-API" | ||
| }, | ||
| "specWriter": { | ||
| "label": "כותב מפרט", | ||
| "description": "יוצר את מסמך spec.md" | ||
| }, | ||
| "specCritic": { | ||
| "label": "מבקר מפרט", | ||
| "description": "ביקורת עצמית באמצעות ניתוח עמוק" | ||
| }, | ||
| "specDiscovery": { | ||
| "label": "גילוי מפרט", | ||
| "description": "גילוי וניתוח ראשוני של הפרויקט" | ||
| }, | ||
| "specContext": { | ||
| "label": "הקשר מפרט", | ||
| "description": "בונה הקשר מבסיס קוד קיים" | ||
| }, | ||
| "specValidation": { | ||
| "label": "אימות מפרט", | ||
| "description": "מאמת שלמות ואיכות של המפרט" | ||
| }, | ||
| "planner": { | ||
| "label": "מתכנן", | ||
| "description": "יוצר תוכנית יישום עם תתי-משימות" | ||
| }, | ||
| "coder": { | ||
| "label": "מתכנת", | ||
| "description": "מיישם תתי-משימות בודדות" | ||
| }, | ||
| "qaReviewer": { | ||
| "label": "סוקר בקרת איכות", | ||
| "description": "מאמת קריטריוני קבלה. משתמש ב-Electron או Puppeteer לפי סוג הפרויקט" | ||
| }, | ||
| "qaFixer": { | ||
| "label": "מתקן בקרת איכות", | ||
| "description": "מתקן בעיות שדווחו על ידי בקרת איכות. משתמש ב-Electron או Puppeteer לפי סוג הפרויקט" | ||
| }, | ||
| "discovery": { | ||
| "label": "גילוי", | ||
| "description": "מנתח את הפרויקט ומגלה תובנות" | ||
| }, | ||
| "insights": { | ||
| "label": "תובנות", | ||
| "description": "עוזר AI אינטראקטיבי לניתוח קוד ותכנון תכונות" | ||
| }, | ||
| "githubIssuesReviewer": { | ||
| "label": "סוקר בעיות GitHub", | ||
| "description": "מנתח ומעדף בעיות GitHub" | ||
| }, | ||
| "githubPrsReviewer": { | ||
| "label": "סוקר PR של GitHub", | ||
| "description": "סוקר בקשות משיכה של GitHub" | ||
| }, | ||
| "prReviewer": { | ||
| "label": "סוקר PR", | ||
| "description": "סוקר בקשות משיכה של GitHub" | ||
| }, | ||
| "commitMessage": { | ||
| "label": "הודעת commit", | ||
| "description": "מייצר הודעות commit" | ||
| }, | ||
| "mergeResolver": { | ||
| "label": "פותר קונפליקטים", | ||
| "description": "פותר קונפליקטים במיזוג" | ||
| }, | ||
| "analysis": { | ||
| "label": "ניתוח", | ||
| "description": "ניתוח בסיס קוד עם חיפוש הקשר" | ||
| }, | ||
| "batchAnalysis": { | ||
| "label": "ניתוח אצווה", | ||
| "description": "עיבוד אצווה של בעיות או פריטים" | ||
| }, | ||
| "ideation": { | ||
| "label": "רעיונות", | ||
| "description": "מייצר רעיונות לתכונות" | ||
| }, | ||
| "roadmapDiscovery": { | ||
| "label": "גילוי מפת דרכים", | ||
| "description": "מגלה פריטי מפת דרכים" | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify agentTools.json exists in all required locales
echo "=== Checking agentTools.json across locales ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/${locale}/agentTools.json"
if [ -f "$file" ]; then
echo "✓ Found: $file"
key_count=$(jq 'keys | length' "$file" 2>/dev/null)
echo " Top-level keys: $key_count"
else
echo "✗ Missing: $file"
fi
done
echo ""
echo "=== Comparing top-level key structure ==="
for locale in en fr he; do
file="apps/frontend/src/shared/i18n/locales/${locale}/agentTools.json"
if [ -f "$file" ]; then
echo "$locale keys:"
jq 'keys | sort' "$file" 2>/dev/null | head -20
fi
done
echo ""
echo "=== List all locale files ==="
find apps/frontend/src/shared/i18n/locales -name "agentTools.json" 2>/dev/null | sortRepository: AndyMik90/Auto-Claude
Length of output: 1040
Create apps/frontend/src/shared/i18n/locales/fr/agentTools.json
The French translation file is missing. Since this Hebrew translation file introduces a complete agentTools namespace with 14 top-level keys, you must create the corresponding French file with matching key structure before merging (per coding guidelines requiring all translation keys in en/*.json and fr/*.json).
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/he/agentTools.json lines 1-136, the
review notes the French translation file is missing; create
apps/frontend/src/shared/i18n/locales/fr/agentTools.json with the exact same key
structure (all 14 top-level keys and nested objects like mcpServers, categories,
agents) as the Hebrew file (or the canonical en/agentTools.json), provide French
translations for each string (or temporary French placeholders matching
semantics), ensure valid JSON formatting, preserve key names/structure exactly,
and run the i18n validation/linting step to confirm parity before merging.
- Added missing terminal.json for EN/HE translations - Added terminal namespace to i18n config - Fixed missing keys in FR welcome.json (placeholder text) - Fixed malformed JSON in HE roadmap.json - Added configurable IDE URI scheme support (60+ editors) - Fixed file-handlers.ts import to use readSettingsFile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/frontend/src/shared/types/settings.ts (1)
251-265: Fix duplicate property definition.The
preferredIDEfield is declared twice in theAppSettingsinterface (line 252 and line 264). TypeScript does not allow duplicate property names in interfaces, and this will cause a compilation error.🔎 Proposed fix
changelogFormat?: ChangelogFormat; // Preferred IDE for opening files (defaults to VS Code) preferredIDE?: SupportedIDE; changelogAudience?: ChangelogAudience; changelogEmojiLevel?: ChangelogEmojiLevel; // UI Scale setting (75-200%, default 100) uiScale?: number; // Beta updates opt-in (receive pre-release updates) betaUpdates?: boolean; // Migration flags (internal use) _migratedAgentProfileToAuto?: boolean; // Language preference for UI (i18n) language?: SupportedLanguage; // Developer tools preferences - preferredIDE?: SupportedIDE; customIDEPath?: string; // For 'custom' IDE preferredTerminal?: SupportedTerminal; customTerminalPath?: string; // For 'custom' terminal
♻️ Duplicate comments (3)
apps/frontend/src/shared/i18n/locales/he/roadmap.json (1)
1-116: Verify locale parity per coding guidelines.Per the coding guidelines and retrieved learnings, new translation keys must be added to ALL language files (minimum:
en/*.jsonandfr/*.json). A past review flagged thatfr/roadmap.jsonis missing anden/roadmap.jsonmay be missing thefeatureDetailkey.Based on coding guidelines, this is a critical compliance issue. Run the following script to verify the current state of locale parity:
#!/bin/bash # Description: Verify roadmap.json exists in all required locales and compare keys echo "=== Checking existence of roadmap.json files ===" for locale in en fr he; do file="apps/frontend/src/shared/i18n/locales/$locale/roadmap.json" if [ -f "$file" ]; then echo "✓ $locale/roadmap.json exists" else echo "✗ $locale/roadmap.json MISSING" fi done echo "" echo "=== Extracting and comparing top-level keys ===" for locale in en fr he; do file="apps/frontend/src/shared/i18n/locales/$locale/roadmap.json" if [ -f "$file" ]; then echo "--- Keys in $locale/roadmap.json ---" jq -r 'keys | .[]' "$file" 2>/dev/null | sort echo "" fi done echo "=== Detailed key comparison ===" python3 << 'PYEOF' import json import os locales = ["en", "fr", "he"] keys_by_locale = {} for locale in locales: path = f"apps/frontend/src/shared/i18n/locales/{locale}/roadmap.json" if os.path.exists(path): with open(path, 'r', encoding='utf-8') as f: keys_by_locale[locale] = set(json.load(f).keys()) else: keys_by_locale[locale] = None # Report missing files for locale in locales: if keys_by_locale[locale] is None: print(f"ERROR: {locale}/roadmap.json NOT FOUND") else: print(f"OK: {locale}/roadmap.json has {len(keys_by_locale[locale])} top-level keys") # Compare key sets if keys_by_locale["en"] and keys_by_locale["he"]: en_only = keys_by_locale["en"] - keys_by_locale["he"] he_only = keys_by_locale["he"] - keys_by_locale["en"] if en_only: print(f"\nKeys in EN but NOT in HE: {sorted(en_only)}") if he_only: print(f"Keys in HE but NOT in EN: {sorted(he_only)}") if not en_only and not he_only: print("\n✓ EN and HE have identical key sets") if keys_by_locale["fr"]: if keys_by_locale["en"]: en_only = keys_by_locale["en"] - keys_by_locale["fr"] fr_only = keys_by_locale["fr"] - keys_by_locale["en"] if en_only: print(f"\nKeys in EN but NOT in FR: {sorted(en_only)}") if fr_only: print(f"Keys in FR but NOT in EN: {sorted(fr_only)}") if not en_only and not fr_only: print("\n✓ EN and FR have identical key sets") PYEOFapps/frontend/src/shared/i18n/index.ts (1)
32-40: Critical: French imports still point to English directory (previously flagged).Lines 32-40 import French translation resources from
./locales/en/instead of./locales/fr/. This means French users will see English text for changelog, context, insights, roadmap, ideation, rateLimit, worktrees, agentTools, and terminal namespaces. This issue was previously identified but remains unresolved.🔎 Fix: Update import paths to French directory
-import frChangelog from './locales/en/changelog.json'; -import frContext from './locales/en/context.json'; -import frInsights from './locales/en/insights.json'; -import frRoadmap from './locales/en/roadmap.json'; -import frIdeation from './locales/en/ideation.json'; -import frRateLimit from './locales/en/rateLimit.json'; -import frWorktrees from './locales/en/worktrees.json'; -import frAgentTools from './locales/en/agentTools.json'; -import frTerminal from './locales/en/terminal.json'; +import frChangelog from './locales/fr/changelog.json'; +import frContext from './locales/fr/context.json'; +import frInsights from './locales/fr/insights.json'; +import frRoadmap from './locales/fr/roadmap.json'; +import frIdeation from './locales/fr/ideation.json'; +import frRateLimit from './locales/fr/rateLimit.json'; +import frWorktrees from './locales/fr/worktrees.json'; +import frAgentTools from './locales/fr/agentTools.json'; +import frTerminal from './locales/fr/terminal.json';Based on learnings, ensure the corresponding French translation files exist in
apps/frontend/src/shared/i18n/locales/fr/with keys matching their English counterparts.apps/frontend/src/main/ipc-handlers/file-handlers.ts (1)
146-146: Use IPC channel constant instead of hardcoded string.The hardcoded string
'open-file'should be replaced with the importedIPC_CHANNELSconstant for consistency and maintainability.Based on past review comments, this issue was previously identified but remains unresolved.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
apps/frontend/src/main/ipc-handlers/file-handlers.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/shared/i18n/locales/en/terminal.jsonapps/frontend/src/shared/i18n/locales/fr/welcome.jsonapps/frontend/src/shared/i18n/locales/he/roadmap.jsonapps/frontend/src/shared/types/settings.ts
🧰 Additional context used
📓 Path-based instructions (3)
apps/frontend/src/shared/i18n/locales/**/*.json
📄 CodeRabbit inference engine (CLAUDE.md)
Add new translation keys to ALL language files (minimum:
en/*.jsonandfr/*.json) inapps/frontend/src/shared/i18n/locales/
Files:
apps/frontend/src/shared/i18n/locales/en/terminal.jsonapps/frontend/src/shared/i18n/locales/he/roadmap.jsonapps/frontend/src/shared/i18n/locales/fr/welcome.json
apps/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/frontend/src/**/*.{ts,tsx}: Always use translation keys withuseTranslation()for all user-facing text in React/TypeScript frontend components - use formatnamespace:section.key(e.g.,navigation:items.githubPRs)
Never use hardcoded strings in JSX/TSX files for user-facing text - always reference translation keys fromapps/frontend/src/shared/i18n/locales/
Files:
apps/frontend/src/main/ipc-handlers/file-handlers.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/shared/types/settings.ts
apps/frontend/**/*.{ts,tsx}
⚙️ CodeRabbit configuration file
apps/frontend/**/*.{ts,tsx}: Review React patterns and TypeScript type safety.
Check for proper state management and component composition.
Files:
apps/frontend/src/main/ipc-handlers/file-handlers.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/shared/types/settings.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/frontend/src/shared/i18n/locales/**/*.json : Add new translation keys to ALL language files (minimum: `en/*.json` and `fr/*.json`) in `apps/frontend/src/shared/i18n/locales/`
📚 Learning: 2025-12-25T18:29:32.954Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/frontend/src/shared/i18n/locales/**/*.json : Add new translation keys to ALL language files (minimum: `en/*.json` and `fr/*.json`) in `apps/frontend/src/shared/i18n/locales/`
Applied to files:
apps/frontend/src/shared/i18n/locales/en/terminal.jsonapps/frontend/src/shared/i18n/locales/he/roadmap.jsonapps/frontend/src/shared/i18n/locales/fr/welcome.jsonapps/frontend/src/shared/i18n/index.ts
📚 Learning: 2025-12-25T18:29:32.954Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/frontend/src/**/*.{ts,tsx} : Never use hardcoded strings in JSX/TSX files for user-facing text - always reference translation keys from `apps/frontend/src/shared/i18n/locales/`
Applied to files:
apps/frontend/src/main/ipc-handlers/file-handlers.tsapps/frontend/src/shared/i18n/index.ts
📚 Learning: 2025-12-25T18:29:32.954Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T18:29:32.954Z
Learning: Applies to apps/frontend/src/**/*.{ts,tsx} : Always use translation keys with `useTranslation()` for all user-facing text in React/TypeScript frontend components - use format `namespace:section.key` (e.g., `navigation:items.githubPRs`)
Applied to files:
apps/frontend/src/shared/i18n/index.ts
🧬 Code graph analysis (1)
apps/frontend/src/main/ipc-handlers/file-handlers.ts (3)
apps/frontend/src/shared/types/settings.ts (2)
SupportedIDE(14-88)AppSettings(215-268)apps/frontend/src/main/settings-utils.ts (1)
readSettingsFile(29-43)apps/frontend/src/shared/constants/config.ts (1)
DEFAULT_APP_SETTINGS(19-52)
🔇 Additional comments (8)
apps/frontend/src/shared/types/settings.ts (2)
229-230: LGTM! Claude authentication fields follow existing patterns.The new global Claude authentication fields are well-documented and follow the established naming convention for global API keys. The comments clearly indicate sessionKey is recommended over OAuth token.
274-275: LGTM! Consistent Claude authentication fields in SourceEnvConfig.The Claude authentication fields mirror the pattern established in
AppSettings, maintaining consistency across the configuration types.apps/frontend/src/shared/i18n/locales/he/roadmap.json (1)
1-116: Hebrew translation content looks comprehensive.The Hebrew translations appear complete and properly formatted with:
- All placeholder variables ({count}, {provider}, {{title}}) correctly preserved
- Consistent terminology throughout nested sections
- Appropriate RTL Hebrew text for all keys
apps/frontend/src/shared/i18n/index.ts (3)
42-59: LGTM: Hebrew imports correctly configured.All Hebrew translation imports properly reference
./locales/he/directory and follow the established pattern for locale imports.
102-119: LGTM: Hebrew resources properly mapped.The Hebrew language resources object correctly maps all imported Hebrew translations to their respective namespaces, maintaining consistency with the English and French resource structures.
130-130: LGTM: All namespaces properly registered.The namespace array correctly includes all 17 translation namespaces used across the application, ensuring i18next loads all required resources.
apps/frontend/src/main/ipc-handlers/file-handlers.ts (2)
84-90: LGTM with caveat.The
buildEditorUrihelper function is well-structured with a sensible fallback to VS Code. However, its correctness depends on fixing the underlyingIDE_URI_SCHEMESmapping issues (path encoding and fallback URIs).
151-154: LGTM!The settings reading logic correctly merges user settings with defaults and provides a sensible fallback to VS Code if no preferred IDE is configured.
| { | ||
| "taskSelector": { | ||
| "currentTask": "Current Task", | ||
| "switchTo": "Switch to...", | ||
| "clearTask": "Clear Task", | ||
| "selectTask": "Select task...", | ||
| "availableTasks": "Available Tasks", | ||
| "noTasksAvailable": "No tasks available", | ||
| "createInKanban": "Create tasks in Kanban board", | ||
| "addNewTask": "Add New Task" | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if fr/terminal.json exists and compare with en/terminal.json
echo "=== Checking for fr/terminal.json ==="
if [ -f "apps/frontend/src/shared/i18n/locales/fr/terminal.json" ]; then
echo "✓ fr/terminal.json exists"
echo ""
echo "=== Content of fr/terminal.json ==="
cat apps/frontend/src/shared/i18n/locales/fr/terminal.json
echo ""
echo "=== Comparing keys ==="
echo "EN keys:"
jq -r '.taskSelector | keys[]' apps/frontend/src/shared/i18n/locales/en/terminal.json | sort
echo ""
echo "FR keys:"
jq -r '.taskSelector | keys[]' apps/frontend/src/shared/i18n/locales/fr/terminal.json | sort
else
echo "✗ fr/terminal.json does NOT exist"
fiRepository: AndyMik90/Auto-Claude
Length of output: 136
Create French translation file with matching keys.
The coding guidelines require new translation keys to be added to ALL language files (minimum: en/*.json and fr/*.json). The fr/terminal.json file is missing. Create it with French translations for all 8 keys defined in en/terminal.json: currentTask, switchTo, clearTask, selectTask, availableTasks, noTasksAvailable, createInKanban, and addNewTask.
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/fr/terminal.json (create file, lines
1-12), add a JSON object with the exact same keys as the English file
(currentTask, switchTo, clearTask, selectTask, availableTasks, noTasksAvailable,
createInKanban, addNewTask) and provide French translations for each value
(e.g., "Tâche actuelle", "Basculer vers…", "Effacer la tâche", "Sélectionner une
tâche…", "Tâches disponibles", "Aucune tâche disponible", "Créer des tâches dans
le tableau Kanban", "Ajouter une nouvelle tâche"); keep the same key order,
valid UTF-8 and valid JSON formatting, and save alongside other locale files so
both en and fr contain matching keys.
|
this tool is made by Jews? |
✨ i18n Enhancements: - French (FR): welcome, settings, taskReview, tasks, terminal (new file) - Hebrew (HE): roadmap, settings, taskReview, tasks, context, ideation, insights, onboarding - English (EN): context, insights, onboarding, roadmap, settings, taskReview, tasks 🎨 UI Improvements: - Roadmap: Enhanced Kanban view, feature/phase cards, competitor analysis viewer - Settings: Comprehensive project settings, integration sections (GitHub, Linear) - Task Review: QA feedback, workspace messages, staged success notifications - Agent Tools: Improved agent manager, process handling, queue management 🔧 Infrastructure: - IPC: Enhanced handlers, middleware, cache, retry logic, error handling - Type definitions: common, insights, settings, ipc-enhanced - Memory service enhancements - Python environment detection improvements 🐙 Integrations: - GitHub: OAuth flows, issue handlers, investigation handlers, release handlers - Backend runners: ideation, roadmap, spec orchestrators 📚 Documentation: - AUTH_ISSUES_EXPLAINED.md - CODE_QUALITY_IMPROVEMENTS.md - IPC_IMPROVEMENTS_README.md - STABILITY_REPORT.md - GETTING_STARTED_POC.md - CONNECTION_DIAGNOSIS.md
|
לא זה נוצר על ידי copilot אבל רק עבור יהודים |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 59
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (19)
apps/frontend/src/renderer/components/project-settings/MemoryBackendSection.tsx (1)
101-502: Incomplete i18n implementation: 50+ hardcoded strings remain untranslated.While one string has been translated (line 452), this component still contains 50+ hardcoded user-facing strings that violate the coding guidelines and the PR's stated goal of complete Hebrew translation support. Hebrew users will see a heavily mixed UI with only one Hebrew string among dozens of English strings.
Examples of untranslated strings:
- Line 101: Badge text
'Enabled'/'Disabled'- Line 107: Section title
"Memory"- Lines 115-117:
"Enable Memory"label and description- Lines 133-134: File-based memory informational text
- Lines 150-152:
"Enable Agent Memory Access"and description- Lines 181-183:
"Embedding Provider"and description- Lines 198-202: Provider dropdown options (
"Ollama (Local - Free)","OpenAI", etc.)- Lines 214-236: OpenAI section (labels, descriptions, placeholders)
- Lines 244-272: Voyage AI section
- Lines 279-294: Google AI section
- Lines 300-343: Azure OpenAI section
- Lines 350-473: Ollama section (labels, status messages like
"Checking...","Connected","Not running", placeholders)- Lines 481-502: Database settings section
All user-facing text must be converted to use translation keys and added to the translation files (en, fr, he).
As per coding guidelines and retrieved learnings.
apps/frontend/src/renderer/components/task-detail/TaskLogs.tsx (1)
466-467: Incomplete i18n: Hardcoded "Less" and "More" strings.The strings "Less" and "More" remain hardcoded in English, which is inconsistent with the comprehensive i18n migration elsewhere in this file and violates the coding guidelines requiring all user-facing text to use translation keys.
🔎 Suggested fix
Add translation keys for these strings, following the pattern used for similar UI elements elsewhere in this file:
{isExpanded ? ( <> <ChevronDown className="h-2.5 w-2.5" /> - <span>Less</span> + <span>{t('logs.showLess')}</span> </> ) : ( <> <ChevronRight className="h-2.5 w-2.5" /> - <span>More</span> + <span>{t('logs.showMore')}</span> </> )}As per coding guidelines and learnings, remember to add
logs.showLessandlogs.showMorekeys to all language files (minimum: en/tasks.json, fr/tasks.json, he/tasks.json).Also applies to: 471-472
apps/frontend/src/renderer/components/onboarding/OllamaModelSelector.tsx (1)
325-339: Translate hardcoded badge labels.The badge labels "Recommended", "Highest Quality", and "Fastest" are hardcoded English strings. Per coding guidelines, all user-facing text should use i18n translation keys.
🔎 Proposed fix
Add badge translation keys to
en/onboarding.json:"badges": { "recommended": "Recommended", "highestQuality": "Highest Quality", "fastest": "Fastest" }Then update the component:
{model.badge === 'recommended' && ( <span className="inline-flex items-center rounded-full bg-primary/15 px-2 py-0.5 text-xs font-medium text-primary"> - Recommended + {t('badges.recommended')} </span> )} {model.badge === 'quality' && ( <span className="inline-flex items-center rounded-full bg-violet-500/15 px-2 py-0.5 text-xs font-medium text-violet-600 dark:text-violet-400"> - Highest Quality + {t('badges.highestQuality')} </span> )} {model.badge === 'fast' && ( <span className="inline-flex items-center rounded-full bg-amber-500/15 px-2 py-0.5 text-xs font-medium text-amber-600 dark:text-amber-400"> - Fastest + {t('badges.fastest')} </span> )}Remember to add corresponding translations to all locale files (minimum:
en/,fr/,he/).Based on learnings and coding guidelines.
apps/frontend/src/renderer/components/Sidebar.tsx (1)
119-120: Keyboard shortcut logic inconsistent with button disablement.The early return at line 120 prevents ALL keyboard shortcuts when no project is selected, but the agent-tools button (lines 226-233) is now enabled without a project. This creates inconsistent UX: users can click the agent-tools button but the 'M' keyboard shortcut won't work in the same scenario.
🔎 Suggested fix to align keyboard shortcuts with button behavior
Update the keyboard handler to check if the matched item requires a project:
- // Only handle shortcuts when a project is selected - if (!selectedProjectId) return; - // Check for modifier keys - we want plain key presses only if (e.metaKey || e.ctrlKey || e.altKey) return; const key = e.key.toUpperCase(); // Find matching nav item const allNavItems = [...projectNavItems, ...toolsNavItems]; const matchedItem = allNavItems.find((item) => item.shortcut === key); if (matchedItem) { + // agent-tools can be accessed without a project + const requiresProject = matchedItem.id !== 'agent-tools'; + if (requiresProject && !selectedProjectId) return; + e.preventDefault(); onViewChange?.(matchedItem.id); }This ensures keyboard shortcuts and button clicks have consistent behavior.
apps/frontend/src/renderer/components/project-settings/AgentConfigSection.tsx (1)
28-30: Replace hardcoded model labels with i18n translation keys.The model labels from
AVAILABLE_MODELS('Claude Opus 4.5', 'Claude Sonnet 4.5', 'Claude Haiku 4.5') are user-facing text rendered directly without translation. Add translation keys to the language files (en/settings.json, fr/settings.json) and use theuseTranslation()hook to display them, consistent with other labels in this component and the i18n implementation across this PR.apps/frontend/src/renderer/components/task-detail/task-review/WorkspaceMessages.tsx (2)
116-116: Translate hardcoded error messages.The error messages
'Failed to delete worktree'are hardcoded English strings that will be displayed to users (line 176). All user-facing text must use i18n translation keys.🔎 Proposed fix
if (!result.success) { - setError(result.error || 'Failed to delete worktree'); + setError(result.error || t('stagedInProject.errors.failedToDelete')); return; }} catch (err) { console.error('Error deleting worktree:', err); - setError(err instanceof Error ? err.message : 'Failed to delete worktree'); + setError(err instanceof Error ? err.message : t('stagedInProject.errors.failedToDelete')); } finally {As per coding guidelines and learnings: all user-facing text in the frontend must use i18n translation keys instead of hardcoded strings.
Also applies to: 127-127
102-185: Add missing French translations forstagedInProjectand other sections infr/taskReview.json.The
StagedInProjectMessagecomponent uses all required i18n keys, which are present in both English and Hebrew locale files. However, the French translation file is incomplete and missing the entirestagedInProjectsection, along withdiffDialog,actions,subtasks,warnings,dialogs, andstagedsections.French users will see untranslated text when this component renders. Complete the French translations in
apps/frontend/src/shared/i18n/locales/fr/taskReview.jsonto match the structure and content in the English file.apps/frontend/src/renderer/components/task-detail/task-review/DiscardDialog.tsx (1)
43-43: Translate all remaining hardcoded strings.Multiple user-facing strings remain hardcoded in English, violating the coding guideline that requires all user-facing text to use i18n translation keys. The following strings must be translated:
- Line 43: "Discard Build" (dialog title)
- Lines 51-52: Warning message about deletion
- Line 57: "Files changed:"
- Line 61: "Lines:"
- Line 71: "Cancel"
- Line 83: "Discarding..."
- Line 88: "Discard Build" (button label)
Add corresponding translation keys to
en/taskReview.json,fr/taskReview.json, andhe/taskReview.jsonand replace all hardcoded strings witht('...')calls.Based on coding guidelines requiring i18n for all user-facing text. Based on learnings requiring translation keys in all language files.
Also applies to: 51-52, 57-57, 61-61, 71-71, 83-83, 88-88
apps/frontend/src/renderer/components/project-settings/LinearIntegrationSection.tsx (2)
78-78: Consider translating the placeholder for consistency (optional).The hardcoded placeholder
"lin_api_xxxxxxxx"could be extracted to a translation key for full i18n coverage. While API format examples are sometimes left as-is, extracting it would maintain consistency with the i18n approach throughout this component.🔎 Proposed change
<PasswordInput value={envConfig.linearApiKey || ''} onChange={(value) => onUpdateConfig({ linearApiKey: value })} - placeholder="lin_api_xxxxxxxx" + placeholder={t('linearIntegration.apiKeyPlaceholder')} />
36-163: Add missing linearIntegration translation keys to all language files.The component uses 22 translation keys from the
linearIntegrationnamespace that do not exist in any language file. All of the following keys are missing fromen/settings.json,fr/settings.json, andhe/settings.json:
- linearIntegration.enabled
- linearIntegration.title
- linearIntegration.enableSync
- linearIntegration.enableSyncDesc
- linearIntegration.apiKey
- linearIntegration.getKeyFrom
- linearIntegration.linearSettings
- linearIntegration.connectionStatus
- linearIntegration.connected
- linearIntegration.connectedTo
- linearIntegration.notConnected
- linearIntegration.tasksAvailable
- linearIntegration.importExistingTitle
- linearIntegration.importExistingDesc
- linearIntegration.importTasks
- linearIntegration.realtimeSync
- linearIntegration.realtimeSyncDesc
- linearIntegration.realtimeSyncWarning
- linearIntegration.teamId
- linearIntegration.autoDetected
- linearIntegration.projectId
- linearIntegration.autoCreated
Add these keys to all required language files before merging.
apps/frontend/src/renderer/components/project-settings/SecuritySettings.tsx (1)
99-460: Add French translations for memory settings section.The component introduces a complete
settings:sections.memorysection with 24+ translation keys, but these keys are missing fromapps/frontend/src/shared/i18n/locales/fr/settings.json. English (en) and Hebrew (he) locale files have the complete memory section, but French is missing the entire section. This breaks French localization for all memory-related UI text in this component.Add the memory section to the French locale file to match the English and Hebrew implementations.
apps/frontend/src/main/agent/agent-manager.ts (1)
162-162: Store language in task context to preserve it across restarts.The
languageparameter is not stored intaskExecutionContext, which means it will be lost if the task is restarted (via auto-swap or manual restart). This will cause restarted tasks to lose the user's language preference.🔎 Proposed fix
- Add
languageto the context interface andstoreTaskContextcall:private taskExecutionContext: Map<string, { projectPath: string; specId: string; options: TaskExecutionOptions; isSpecCreation?: boolean; taskDescription?: string; specDir?: string; metadata?: SpecCreationMetadata; baseBranch?: string; + language?: string; swapCount: number; }> = new Map();
- Update the
storeTaskContextsignature and implementation:private storeTaskContext( taskId: string, projectPath: string, specId: string, options: TaskExecutionOptions, isSpecCreation?: boolean, taskDescription?: string, specDir?: string, metadata?: SpecCreationMetadata, - baseBranch?: string + baseBranch?: string, + language?: string ): void { // Preserve swapCount if context already exists (for restarts) const existingContext = this.taskExecutionContext.get(taskId); const swapCount = existingContext?.swapCount ?? 0; this.taskExecutionContext.set(taskId, { projectPath, specId, options, isSpecCreation, taskDescription, specDir, metadata, baseBranch, + language, swapCount // Preserve existing count instead of resetting }); }
- Pass language when storing context:
// Store context for potential restart - this.storeTaskContext(taskId, projectPath, '', {}, true, taskDescription, specDir, metadata, baseBranch); + this.storeTaskContext(taskId, projectPath, '', {}, true, taskDescription, specDir, metadata, baseBranch, language);
- Pass language when restarting spec creation:
if (context.isSpecCreation) { console.log('[AgentManager] Restarting as spec creation'); this.startSpecCreation( taskId, context.projectPath, context.taskDescription!, context.specDir, context.metadata, - context.baseBranch + context.baseBranch, + context.language ); }Also applies to: 340-366, 418-427
apps/frontend/src/renderer/components/roadmap/FeatureDetailPanel.tsx (1)
218-221: Hardcoded string "Go to Task" needs translation.Line 220 contains a hardcoded English string that violates the i18n requirement. This button label should use a translation key consistent with the rest of the component.
🔎 Proposed fix
<Button className="w-full" onClick={() => onGoToTask(feature.linkedSpecId!)}> <ExternalLink className="h-4 w-4 mr-2" /> - Go to Task + {t('phaseCard.viewTask')} </Button>Note: Reusing the existing
phaseCard.viewTaskkey (used on line 122) or creating a newfeatureDetail.goToTaskkey would both work. Choose based on whether the context requires different wording.As per coding guidelines, all user-facing text in frontend components must use i18n translation keys.
apps/frontend/src/renderer/components/project-settings/InfrastructureStatus.tsx (1)
88-93: Consider translating or contextualizing error messages.The error message from
infrastructureStatus.memory.erroris displayed directly without translation. If these errors originate from system calls or backend services, they may appear in English regardless of the user's language setting.Consider one of these approaches:
- Wrap the error with a translated prefix:
{t('infrastructure.errorPrefix')}: {infrastructureStatus.memory.error}- Map known error codes to translation keys in the error handling logic
- If the backend already provides localized errors, document this assumption
🔎 Example: Add translated error prefix
{infrastructureStatus?.memory.error && ( <p className="text-xs text-destructive"> - {infrastructureStatus.memory.error} + {t('infrastructure.error')}: {infrastructureStatus.memory.error} </p> )}apps/frontend/src/main/ipc-handlers/ideation/generation-handlers.ts (1)
89-94: Debug log missinglanguagefield for consistency.The debug log at lines 89-94 includes
modelandthinkingLevelbut omitslanguage, unlike the debug log at lines 67-74 which includes all three. For consistency in debugging, consider addinglanguagehere as well.🔎 Proposed fix
debugLog('[Ideation Handler] Starting agent manager generation:', { projectId, projectPath: project.path, model: configWithSettings.model, - thinkingLevel: configWithSettings.thinkingLevel + thinkingLevel: configWithSettings.thinkingLevel, + language: configWithSettings.language });apps/backend/runners/roadmap/orchestrator.py (1)
26-36: Consider addinglanguageto the class docstring.For consistency with other orchestrators (e.g.,
SpecOrchestrator), consider documenting thelanguageparameter in the__init__docstring if one exists, or adding a brief inline comment.apps/frontend/src/main/ipc-handlers/roadmap-handlers.ts (1)
254-263: Consider using translation keys for progress messages.The
RoadmapGenerationStatus.messagestrings are hardcoded in English (e.g.,'Analyzing project structure...','Refreshing roadmap...'). Since these messages are sent to the renderer for display, they should ideally use translation keys or be generated on the renderer side based on thephasevalue.As per coding guidelines, user-facing text should use i18n translation keys.
apps/frontend/src/renderer/components/settings/IntegrationSettings.tsx (1)
296-303: Fix corrupted text and variable names causing compilation errors.The code contains corrupted text at multiple locations that will prevent compilation and runtime execution:
- Line 296:
linxxxxxxxxxctionStatusshould belinear.connectionStatus- Line 300:
linexxxxxxxxctedshould belinear.connected- Line 303:
linearConnectionStatusxxxxxxxctedandlinearxxxxxctionStatusare corrupted variable names- Line 438:
xxxxxxxxxcted: isConnected,should beconnected: isConnected,- Line 447:
xxxxxxxxxxxxcted: false,should beconnected: false,🔎 Required fixes
Fix translation keys (lines 296-301):
- <p className="text-sm font-medium text-foreground">{t('linxxxxxxxxxctionStatus')}</p> + <p className="text-sm font-medium text-foreground">{t('linear.connectionStatus')}</p> <p className="text-xs text-muted-foreground"> {isCheckingLinear ? t('linear.checking') : linearConnectionStatus?.connected - ? `${t('linexxxxxxxxcted')}${linearConnectionStatus.teamName ? ` ${t('linear.to')} ${linearConnectionStatus.teamName}` : ''}` + ? `${t('linear.connected')}${linearConnectionStatus.teamName ? ` ${t('linear.to')} ${linearConnectionStatus.teamName}` : ''}` : linearConnectionStatus?.error || t('linear.notConnected')} </p>Fix condition check (line 303):
- {linearConnectionStatusxxxxxxxcted && linearxxxxxctionStatus.issueCount !== undefined && ( + {linearConnectionStatus?.connected && linearConnectionStatus.issueCount !== undefined && (Fix proxy status object (lines 438, 447):
results.claudeApi = { - xxxxxxxxxcted: isConnected, + connected: isConnected, message: isConnected ? response.status === 401 ? t('proxy.proxyWorking', `Proxy working! (Auth required)`) : t('proxy.connected', `Connected to ${url.host}`) : t('proxy.connectionFailed', `Connection failed: ${response.statusText}`) }; } catch (err) { results.claudeApi = { - xxxxxxxxxxxxcted: false, + connected: false, message: err instanceof Error ? t('proxy.connectionFailed', `Connection failed: ${err.message}`) : t('proxy.connectionFailedGeneric', 'Connection failed') };Also applies to: 438-451
apps/frontend/src/renderer/components/project-settings/IntegrationSettings.tsx (1)
133-591: Fix critical translation key namespace mismatch and add missing locale entries.The component uses incorrect translation key namespaces that will cause missing text at runtime:
- Uses
t('linear.*')but keys are stored atsections.linear.*in locale files- Correct all
linear.*references to usesections.linear.*namespaceMissing translation keys in
apps/frontend/src/shared/i18n/locales/en/settings.json:
proxy.enabledproxy.configuredDescriptionsections.githubIntegration.checkingsections.githubIntegration.loadingBranchessections.githubIntegration.mainBranchDescriptionsections.githubIntegration.mainBranchLabelsections.githubIntegration.selectMainBranchsections.githubIntegration.tasksWillBranchThe French locale file (
apps/frontend/src/shared/i18n/locales/fr/settings.json) is severely incomplete and missing entire sections (proxy, linear). Add translations for all missing keys to both language files.Fix corrupted text in code: lines containing
linexxxxxxxxctedandlinxxxxxxxxxctionStatusare corrupted.
♻️ Duplicate comments (19)
apps/frontend/src/shared/i18n/locales/en/context.json (1)
1-119: Add French translation file for context.jsonThe French translation file
apps/frontend/src/shared/i18n/locales/fr/context.jsonis missing. Per coding guidelines, all new translation keys must be added to all language files (minimum:en/*.jsonandfr/*.json). Create this file with French translations matching all keys from the English version.apps/frontend/src/main/python-env-manager.ts (1)
315-321: Duplication: Environment variables should be centralized ingetPythonEnv().This duplication issue was previously flagged. The same UTF-8 environment variables are repeated in both
bootstrapPip()andinstallDeps(), when the class already provides agetPythonEnv()method (lines 635-651) designed for exactly this purpose.Please refer to the earlier review comment for the complete refactoring steps. In summary:
- Update
getPythonEnv()to includePYTHONUTF8andPYTHONLEGACYWINDOWSSTDIO(note:PYTHONIOENCODINGis already there)- Replace the inline
envobjects with...this.getPythonEnv()in both methodsAlso applies to: 375-381
apps/frontend/src/shared/i18n/locales/en/onboarding.json (1)
34-172: French translations missing for all new onboarding keys.Past review comments have already flagged that the new translation keys added to
en/onboarding.jsonare missing fromapps/frontend/src/shared/i18n/locales/fr/onboarding.json. This includes:
- OAuth section expansion (lines 34-47)
- firstSpec section (lines 49-81)
- Memory section expansion (lines 82-100)
- ollama section (lines 153-165)
- embeddingModels section (lines 166-172)
Per coding guidelines, all new translation keys must be added to minimum
en/*.jsonandfr/*.jsonfiles.Based on learnings and coding guidelines.
apps/frontend/src/renderer/components/github-issues/components/EmptyStates.tsx (1)
6-19: Still accepting hardcoded strings viamessageprop.This component continues to allow parent components to pass hardcoded strings through the
messageprop (line 15), which was previously flagged. All user-facing text must use translation keys according to the coding guidelines.Based on learnings and coding guidelines, all user-facing text in the frontend must use i18n translation keys.
apps/frontend/src/renderer/components/task-detail/task-review/DiscardDialog.tsx (1)
48-48: Existing issue flagged: French translation missing.As noted in the previous review, the translation key
dialogs.discardChangesis missing fromapps/frontend/src/shared/i18n/locales/fr/taskReview.json. Ensure this key is added to the French locale file.apps/backend/prompts_pkg/prompt_generator.py (1)
70-81: Consider extracting language mapping to module-level constant.The inline language mapping dictionary was previously flagged as a refactoring opportunity. Moving it to a module-level constant (e.g.,
LANGUAGE_NAMES) would improve maintainability and enable reuse if other functions need language name lookups in the future.🔎 Optional refactor
At the top of the file (after imports):
# Language code to human-readable name mapping LANGUAGE_NAMES = { "he": "Hebrew (עברית)", "ar": "Arabic (العربية)", "es": "Spanish (Español)", "fr": "French (Français)", "de": "German (Deutsch)", "zh": "Chinese (中文)", "ja": "Japanese (日本語)", "ko": "Korean (한국어)", "ru": "Russian (Русский)", "pt": "Portuguese (Português)", }Then in the function:
preferred_lang = requirements.get("preferred_language") if preferred_lang and preferred_lang != "en": - # Map language codes to readable names - lang_names = { - "he": "Hebrew (עברית)", - "ar": "Arabic (العربية)", - "es": "Spanish (Español)", - "fr": "French (Français)", - "de": "German (Deutsch)", - "zh": "Chinese (中文)", - "ja": "Japanese (日本語)", - "ko": "Korean (한국어)", - "ru": "Russian (Русский)", - "pt": "Portuguese (Português)" - } - lang_name = lang_names.get( + lang_name = LANGUAGE_NAMES.get( preferred_lang, preferred_lang.upper() )apps/backend/core/auth.py (2)
16-22: Past review concern: sessionKey validation still missing.A previous review comment flagged that
CLAUDE_SESSION_KEYlacks format validation, unlike OAuth tokens which are validated for thesk-ant-oat01-prefix (line 84). The issue remains unresolved:get_auth_token()returns any non-empty sessionKey without checking its format or structure.See past review comment on lines 16-22 for detailed analysis and suggested remediation.
144-175: Past review concern: Security warnings still missing from sessionKey instructions.A previous review comment flagged that the sessionKey extraction instructions lack security warnings. Users are guided to extract browser cookies but not warned about:
- Treating sessionKey as sensitive (like a password)
- Using private/personal devices only
- Never sharing or logging the key in public repos
- Preferring OAuth if unsure about security
The issue remains unresolved in the current code.
See past review comment on lines 144-175 for detailed security warnings to add.
apps/frontend/src/shared/i18n/locales/en/settings.json (1)
339-362: Verify devtools section is no longer duplicated.A past review flagged duplicate
devtoolskeys causing data loss. The current file shows a singledevtoolssection (lines 339-362). Please confirm no duplicates exist elsewhere in the file.#!/bin/bash # Verify no duplicate top-level keys in settings.json echo "Checking for duplicate keys in en/settings.json..." python3 << 'EOF' import json import sys from collections import Counter with open('apps/frontend/src/shared/i18n/locales/en/settings.json', 'r') as f: content = f.read() # Parse and check for duplicate keys at root level import re # Find all top-level keys keys = re.findall(r'^\s*"([^"]+)":', content, re.MULTILINE) duplicates = [k for k, v in Counter(keys).items() if v > 1] if duplicates: print(f"❌ Duplicate keys found: {duplicates}") sys.exit(1) else: print("✅ No duplicate keys found") EOFapps/frontend/src/renderer/components/CompetitorAnalysisViewer.tsx (1)
2-2: French translations required for competitorViewer keys.The i18n implementation is correct, but as noted in a previous review comment (lines 34-37), the French translation file
apps/frontend/src/shared/i18n/locales/fr/roadmap.jsonis missing thecompetitorViewersection. Per coding guidelines, all translation keys must exist in both en/.json and fr/.json.Based on coding guidelines.
Also applies to: 25-25, 34-175
apps/frontend/src/shared/i18n/locales/en/insights.json (1)
1-96: French translations required for Insights feature.As noted in a previous review comment (lines 1-96), the French translation file
apps/frontend/src/shared/i18n/locales/fr/insights.jsonis missing. Per coding guidelines, all new translation keys must be added to both en/.json and fr/.json.Based on coding guidelines.
apps/backend/spec/phases/planning_phases.py (1)
164-187: Centralize the language mapping to eliminate duplication.This
language_mapdictionary is identical to the one inapps/backend/ideation/phase_executor.py(lines 290-303). Duplicating this mapping across multiple files violates the DRY principle and makes it harder to maintain when adding new languages.Please apply the same centralization refactor suggested for
phase_executor.pyby extracting the language mapping to a shared module and importing it here.🔎 Proposed fix
After creating the shared
apps/backend/core/language_utils.pymodule (as suggested in the review forphase_executor.py), update this file:+from core.language_utils import get_language_name + # ... - # Get language name for AI instructions - language_map = { - "en": "English", - "he": "Hebrew", - "fr": "French", - "es": "Spanish", - "de": "German", - "it": "Italian", - "pt": "Portuguese", - "ru": "Russian", - "ja": "Japanese", - "zh": "Chinese", - "ko": "Korean", - "ar": "Arabic", - } - language_name = language_map.get(self.language, self.language) + language_name = get_language_name(self.language) # Prepend language requirement to contextapps/frontend/src/shared/i18n/locales/en/roadmap.json (1)
1-204: Add French translation file with all keys from en/roadmap.json.The file
apps/frontend/src/shared/i18n/locales/fr/roadmap.jsonis missing. Per coding guidelines, new frontend features must include translation keys in all language files (minimum:en/*.jsonandfr/*.json). Currently only the English version exists.Additionally, the English file has duplicate key definitions for
complexityandimpactproperties that should be removed to maintain clean structure.apps/frontend/src/main/ipc-handlers/file-handlers.ts (1)
218-219: Use IPC channel constant instead of hardcoded string.This duplicates feedback from a past review. The hardcoded
'open-file'string should useIPC_CHANNELS.FILE_OPENfor consistency and maintainability.apps/frontend/src/renderer/components/AgentTools.tsx (1)
26-26: French translation fileagentTools.jsonis missing.This is a duplicate of an existing review comment. The component uses
useTranslation('agentTools')butapps/frontend/src/shared/i18n/locales/fr/agentTools.jsondoes not exist. Per coding guidelines, translation keys must exist in all required language files (minimum:enandfr).apps/frontend/src/renderer/components/Insights.tsx (4)
30-30: French locale file for insights namespace is missing.This is a duplicate of an existing review comment. The component uses
useTranslation('insights')butapps/frontend/src/shared/i18n/locales/fr/insights.jsondoes not exist. Per coding guidelines, translation keys must exist in all required language files (minimum:enandfr).
586-596: Include keyboard shortcuts in translation keys for proper localization.This is a duplicate of an existing review comment. Lines 587 and 595 append hardcoded keyboard shortcuts
(Ctrl+Enter)and(Esc)to translated button text. These should be part of the translation keys to support proper localization and RTL languages.
551-555: Replace hardcoded "(edited)" with translation key.The string "(edited)" on line 553 is hardcoded. Per coding guidelines, all user-facing text must use i18n translation keys.
🔎 Proposed fix
Add to locale files:
{ "edit": { "edited": "(edited)" } }Then update the code:
{message.edited && ( <span className="text-xs text-muted-foreground italic"> - (edited) + {t('edit.edited')} </span> )}
891-891: Add missing French translation keys for insights namespace.The pluralization keys
tools.usedandtools.usedPluralexist in English and Hebrew locales butfr/insights.jsonis missing entirely. Add this file with translations for the tools namespace to meet the minimum locale requirement (en + fr).Optional: Consider using i18next's built-in pluralization feature instead of manual conditional logic
tools.length !== 1 ? t('tools.usedPlural') : t('tools.used')for cleaner code.
| language: str = "en", | ||
| ): | ||
| self.project_dir = Path(project_dir) | ||
| self.output_dir = Path(output_dir) | ||
| self.model = model | ||
| self.thinking_level = thinking_level | ||
| self.thinking_budget = get_thinking_budget(thinking_level) | ||
| self.max_ideas_per_type = max_ideas_per_type | ||
| self.language = language |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Language parameter is stored but not used in AI prompts.
The language parameter is added to the constructor and stored as an instance variable, but it's never used when constructing prompts in the run_agent method (lines 73-93). Without passing the language instruction to the AI, ideation content will be generated in the model's default language (typically English) regardless of the language setting.
🔎 Proposed fix to include language instruction in prompts
# Add context
prompt += f"\n\n---\n\n**Output Directory**: {self.output_dir}\n"
prompt += f"**Project Directory**: {self.project_dir}\n"
prompt += f"**Max Ideas**: {self.max_ideas_per_type}\n"
+ prompt += f"**Language**: Please respond in {self.language}\n"
if additional_context:
prompt += f"\n{additional_context}\n"Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/backend/ideation/generator.py around lines 62-70 (and affecting
run_agent at ~73-93), the constructor stores self.language but run_agent never
injects it into AI prompts; update run_agent to include a clear language
instruction (e.g., "Respond in {self.language}") when building the system/user
prompt templates so generated ideation respects the instance language,
interpolate self.language into all prompt templates, and keep a sensible
default/fallback if self.language is empty.
| # Get language name for AI instructions | ||
| language_map = { | ||
| "en": "English", | ||
| "he": "Hebrew", | ||
| "fr": "French", | ||
| "es": "Spanish", | ||
| "de": "German", | ||
| "it": "Italian", | ||
| "pt": "Portuguese", | ||
| "ru": "Russian", | ||
| "ja": "Japanese", | ||
| "zh": "Chinese", | ||
| "ko": "Korean", | ||
| "ar": "Arabic", | ||
| } | ||
| language_name = language_map.get(self.generator.language, self.generator.language) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Centralize the language mapping dictionary to eliminate duplication.
The language_map dictionary is duplicated across multiple files (also in apps/backend/spec/phases/planning_phases.py at lines 165-178). This violates the DRY principle and makes maintenance harder when adding new languages.
Consider extracting this mapping to a shared module (e.g., apps/backend/core/language_utils.py or apps/backend/shared/constants.py) and importing it where needed.
🔎 Proposed solution
Create a new shared module:
# apps/backend/core/language_utils.py
"""Language utilities and mappings."""
LANGUAGE_MAP = {
"en": "English",
"he": "Hebrew",
"fr": "French",
"es": "Spanish",
"de": "German",
"it": "Italian",
"pt": "Portuguese",
"ru": "Russian",
"ja": "Japanese",
"zh": "Chinese",
"ko": "Korean",
"ar": "Arabic",
}
def get_language_name(language_code: str) -> str:
"""Get the full language name from a language code.
Args:
language_code: Two-letter language code (e.g., 'en', 'he')
Returns:
Full language name, falling back to the code if not found
"""
return LANGUAGE_MAP.get(language_code, language_code)Then update this file to use the shared utility:
+from core.language_utils import get_language_name
+
# ...
- # Get language name for AI instructions
- language_map = {
- "en": "English",
- "he": "Hebrew",
- "fr": "French",
- "es": "Spanish",
- "de": "German",
- "it": "Italian",
- "pt": "Portuguese",
- "ru": "Russian",
- "ja": "Japanese",
- "zh": "Chinese",
- "ko": "Korean",
- "ar": "Arabic",
- }
- language_name = language_map.get(self.generator.language, self.generator.language)
+ language_name = get_language_name(self.generator.language)Apply the same refactor to apps/backend/spec/phases/planning_phases.py.
Committable suggestion skipped: line range outside the PR's diff.
| # Get language name for AI instructions | ||
| language_map = { | ||
| "en": "English", | ||
| "he": "Hebrew", | ||
| "fr": "French", | ||
| "es": "Spanish", | ||
| "de": "German", | ||
| "it": "Italian", | ||
| "pt": "Portuguese", | ||
| "ru": "Russian", | ||
| "ja": "Japanese", | ||
| "zh": "Chinese", | ||
| "ko": "Korean", | ||
| "ar": "Arabic", | ||
| } | ||
| language_name = language_map.get(self.language, self.language) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Extract duplicated language_map to avoid maintenance issues.
The language_map dictionary is duplicated in both phase_quick_spec and phase_self_critique methods. This violates the DRY principle and creates a maintenance burden if languages need to be added or modified.
🔎 Proposed refactor
Extract the language map as a module-level constant at the top of the file:
"""
Spec Writing and Critique Phase Implementations
================================================
Phases for spec document creation and quality assurance.
"""
import json
from typing import TYPE_CHECKING
from .. import validator, writer
from .models import MAX_RETRIES, PhaseResult
if TYPE_CHECKING:
pass
+
+# Language code to display name mapping for AI instructions
+LANGUAGE_NAMES = {
+ "en": "English",
+ "he": "Hebrew",
+ "fr": "French",
+ "es": "Spanish",
+ "de": "German",
+ "it": "Italian",
+ "pt": "Portuguese",
+ "ru": "Russian",
+ "ja": "Japanese",
+ "zh": "Chinese",
+ "ko": "Korean",
+ "ar": "Arabic",
+}
+
class SpecPhaseMixin:Then replace both occurrences with:
- # Get language name for AI instructions
- language_map = {
- "en": "English",
- "he": "Hebrew",
- "fr": "French",
- "es": "Spanish",
- "de": "German",
- "it": "Italian",
- "pt": "Portuguese",
- "ru": "Russian",
- "ja": "Japanese",
- "zh": "Chinese",
- "ko": "Korean",
- "ar": "Arabic",
- }
- language_name = language_map.get(self.language, self.language)
+ # Get language name for AI instructions
+ language_name = LANGUAGE_NAMES.get(self.language, self.language)Also applies to: 163-178
🤖 Prompt for AI Agents
In apps/backend/spec/phases/spec_phases.py around lines 38-53 and 163-178, the
same language_map dictionary is duplicated in phase_quick_spec and
phase_self_critique; extract this dictionary to a single module-level constant
(e.g., LANGUAGE_MAP) at the top of the file and replace both local dictionaries
with lookups against that constant (language_name =
LANGUAGE_MAP.get(self.language, self.language)); ensure the constant is defined
before the class so both methods can reference it and run existing code paths
unchanged.
| // Load global settings for proxy configuration | ||
| const savedSettings = readSettingsFile(); | ||
| const settings = { ...DEFAULT_APP_SETTINGS, ...savedSettings }; | ||
|
|
||
| // Build environment with global proxy settings | ||
| const globalEnv: Record<string, string> = {}; | ||
|
|
||
| // Add proxy settings if configured | ||
| if (settings.globalHttpProxy) { | ||
| globalEnv.HTTP_PROXY = settings.globalHttpProxy; | ||
| } | ||
| if (settings.globalHttpsProxy) { | ||
| globalEnv.HTTPS_PROXY = settings.globalHttpsProxy; | ||
| } | ||
| if (settings.globalNoProxy) { | ||
| globalEnv.NO_PROXY = settings.globalNoProxy; | ||
| } | ||
|
|
||
| // Add Claude API proxy (ANTHROPIC_BASE_URL) if configured | ||
| if (settings.globalAnthropicBaseUrl) { | ||
| globalEnv.ANTHROPIC_BASE_URL = settings.globalAnthropicBaseUrl; | ||
| console.log(`[AgentProcess] 🎯 Setting ANTHROPIC_BASE_URL=${settings.globalAnthropicBaseUrl}`); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify proxy settings are defined in DEFAULT_APP_SETTINGS
echo "=== Checking for proxy-related keys in config.ts ==="
rg -n "global(Http|Https|No|Anthropic)" apps/frontend/src/shared/constants/config.ts
echo ""
echo "=== Checking if proxy settings are defined elsewhere ==="
rg -n "globalHttpProxy|globalHttpsProxy|globalNoProxy|globalAnthropicBaseUrl" apps/frontend/src/shared/constants/ -A 1 -B 1Repository: AndyMik90/Auto-Claude
Length of output: 175
🏁 Script executed:
#!/bin/bash
# Check the actual content of DEFAULT_APP_SETTINGS
echo "=== Content of config.ts ==="
cat -n apps/frontend/src/shared/constants/config.ts
echo ""
echo "=== Check for settings type definitions ==="
fd -e ts -e tsx . apps/frontend/src/shared | xargs rg -l "globalHttpProxy|Settings.*interface|Settings.*type" | head -20
echo ""
echo "=== Check imports in agent-process.ts ==="
head -30 apps/frontend/src/main/agent/agent-process.ts | grep -n "import\|from"Repository: AndyMik90/Auto-Claude
Length of output: 5401
🏁 Script executed:
#!/bin/bash
# Check the settings type definitions
echo "=== Content of settings.ts ==="
cat -n apps/frontend/src/shared/types/settings.ts
echo ""
echo "=== Content of settings-utils.ts ==="
cat -n apps/frontend/src/main/settings-utils.ts | head -100Repository: AndyMik90/Auto-Claude
Length of output: 15719
Add proxy settings keys to DEFAULT_APP_SETTINGS.
The proxy settings (globalHttpProxy, globalHttpsProxy, globalNoProxy, globalAnthropicBaseUrl) are defined in the AppSettings interface but are missing from DEFAULT_APP_SETTINGS in apps/frontend/src/shared/constants/config.ts. After the merge on line 58, these keys will be undefined unless previously saved to the settings file, causing proxy configuration to silently fail.
Initialize these keys in DEFAULT_APP_SETTINGS with appropriate defaults (e.g., undefined or empty strings, depending on intended behavior).
🤖 Prompt for AI Agents
In apps/frontend/src/shared/constants/config.ts around where
DEFAULT_APP_SETTINGS is defined, the DEFAULT_APP_SETTINGS object is missing the
proxy-related keys (globalHttpProxy, globalHttpsProxy, globalNoProxy,
globalAnthropicBaseUrl) declared on the AppSettings interface; add these four
keys to DEFAULT_APP_SETTINGS with appropriate default values (either undefined
or empty string to match the AppSettings type/usage), ensuring types line up
with AppSettings so the later merge in agent-process.ts won’t produce undefined
proxies unexpectedly.
| export interface RoadmapConfig { | ||
| model?: string; // Model shorthand (opus, sonnet, haiku) | ||
| thinkingLevel?: string; // Thinking level (none, low, medium, high, ultrathink) | ||
| language?: string; // UI language for content generation (en, he, etc.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
🧩 Analysis chain
🏁 Script executed:
# Find RoadmapConfig definition and usage
rg -n "RoadmapConfig" --type=ts -g '!*.test.ts' | head -30Repository: AndyMik90/Auto-Claude
Length of output: 748
🏁 Script executed:
# Search for where language property is accessed/validated
rg -n "\.language" --type=ts -g '!*.test.ts' apps/frontend/src/main/agent/ -B2 -A2Repository: AndyMik90/Auto-Claude
Length of output: 906
🏁 Script executed:
# Search for roadmap handlers and orchestrator
rg -n "ROADMAP_GENERATE|ROADMAP_REFRESH|RoadmapOrchestrator" --type=ts -g '!*.test.ts' -B2 -A5Repository: AndyMik90/Auto-Claude
Length of output: 3848
🏁 Script executed:
# Check for language validation or enum patterns
rg -n "language.*=.*\(en|he|fr\)|LanguageCode|LANGUAGE_" --type=ts -g '!*.test.ts'Repository: AndyMik90/Auto-Claude
Length of output: 50378
🏁 Script executed:
# Search for where language is set in roadmap handlers and if there's validation
rg -n "language" apps/frontend/src/main/ipc-handlers/roadmap-handlers.ts -B5 -A5 | head -80Repository: AndyMik90/Auto-Claude
Length of output: 1725
🏁 Script executed:
# Check if there's a validation function or language enum
rg -n "enum.*[Ll]anguage|LANGUAGE_|validateLanguage|supportedLanguages" --type=ts -g '!*.test.ts'Repository: AndyMik90/Auto-Claude
Length of output: 47
🏁 Script executed:
# Look for defaults or validation in the agent/config
cat -n apps/frontend/src/main/ipc-handlers/roadmap-handlers.ts | sed -n '200,280p'Repository: AndyMik90/Auto-Claude
Length of output: 3126
Consider adding explicit language type or validation if strict language codes are required.
The language property is typed as string, which allows any value including typos or unsupported language codes. While the code includes a sensible default (language || 'en') in the ROADMAP_GENERATE and ROADMAP_REFRESH handlers, there is no validation to prevent invalid language codes from being passed through to the CLI.
Current approach balances safety (defaults prevent undefined) with extensibility (permissive type allows adding languages without code changes). If stricter type safety is desired, consider:
- Union type:
language?: 'en' | 'he' | 'fr'(requires updates when adding languages) - Validation function in handlers to explicitly allow/reject language codes
- JSDoc clarifying expected ISO 639-1 format
🤖 Prompt for AI Agents
In apps/frontend/src/main/agent/types.ts around line 41, the language property
is currently typed as string which allows invalid or mistyped codes; change to a
stricter approach by introducing a Language type (e.g., export type Language =
'en' | 'he' | 'fr' or other supported ISO 639-1 codes), update the language?:
string to language?: Language, add a JSDoc comment clarifying expected format,
and ensure handlers that receive language still validate/normalize incoming
values (fallback to 'en' if invalid) or update the
ROADMAP_GENERATE/ROADMAP_REFRESH handlers to call a simple validator that
confirms the value is one of the Language members before passing to the CLI.
| /> | ||
| <p className="text-[10px] text-muted-foreground mt-1.5"> | ||
| Edit as needed, then copy and use with <code className="bg-background px-1 rounded">git commit -m "..."</code> | ||
| {t('staged.editNote')} <code className="bg-background px-1 rounded">git commit -m "..."</code> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's view the actual code at the lines mentioned
cd apps/frontend/src/renderer/components/task-detail/task-review && \
wc -l StagedSuccessMessage.tsx && \
sed -n '75,95p' StagedSuccessMessage.tsxRepository: AndyMik90/Auto-Claude
Length of output: 1093
🏁 Script executed:
# Check the structure of translation files and locate taskReview.json files
find apps/frontend/src/shared/i18n/locales -name "*.json" -type f | head -20Repository: AndyMik90/Auto-Claude
Length of output: 1165
🏁 Script executed:
# Check for taskReview translation files specifically
fd -type f -name "*taskReview*" "apps/frontend/src/shared/i18n/locales/"Repository: AndyMik90/Auto-Claude
Length of output: 235
🏁 Script executed:
# Check what languages are supported
ls -d apps/frontend/src/shared/i18n/locales/*/Repository: AndyMik90/Auto-Claude
Length of output: 190
🏁 Script executed:
# View the en/taskReview.json file to verify keys
cat apps/frontend/src/shared/i18n/locales/en/taskReview.jsonRepository: AndyMik90/Auto-Claude
Length of output: 3627
🏁 Script executed:
# Check if fr/taskReview.json exists
cat apps/frontend/src/shared/i18n/locales/fr/taskReview.jsonRepository: AndyMik90/Auto-Claude
Length of output: 878
🏁 Script executed:
# Check if Hebrew translation file exists and has the staged keys
cat apps/frontend/src/shared/i18n/locales/he/taskReview.jsonRepository: AndyMik90/Auto-Claude
Length of output: 3288
Add missing French translations for the staged section in taskReview.json.
The staged section is completely missing from apps/frontend/src/shared/i18n/locales/fr/taskReview.json, but is present in English and Hebrew. Since French is a minimum supported language, the following keys must be added:
staged.titlestaged.aiCommitMessagestaged.copiedstaged.copystaged.commitPlaceholderstaged.editNotestaged.nextStepsTitlestaged.step1staged.step2staged.step2Andstaged.step3
Additionally, consider refactoring the split-translation pattern on line 88 ({t('staged.step2')} ... {t('staged.step2And')} ...) to use a single translation key with interpolation for better maintainability and translator context, even though the current pattern functions correctly across languages including RTL (Hebrew).
🤖 Prompt for AI Agents
In
apps/frontend/src/renderer/components/task-detail/task-review/StagedSuccessMessage.tsx
around line 79, French translations are missing: add the entire "staged" object
to apps/frontend/src/shared/i18n/locales/fr/taskReview.json containing the keys
staged.title, staged.aiCommitMessage, staged.copied, staged.copy,
staged.commitPlaceholder, staged.editNote, staged.nextStepsTitle, staged.step1,
staged.step2, staged.step2And, and staged.step3 with appropriate French strings;
also optionally refactor the split translation pattern used for step2/step2And
into a single key (e.g., staged.step2Combined) that uses
interpolation/placeholders so translators get full context and you can replace
the two-part JSX concatenation with a single t(...) call.
| "complexity": { | ||
| "low": "low", | ||
| "medium": "medium", | ||
| "high": "high" | ||
| }, | ||
| "impact": { | ||
| "low": "low", | ||
| "medium": "medium", | ||
| "high": "high" | ||
| }, | ||
| "impactFull": { | ||
| "low": "Low Impact", | ||
| "medium": "Medium Impact", | ||
| "high": "High Impact" | ||
| }, | ||
| "complexityFull": { | ||
| "low": "Low Complexity", | ||
| "medium": "Medium Complexity", | ||
| "high": "High Complexity" | ||
| }, | ||
| "priority": { | ||
| "must": "Must Have", | ||
| "should": "Should Have", | ||
| "could": "Could Have", | ||
| "wont": "Won't Have" | ||
| }, | ||
| "complexity": { | ||
| "low": "Low", | ||
| "medium": "Medium", | ||
| "high": "High" | ||
| }, | ||
| "impact": { | ||
| "low": "Low", | ||
| "medium": "Medium", | ||
| "high": "High" | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Remove duplicate JSON keys.
The static analysis correctly identified duplicate keys:
complexityis defined twice (lines 119-123 and lines 145-149)impactis defined twice (lines 124-128 and lines 150-154)
In JSON, duplicate keys are invalid and only the last definition takes effect. This means lines 119-128 are effectively ignored.
🔎 Proposed fix
Remove the first occurrence of both duplicate keys:
},
- "complexity": {
- "low": "low",
- "medium": "medium",
- "high": "high"
- },
- "impact": {
- "low": "low",
- "medium": "medium",
- "high": "high"
- },
"impactFull": {The definitions at lines 145-154 should be retained as they have the correct capitalized values ("Low", "Medium", "High").
📝 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.
| "complexity": { | |
| "low": "low", | |
| "medium": "medium", | |
| "high": "high" | |
| }, | |
| "impact": { | |
| "low": "low", | |
| "medium": "medium", | |
| "high": "high" | |
| }, | |
| "impactFull": { | |
| "low": "Low Impact", | |
| "medium": "Medium Impact", | |
| "high": "High Impact" | |
| }, | |
| "complexityFull": { | |
| "low": "Low Complexity", | |
| "medium": "Medium Complexity", | |
| "high": "High Complexity" | |
| }, | |
| "priority": { | |
| "must": "Must Have", | |
| "should": "Should Have", | |
| "could": "Could Have", | |
| "wont": "Won't Have" | |
| }, | |
| "complexity": { | |
| "low": "Low", | |
| "medium": "Medium", | |
| "high": "High" | |
| }, | |
| "impact": { | |
| "low": "Low", | |
| "medium": "Medium", | |
| "high": "High" | |
| }, | |
| "impactFull": { | |
| "low": "Low Impact", | |
| "medium": "Medium Impact", | |
| "high": "High Impact" | |
| }, | |
| "complexityFull": { | |
| "low": "Low Complexity", | |
| "medium": "Medium Complexity", | |
| "high": "High Complexity" | |
| }, | |
| "priority": { | |
| "must": "Must Have", | |
| "should": "Should Have", | |
| "could": "Could Have", | |
| "wont": "Won't Have" | |
| }, | |
| "complexity": { | |
| "low": "Low", | |
| "medium": "Medium", | |
| "high": "High" | |
| }, | |
| "impact": { | |
| "low": "Low", | |
| "medium": "Medium", | |
| "high": "High" | |
| }, |
🧰 Tools
🪛 Biome (2.1.2)
[error] 119-119: The key complexity was already declared.
This where a duplicated key was declared again.
If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.
(lint/suspicious/noDuplicateObjectKeys)
[error] 124-124: The key impact was already declared.
This where a duplicated key was declared again.
If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.
(lint/suspicious/noDuplicateObjectKeys)
🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/en/roadmap.json around lines 119-154
there are duplicate JSON keys: "complexity" and "impact" are each defined twice;
remove the first occurrences (lines ~119-128) and keep the later definitions
(lines ~145-154 with "Low"/"Medium"/"High") so the file has only one
"complexity" and one "impact" entry and valid comma placement between
surrounding properties.
| # תכנית שיפור איכות קוד - שכבת IPC | ||
|
|
||
| ## סקירה כללית | ||
| מסמך זה מתאר שיפורים מוצעים לשכבת התקשורת בין Frontend ל-Backend (IPC Layer). | ||
|
|
||
| ## 🎯 יעדים | ||
|
|
||
| 1. **אחידות** - ליצור מבנה אחיד לכל ה-IPC handlers | ||
| 2. **Type Safety** - לחזק את הבטיחות הטיפוסית בכל השכבות | ||
| 3. **Validation** - להוסיף שכבת validation מרכזית | ||
| 4. **Error Handling** - לשפר את הטיפול בשגיאות | ||
| 5. **Documentation** - לתעד את ה-API contracts | ||
|
|
||
| --- | ||
|
|
||
| ## 📦 שיפורים מוצעים | ||
|
|
||
| ### 1. Error Handling מרכזי | ||
|
|
||
| **בעיה נוכחית:** | ||
| ```typescript | ||
| // בקבצים שונים יש טיפול שונה בשגיאות | ||
| console.warn('[TASK_START] No main window found'); | ||
| console.error('[Roadmap Handler] Failed to read feature settings:', error); | ||
| ``` | ||
|
|
||
| **פתרון מוצע:** | ||
| ```typescript | ||
| // apps/frontend/src/shared/utils/ipc-error-handler.ts | ||
| export class IPCError extends Error { | ||
| constructor( | ||
| message: string, | ||
| public readonly code: string, | ||
| public readonly context?: Record<string, unknown> | ||
| ) { | ||
| super(message); | ||
| this.name = 'IPCError'; | ||
| } | ||
| } | ||
|
|
||
| export const IPCErrorCodes = { | ||
| NOT_FOUND: 'NOT_FOUND', | ||
| UNAUTHORIZED: 'UNAUTHORIZED', | ||
| VALIDATION_ERROR: 'VALIDATION_ERROR', | ||
| INTERNAL_ERROR: 'INTERNAL_ERROR', | ||
| TIMEOUT: 'TIMEOUT', | ||
| } as const; | ||
|
|
||
| export function handleIPCError(error: unknown, context: string): IPCResult { | ||
| if (error instanceof IPCError) { | ||
| debugError(`[${context}] ${error.code}:`, error.message, error.context); | ||
| return { | ||
| success: false, | ||
| error: error.message, | ||
| errorCode: error.code, | ||
| errorContext: error.context, | ||
| }; | ||
| } | ||
|
|
||
| debugError(`[${context}] Unexpected error:`, error); | ||
| return { | ||
| success: false, | ||
| error: 'Internal server error', | ||
| errorCode: IPCErrorCodes.INTERNAL_ERROR, | ||
| }; | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### 2. IPC Request Validator | ||
|
|
||
| **בעיה נוכחית:** | ||
| - כל handler מבצע validation משלו | ||
| - אין בדיקות עקביות | ||
|
|
||
| **פתרון מוצע:** | ||
| ```typescript | ||
| // apps/frontend/src/main/ipc-handlers/validators/schema-validator.ts | ||
| import { z } from 'zod'; | ||
|
|
||
| export function createIPCValidator<T extends z.ZodType>(schema: T) { | ||
| return (data: unknown): z.infer<T> => { | ||
| const result = schema.safeParse(data); | ||
| if (!result.success) { | ||
| throw new IPCError( | ||
| 'Validation failed', | ||
| IPCErrorCodes.VALIDATION_ERROR, | ||
| { errors: result.error.errors } | ||
| ); | ||
| } | ||
| return result.data; | ||
| }; | ||
| } | ||
|
|
||
| // דוגמה לשימוש | ||
| const taskStartOptionsSchema = z.object({ | ||
| taskId: z.string().min(1), | ||
| options: z.object({ | ||
| baseBranch: z.string().optional(), | ||
| language: z.string().optional(), | ||
| }).optional(), | ||
| }); | ||
|
|
||
| export const validateTaskStartOptions = createIPCValidator(taskStartOptionsSchema); | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### 3. Middleware Pattern for Handlers | ||
|
|
||
| **פתרון מוצע:** | ||
| ```typescript | ||
| // apps/frontend/src/main/ipc-handlers/middleware/ipc-middleware.ts | ||
| import { ipcMain, IpcMainInvokeEvent } from 'electron'; | ||
|
|
||
| export type IPCHandler<TArgs extends unknown[], TResult> = ( | ||
| event: IpcMainInvokeEvent, | ||
| ...args: TArgs | ||
| ) => Promise<IPCResult<TResult>>; | ||
|
|
||
| export type IPCMiddleware = <TArgs extends unknown[], TResult>( | ||
| handler: IPCHandler<TArgs, TResult> | ||
| ) => IPCHandler<TArgs, TResult>; | ||
|
|
||
| // Logging middleware | ||
| export const loggingMiddleware: IPCMiddleware = (handler) => { | ||
| return async (event, ...args) => { | ||
| const startTime = Date.now(); | ||
| debugLog(`[IPC] Handler started with args:`, args); | ||
|
|
||
| try { | ||
| const result = await handler(event, ...args); | ||
| const duration = Date.now() - startTime; | ||
| debugLog(`[IPC] Handler completed in ${duration}ms`, result); | ||
| return result; | ||
| } catch (error) { | ||
| debugError(`[IPC] Handler failed:`, error); | ||
| throw error; | ||
| } | ||
| }; | ||
| }; | ||
|
|
||
| // Validation middleware | ||
| export const validationMiddleware = <T>( | ||
| validator: (data: unknown) => T | ||
| ): IPCMiddleware => { | ||
| return (handler) => { | ||
| return async (event, ...args) => { | ||
| try { | ||
| const validatedArgs = args.map(arg => validator(arg)); | ||
| return await handler(event, ...validatedArgs as unknown[]); | ||
| } catch (error) { | ||
| return handleIPCError(error, 'Validation'); | ||
| } | ||
| }; | ||
| }; | ||
| }; | ||
|
|
||
| // Error handling middleware | ||
| export const errorHandlingMiddleware: IPCMiddleware = (handler) => { | ||
| return async (event, ...args) => { | ||
| try { | ||
| return await handler(event, ...args); | ||
| } catch (error) { | ||
| return handleIPCError(error, 'Handler'); | ||
| } | ||
| }; | ||
| }; | ||
|
|
||
| // Compose multiple middlewares | ||
| export function composeMiddlewares(...middlewares: IPCMiddleware[]): IPCMiddleware { | ||
| return (handler) => { | ||
| return middlewares.reduceRight((acc, middleware) => middleware(acc), handler); | ||
| }; | ||
| } | ||
|
|
||
| // Helper to register handler with middlewares | ||
| export function registerIPCHandler<TArgs extends unknown[], TResult>( | ||
| channel: string, | ||
| handler: IPCHandler<TArgs, TResult>, | ||
| middlewares: IPCMiddleware[] = [] | ||
| ) { | ||
| const composedMiddleware = composeMiddlewares(...middlewares); | ||
| const wrappedHandler = composedMiddleware(handler); | ||
| ipcMain.handle(channel, wrappedHandler); | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### 4. Enhanced Type Definitions | ||
|
|
||
| **פתרון מוצע:** | ||
| ```typescript | ||
| // apps/frontend/src/shared/types/common.ts | ||
| export interface IPCResult<T = unknown> { | ||
| success: boolean; | ||
| data?: T; | ||
| error?: string; | ||
| errorCode?: string; | ||
| errorContext?: Record<string, unknown>; | ||
| metadata?: { | ||
| timestamp?: number; | ||
| duration?: number; | ||
| version?: string; | ||
| }; | ||
| } | ||
|
|
||
| // Create strongly-typed IPC channel definitions | ||
| export type IPCChannelDefinition<TRequest, TResponse> = { | ||
| request: TRequest; | ||
| response: TResponse; | ||
| }; | ||
|
|
||
| // Example usage | ||
| export type IPCChannels = { | ||
| 'task:start': IPCChannelDefinition< | ||
| { taskId: string; options?: TaskStartOptions }, | ||
| Task | ||
| >; | ||
| 'task:stop': IPCChannelDefinition< | ||
| { taskId: string }, | ||
| void | ||
| >; | ||
| 'project:add': IPCChannelDefinition< | ||
| { projectPath: string }, | ||
| Project | ||
| >; | ||
| // ... more channels | ||
| }; | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### 5. API Contract Documentation | ||
|
|
||
| **פתרון מוצע:** | ||
| ```typescript | ||
| // apps/frontend/src/shared/docs/api-contracts.ts | ||
| /** | ||
| * IPC API Contract Documentation | ||
| * | ||
| * This file serves as the single source of truth for all IPC communication | ||
| * contracts between the frontend and backend. | ||
| */ | ||
|
|
||
| export const IPC_API_CONTRACTS = { | ||
| 'task:start': { | ||
| description: 'Starts a task execution', | ||
| request: { | ||
| taskId: 'string (required) - The unique task identifier', | ||
| options: { | ||
| baseBranch: 'string (optional) - Base branch for worktree', | ||
| language: 'string (optional) - Language for spec generation', | ||
| }, | ||
| }, | ||
| response: { | ||
| success: 'boolean - Indicates if operation succeeded', | ||
| data: 'Task | undefined - The updated task object', | ||
| error: 'string | undefined - Error message if failed', | ||
| }, | ||
| errors: { | ||
| NOT_FOUND: 'Task or project not found', | ||
| UNAUTHORIZED: 'No valid Claude authentication', | ||
| VALIDATION_ERROR: 'Invalid request parameters', | ||
| }, | ||
| example: ` | ||
| // Request | ||
| await window.electronAPI.startTask('task-123', { | ||
| baseBranch: 'main', | ||
| language: 'en' | ||
| }); | ||
| // Response (success) | ||
| { success: true, data: { id: 'task-123', ... } } | ||
| // Response (error) | ||
| { success: false, error: 'Task not found', errorCode: 'NOT_FOUND' } | ||
| `, | ||
| }, | ||
| // ... more contracts | ||
| } as const; | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### 6. Retry Mechanism | ||
|
|
||
| **פתרון מוצע:** | ||
| ```typescript | ||
| // apps/frontend/src/shared/utils/ipc-retry.ts | ||
| export interface RetryOptions { | ||
| maxAttempts: number; | ||
| delayMs: number; | ||
| backoff?: 'linear' | 'exponential'; | ||
| retryableErrors?: string[]; | ||
| } | ||
|
|
||
| export async function withRetry<T>( | ||
| fn: () => Promise<IPCResult<T>>, | ||
| options: RetryOptions | ||
| ): Promise<IPCResult<T>> { | ||
| const { maxAttempts, delayMs, backoff = 'exponential', retryableErrors } = options; | ||
|
|
||
| let lastError: IPCResult<T> | undefined; | ||
|
|
||
| for (let attempt = 1; attempt <= maxAttempts; attempt++) { | ||
| try { | ||
| const result = await fn(); | ||
|
|
||
| if (result.success) { | ||
| return result; | ||
| } | ||
|
|
||
| // Check if error is retryable | ||
| if (retryableErrors && result.errorCode) { | ||
| if (!retryableErrors.includes(result.errorCode)) { | ||
| return result; // Not retryable, return immediately | ||
| } | ||
| } | ||
|
|
||
| lastError = result; | ||
|
|
||
| if (attempt < maxAttempts) { | ||
| const delay = backoff === 'exponential' | ||
| ? delayMs * Math.pow(2, attempt - 1) | ||
| : delayMs * attempt; | ||
|
|
||
| debugLog(`[Retry] Attempt ${attempt} failed, retrying in ${delay}ms...`); | ||
| await new Promise(resolve => setTimeout(resolve, delay)); | ||
| } | ||
| } catch (error) { | ||
| debugError(`[Retry] Attempt ${attempt} threw error:`, error); | ||
| if (attempt === maxAttempts) { | ||
| throw error; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return lastError || { success: false, error: 'All retry attempts failed' }; | ||
| } | ||
|
|
||
| // Usage example | ||
| const result = await withRetry( | ||
| () => window.electronAPI.getRoadmap(projectId), | ||
| { | ||
| maxAttempts: 3, | ||
| delayMs: 1000, | ||
| backoff: 'exponential', | ||
| retryableErrors: [IPCErrorCodes.TIMEOUT, IPCErrorCodes.INTERNAL_ERROR], | ||
| } | ||
| ); | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### 7. Request/Response Caching | ||
|
|
||
| **פתרון מוצע:** | ||
| ```typescript | ||
| // apps/frontend/src/renderer/utils/ipc-cache.ts | ||
| export class IPCCache { | ||
| private cache = new Map<string, { data: unknown; timestamp: number }>(); | ||
| private ttlMs: number; | ||
|
|
||
| constructor(ttlMs: number = 60000) { | ||
| this.ttlMs = ttlMs; | ||
| } | ||
|
|
||
| getCacheKey(channel: string, ...args: unknown[]): string { | ||
| return `${channel}:${JSON.stringify(args)}`; | ||
| } | ||
|
|
||
| get<T>(channel: string, ...args: unknown[]): T | undefined { | ||
| const key = this.getCacheKey(channel, ...args); | ||
| const cached = this.cache.get(key); | ||
|
|
||
| if (!cached) return undefined; | ||
|
|
||
| const isExpired = Date.now() - cached.timestamp > this.ttlMs; | ||
| if (isExpired) { | ||
| this.cache.delete(key); | ||
| return undefined; | ||
| } | ||
|
|
||
| return cached.data as T; | ||
| } | ||
|
|
||
| set<T>(channel: string, data: T, ...args: unknown[]): void { | ||
| const key = this.getCacheKey(channel, ...args); | ||
| this.cache.set(key, { data, timestamp: Date.now() }); | ||
| } | ||
|
|
||
| invalidate(channel?: string): void { | ||
| if (!channel) { | ||
| this.cache.clear(); | ||
| return; | ||
| } | ||
|
|
||
| for (const key of this.cache.keys()) { | ||
| if (key.startsWith(`${channel}:`)) { | ||
| this.cache.delete(key); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Create cached API wrapper | ||
| export function createCachedAPI<T extends Record<string, unknown>>( | ||
| api: T, | ||
| cacheConfig: Record<keyof T, number> | ||
| ): T { | ||
| const caches = new Map<keyof T, IPCCache>(); | ||
|
|
||
| return new Proxy(api, { | ||
| get(target, prop: string | symbol) { | ||
| const key = prop as keyof T; | ||
| if (typeof target[key] !== 'function') { | ||
| return target[key]; | ||
| } | ||
|
|
||
| const ttl = cacheConfig[key]; | ||
| if (!ttl) { | ||
| return target[key]; // No caching for this method | ||
| } | ||
|
|
||
| if (!caches.has(key)) { | ||
| caches.set(key, new IPCCache(ttl)); | ||
| } | ||
|
|
||
| const cache = caches.get(key)!; | ||
|
|
||
| return async (...args: unknown[]) => { | ||
| const cached = cache.get(String(prop), ...args); | ||
| if (cached !== undefined) { | ||
| debugLog(`[Cache] Hit for ${String(prop)}`); | ||
| return cached; | ||
| } | ||
|
|
||
| debugLog(`[Cache] Miss for ${String(prop)}`); | ||
| const result = await (target[key] as Function)(...args); | ||
| cache.set(String(prop), result, ...args); | ||
| return result; | ||
| }; | ||
| }, | ||
| }) as T; | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 📊 סדר עדיפויות ליישום | ||
|
|
||
| ### Priority 1 (High) - Critical for stability | ||
| 1. ✅ Error Handling מרכזי | ||
| 2. ✅ Enhanced Type Definitions | ||
| 3. ✅ Validation middleware | ||
|
|
||
| ### Priority 2 (Medium) - Improves developer experience | ||
| 4. ✅ Middleware Pattern | ||
| 5. ✅ API Contract Documentation | ||
|
|
||
| ### Priority 3 (Low) - Nice to have | ||
| 6. ✅ Retry Mechanism | ||
| 7. ✅ Request/Response Caching | ||
|
|
||
| --- | ||
|
|
||
| ## 🔄 תכנית מעבר (Migration Plan) | ||
|
|
||
| ### שלב 1: הקמת תשתית (1-2 ימים) | ||
| - [ ] יצירת קבצי utility חדשים | ||
| - [ ] הגדרת types משופרים | ||
| - [ ] יצירת middleware framework | ||
|
|
||
| ### שלב 2: רפקטורינג הדרגתי (3-5 ימים) | ||
| - [ ] התחלה עם handler אחד (למשל roadmap-handlers) | ||
| - [ ] מעבר של 2-3 handlers נוספים | ||
| - [ ] בדיקות integration | ||
|
|
||
| ### שלב 3: מעבר מלא (5-7 ימים) | ||
| - [ ] מעבר של כל ה-handlers | ||
| - [ ] עדכון תיעוד | ||
| - [ ] בדיקות מקיפות | ||
|
|
||
| ### שלב 4: אופטימיזציה (2-3 ימים) | ||
| - [ ] הוספת caching | ||
| - [ ] הוספת retry logic | ||
| - [ ] מדידות performance | ||
|
|
||
| --- | ||
|
|
||
| ## 📝 דוגמה מלאה להטמעה | ||
|
|
||
| ### לפני: | ||
| ```typescript | ||
| // roadmap-handlers.ts | ||
| ipcMain.handle( | ||
| IPC_CHANNELS.ROADMAP_GET, | ||
| async (_, projectId: string): Promise<IPCResult<Roadmap | null>> => { | ||
| const project = projectStore.getProject(projectId); | ||
| if (!project) { | ||
| return { success: false, error: 'Project not found' }; | ||
| } | ||
|
|
||
| const roadmapPath = path.join( | ||
| project.path, | ||
| AUTO_BUILD_PATHS.ROADMAP_DIR, | ||
| AUTO_BUILD_PATHS.ROADMAP_FILE | ||
| ); | ||
|
|
||
| try { | ||
| const content = readFileSync(roadmapPath, 'utf-8'); | ||
| const roadmap = JSON.parse(content); | ||
| return { success: true, data: roadmap }; | ||
| } catch (error) { | ||
| console.error('Failed to read roadmap:', error); | ||
| return { success: false, error: 'Failed to read roadmap' }; | ||
| } | ||
| } | ||
| ); | ||
| ``` | ||
|
|
||
| ### אחרי: | ||
| ```typescript | ||
| // roadmap-handlers.ts | ||
| import { z } from 'zod'; | ||
| import { registerIPCHandler, loggingMiddleware, errorHandlingMiddleware } from './middleware'; | ||
| import { createIPCValidator, IPCError, IPCErrorCodes } from './validators'; | ||
|
|
||
| const getRoadmapSchema = z.object({ | ||
| projectId: z.string().min(1, 'Project ID is required'), | ||
| }); | ||
|
|
||
| const validateGetRoadmap = createIPCValidator(getRoadmapSchema); | ||
|
|
||
| registerIPCHandler( | ||
| IPC_CHANNELS.ROADMAP_GET, | ||
| async (_, args) => { | ||
| const { projectId } = validateGetRoadmap(args); | ||
|
|
||
| const project = projectStore.getProject(projectId); | ||
| if (!project) { | ||
| throw new IPCError( | ||
| 'Project not found', | ||
| IPCErrorCodes.NOT_FOUND, | ||
| { projectId } | ||
| ); | ||
| } | ||
|
|
||
| const roadmapPath = path.join( | ||
| project.path, | ||
| AUTO_BUILD_PATHS.ROADMAP_DIR, | ||
| AUTO_BUILD_PATHS.ROADMAP_FILE | ||
| ); | ||
|
|
||
| if (!existsSync(roadmapPath)) { | ||
| return { success: true, data: null }; | ||
| } | ||
|
|
||
| const content = await fs.promises.readFile(roadmapPath, 'utf-8'); | ||
| const roadmap = JSON.parse(content); | ||
|
|
||
| return { | ||
| success: true, | ||
| data: roadmap, | ||
| metadata: { | ||
| timestamp: Date.now(), | ||
| }, | ||
| }; | ||
| }, | ||
| [loggingMiddleware, errorHandlingMiddleware] | ||
| ); | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 🧪 בדיקות | ||
|
|
||
| ### Unit Tests | ||
| ```typescript | ||
| describe('IPC Middleware', () => { | ||
| it('should log request and response', async () => { | ||
| const handler = jest.fn().mockResolvedValue({ success: true }); | ||
| const wrappedHandler = loggingMiddleware(handler); | ||
|
|
||
| await wrappedHandler({} as IpcMainInvokeEvent, 'test-arg'); | ||
|
|
||
| expect(handler).toHaveBeenCalledWith({}, 'test-arg'); | ||
| }); | ||
|
|
||
| it('should handle errors gracefully', async () => { | ||
| const handler = jest.fn().mockRejectedValue(new Error('Test error')); | ||
| const wrappedHandler = errorHandlingMiddleware(handler); | ||
|
|
||
| const result = await wrappedHandler({} as IpcMainInvokeEvent); | ||
|
|
||
| expect(result.success).toBe(false); | ||
| expect(result.error).toBeDefined(); | ||
| }); | ||
| }); | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 📚 משאבים נוספים | ||
|
|
||
| - [Electron IPC Best Practices](https://www.electronjs.org/docs/latest/tutorial/ipc) | ||
| - [TypeScript Handbook - Advanced Types](https://www.typescriptlang.org/docs/handbook/2/types-from-types.html) | ||
| - [Zod Documentation](https://zod.dev/) | ||
|
|
||
| --- | ||
|
|
||
| ## ✅ Checklist לסיום | ||
|
|
||
| - [ ] כל ה-handlers משתמשים במידלוור אחיד | ||
| - [ ] כל הבקשות עוברות validation | ||
| - [ ] כל השגיאות מטופלות בצורה עקבית | ||
| - [ ] התיעוד מעודכן | ||
| - [ ] בדיקות unit ו-integration עוברות | ||
| - [ ] Performance נמדד ומאושר | ||
| - [ ] Code review בוצע |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Fix markdown formatting issues for better readability.
The document content is comprehensive and well-organized. However, the static analysis tool has flagged multiple markdown formatting issues that should be addressed for consistency and better rendering:
- Missing blank lines around headings (MD022)
- Missing blank lines around fenced code blocks (MD031)
- Inconsistent ordered list numbering (MD029)
These are mostly spacing issues that can be automatically fixed. Consider running:
#!/bin/bash
# Auto-fix markdown formatting issues
npx markdownlint-cli2 --fix "CODE_QUALITY_IMPROVEMENTS.md"Note: The document is written entirely in Hebrew, which provides excellent localization for Hebrew-speaking contributors. However, consider whether core architectural documentation should also have an English version to ensure accessibility for all contributors.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
3-3: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
21-21: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
28-28: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
78-78: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
113-113: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
195-195: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
239-239: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
291-291: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
361-361: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
455-455: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
460-460: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
461-461: Ordered list item prefix
Expected: 1; Actual: 4; Style: 1/2/3
(MD029, ol-prefix)
462-462: Ordered list item prefix
Expected: 2; Actual: 5; Style: 1/2/3
(MD029, ol-prefix)
464-464: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
465-465: Ordered list item prefix
Expected: 1; Actual: 6; Style: 1/2/3
(MD029, ol-prefix)
466-466: Ordered list item prefix
Expected: 2; Actual: 7; Style: 1/2/3
(MD029, ol-prefix)
472-472: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
477-477: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
482-482: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
487-487: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
496-496: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
497-497: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
525-525: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
526-526: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
581-581: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
582-582: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
🤖 Prompt for AI Agents
In CODE_QUALITY_IMPROVEMENTS.md around lines 1-623, the markdown has
spacing/formatting issues flagged by MD022, MD031 and MD029 (missing blank lines
around headings and fenced code blocks, and inconsistent ordered list
numbering); fix by running a markdown linter auto-fix or manually: ensure a
blank line before and after each heading and fenced code block, normalize
ordered lists so numbering is sequential or use repeated "1." style
consistently, and re-run the linter until no MD022/MD031/MD029 warnings remain.
| @@ -0,0 +1,350 @@ | |||
| # 🔍 דו"ח אבחון - חיבור Claude ודפדפן | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Corrupted or obfuscated filename.
The filename CxxxxxxxxxxxCTION_DIAGNOSIS.md appears corrupted or intentionally obfuscated. This creates several issues:
- Difficult to find and reference in documentation
- May cause problems with version control tools
- Could break on case-sensitive file systems
- Makes the purpose unclear
Recommended fix
Rename the file to a clear, descriptive name:
git mv CxxxxxxxxxxxCTION_DIAGNOSIS.md CONNECTION_DIAGNOSIS.mdOr if the "C" prefix serves a specific purpose:
git mv CxxxxxxxxxxxCTION_DIAGNOSIS.md CLAUDE_CONNECTION_DIAGNOSIS.mdUpdate any references to this file in documentation or code.
🤖 Prompt for AI Agents
In CxxxxxxxxxxxCTION_DIAGNOSIS.md around lines 1-1 the filename is
corrupted/obfuscated which makes it hard to find and may break tooling; rename
the file to a clear name such as CONNECTION_DIAGNOSIS.md (or
CLAUDE_CONNECTION_DIAGNOSIS.md if the prefix is meaningful) using git mv, then
update any references in docs, code, CI/config files, and tests to the new
filename and commit the rename to preserve history.
| ### ✅ Build Status: SUCCESS | ||
| ``` | ||
| ✓ 395 modules transformed. | ||
| out/main/index.js 1,405.60 kB | ||
| ✓ built in 2.44s | ||
| ✓ 31 modules transformed. | ||
| out/preload/index.mjs 47.63 kB | ||
| ✓ built in 77ms | ||
| ✓ 2852 modules transformed. | ||
| ✓ built in 7.52s | ||
| ``` | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Fix markdown formatting issues.
The static analysis tool identified several markdown formatting violations that affect document readability and consistency:
- Missing blank lines around headings (MD022) - Lines 55, 67, 75, 84, 105
- Missing blank lines around code fences (MD031) - Lines 56, 85
- Missing language specifiers on code blocks (MD040) - Lines 56, 85
🔎 Example fixes for common patterns
**תואם לאחור - לא שובר קוד קיים**
---
+
## 🔒 **אישור יציבות:**
+
-### ✅ Build Status: SUCCESS
-```
+### ✅ Build Status: SUCCESS
+
+```text
✓ 395 modules transformed.
out/main/index.js 1,405.60 kB
✓ built in 2.44s✅ אין קריאות API:
Apply similar fixes to all code blocks and headings throughout the document.
</details>
Also applies to: 85-103
<details>
<summary>🧰 Tools</summary>
<details>
<summary>🪛 markdownlint-cli2 (0.18.1)</summary>
55-55: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
---
56-56: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
---
56-56: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
</details>
</details>
<details>
<summary>🤖 Prompt for AI Agents</summary>
In STABILITY_REPORT.md around lines 55-66 (and additionally address occurrences
at 67, 75, 84, 85-103, 105), headings and fenced code blocks lack surrounding
blank lines and code fences are missing language specifiers; fix by inserting a
blank line before and after each heading, ensure there is a blank line before
and after every fenced code block, and add an appropriate language tag (e.g.,
text or bash) to each opening fence so all code blocks include a language
specifier and have proper spacing.
</details>
<!-- fingerprinting:phantom:poseidon:puma -->
<!-- This is an auto-generated comment by CodeRabbit -->
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review continued from previous batch...
| parser.add_argument( | ||
| "--language", | ||
| type=str, | ||
| default="en", | ||
| help="UI language for content generation (en, he, fr, etc.) - AI will generate content in this language (default: en)", | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's look at the ideation_runner.py file to see the actual code
cat -n apps/backend/runners/ideation_runner.py | head -160Repository: AndyMik90/Auto-Claude
Length of output: 6040
🏁 Script executed:
# Now let's find IdeationOrchestrator and check how it handles language
fd -t f "orchestrator" apps/backend/ --type pyRepository: AndyMik90/Auto-Claude
Length of output: 234
🏁 Script executed:
# Search for language parameter handling and validation
rg -n "language" apps/backend/runners/ideation_runner.pyRepository: AndyMik90/Auto-Claude
Length of output: 258
🏁 Script executed:
# Find IdeationOrchestrator definition
find apps/backend -name "*.py" -type f | xargs rg -l "class IdeationOrchestrator"Repository: AndyMik90/Auto-Claude
Length of output: 96
🏁 Script executed:
# Search for language parameter handling and validation in ideation modules
rg -n "language" apps/backend/ideation/ --type py | head -50Repository: AndyMik90/Auto-Claude
Length of output: 1747
🏁 Script executed:
# Look for supported languages definition
rg -n "SUPPORTED_LANGUAGES|supported.*language" apps/backend/ --type pyRepository: AndyMik90/Auto-Claude
Length of output: 176
🏁 Script executed:
# View IdeationOrchestrator class definition
cat -n apps/backend/ideation/runner.py | head -100Repository: AndyMik90/Auto-Claude
Length of output: 4482
🏁 Script executed:
# View the language_map implementation in phase_executor.py
sed -n '285,310p' apps/backend/ideation/phase_executor.pyRepository: AndyMik90/Auto-Claude
Length of output: 815
🏁 Script executed:
# Check if language validation exists anywhere
rg -n "language.*in \[|language.*choices|language.*validation" apps/backend/ideation/ --type pyRepository: AndyMik90/Auto-Claude
Length of output: 47
🏁 Script executed:
# Check IdeationConfigManager for language validation
cat -n apps/backend/ideation/config.py | head -80Repository: AndyMik90/Auto-Claude
Length of output: 3536
🏁 Script executed:
# Check if language validation happens during generator initialization
sed -n '55,80p' apps/backend/ideation/generator.pyRepository: AndyMik90/Auto-Claude
Length of output: 928
🏁 Script executed:
# Verify the complete language_map and if it's used elsewhere
rg -n "language_map" apps/backend/ideation/ --type pyRepository: AndyMik90/Auto-Claude
Length of output: 268
🏁 Script executed:
# Double-check for any validation of language parameter
rg -n "language.*not in|language.*not supported|ValueError.*language|raise.*language" apps/backend/ideation/ --type pyRepository: AndyMik90/Auto-Claude
Length of output: 47
🏁 Script executed:
# Check if there's any client initialization that validates language
rg -n "create_client|Claude.*Client" apps/backend/ideation/ --type py | head -20Repository: AndyMik90/Auto-Claude
Length of output: 276
🏁 Script executed:
# Check create_client function and if it validates language
cat -n apps/backend/core/client.py | head -100Repository: AndyMik90/Auto-Claude
Length of output: 3862
🏁 Script executed:
# Also check generator.py to see how language is used when calling create_client
sed -n '90,110p' apps/backend/ideation/generator.pyRepository: AndyMik90/Auto-Claude
Length of output: 670
Add validation for the language parameter against supported languages.
The --language argument accepts any arbitrary string without validation. While this won't cause a runtime error, invalid language codes (e.g., "invalid123", "xyz") will be passed to the AI with instructions like "Write in xyz language", resulting in degraded output quality and unpredictable behavior.
The codebase already defines a set of supported languages in phase_executor.py (12 languages: en, he, fr, es, de, it, pt, ru, ja, zh, ko, ar). Add validation at the CLI level to enforce this set:
+# Define supported languages (must match language_map in phase_executor.py)
+SUPPORTED_LANGUAGES = ["en", "he", "fr", "es", "de", "it", "pt", "ru", "ja", "zh", "ko", "ar"]
+
parser.add_argument(
"--language",
type=str,
default="en",
+ choices=SUPPORTED_LANGUAGES,
- help="UI language for content generation (en, he, fr, etc.) - AI will generate content in this language (default: en)",
+ help=f"UI language for content generation (choices: {', '.join(SUPPORTED_LANGUAGES)}, default: en)",
)This prevents invalid language codes from propagating through the ideation pipeline.
🤖 Prompt for AI Agents
In apps/backend/runners/ideation_runner.py around lines 107 to 112, the
--language CLI arg currently accepts any string; add validation to restrict
values to the supported language set (en, he, fr, es, de, it, pt, ru, ja, zh,
ko, ar). Replace the plain type/default with an argparse choices= parameter or
validate after parsing (e.g., import the supported list from phase_executor.py
if exported, or declare the same list here) and exit with a clear error message
if an unsupported code is provided so invalid codes never get passed to the AI.
| language_map = { | ||
| "en": "English", | ||
| "he": "Hebrew", | ||
| "es": "Spanish", | ||
| "fr": "French", | ||
| "de": "German", | ||
| "it": "Italian", | ||
| "pt": "Portuguese", | ||
| "ru": "Russian", | ||
| "zh": "Chinese", | ||
| "ja": "Japanese", | ||
| "ko": "Korean", | ||
| "ar": "Arabic" | ||
| } | ||
| language_name = language_map.get(self.language, self.language) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Extract duplicated language_map to a module-level constant.
The identical language_map dictionary is defined in both DiscoveryPhase._build_context() and FeaturesPhase._build_context(). This violates DRY and increases maintenance burden when adding new languages.
🔎 Proposed fix
Add a module-level constant and reference it in both methods:
+# Language code to human-readable name mapping
+LANGUAGE_MAP = {
+ "en": "English",
+ "he": "Hebrew",
+ "es": "Spanish",
+ "fr": "French",
+ "de": "German",
+ "it": "Italian",
+ "pt": "Portuguese",
+ "ru": "Russian",
+ "zh": "Chinese",
+ "ja": "Japanese",
+ "ko": "Korean",
+ "ar": "Arabic"
+}
+
class DiscoveryPhase:
...
def _build_context(self) -> str:
"""Build context string for the discovery agent."""
- language_map = {
- "en": "English",
- ...
- }
- language_name = language_map.get(self.language, self.language)
+ language_name = LANGUAGE_MAP.get(self.language, self.language)Apply the same change to FeaturesPhase._build_context().
Also applies to: 292-306
🤖 Prompt for AI Agents
In apps/backend/runners/roadmap/phases.py around lines 156-170 (and similarly
292-306), the same language_map dict is duplicated in
DiscoveryPhase._build_context() and FeaturesPhase._build_context(); extract this
dict to a module-level constant (e.g., LANGUAGE_MAP = {...}) placed near the top
of the file and replace the in-method dictionaries with lookups against
LANGUAGE_MAP (language_name = LANGUAGE_MAP.get(self.language, self.language));
run tests/lint to ensure no import/name conflicts and update both methods to
reference the single constant.
| // If no manual autoBuildPath is set, try to auto-detect | ||
| if (!settings.autoBuildPath) { | ||
| // Import detectAutoBuildSourcePath from original file | ||
| // For now, skip this to keep it simple | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Remove or implement the placeholder code.
This empty conditional block with a comment about future implementation is dead code. Either implement the auto-detection logic or remove the placeholder to avoid confusion.
🔎 Proposed fix
- // If no manual autoBuildPath is set, try to auto-detect
- if (!settings.autoBuildPath) {
- // Import detectAutoBuildSourcePath from original file
- // For now, skip this to keep it simple
- }
+ // Note: autoBuildPath auto-detection is handled in the original settings handler📝 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.
| // If no manual autoBuildPath is set, try to auto-detect | |
| if (!settings.autoBuildPath) { | |
| // Import detectAutoBuildSourcePath from original file | |
| // For now, skip this to keep it simple | |
| } | |
| // Note: autoBuildPath auto-detection is handled in the original settings handler |
🤖 Prompt for AI Agents
In apps/frontend/src/main/ipc-handlers/enhanced-settings-handlers.ts around
lines 78 to 82, remove the empty conditional placeholder or implement the
auto-detection: either delete the entire if (!settings.autoBuildPath) { /*
placeholder */ } block to eliminate dead code, or import the existing
detectAutoBuildSourcePath function, call it when autoBuildPath is falsy, assign
its result to settings.autoBuildPath (with a null/undefined check), and persist
the updated settings while handling and logging any errors; ensure correct
typings and avoid leaving an empty comment-only branch.
| // IDE URI schemes mapping | ||
| const IDE_URI_SCHEMES: Record<SupportedIDE, (filePath: string, line?: number) => string> = { | ||
| vscode: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `vscode://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | ||
| }, | ||
| vscodium: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `vscodium://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | ||
| }, | ||
| cursor: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `cursor://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | ||
| }, | ||
| windsurf: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `windsurf://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | ||
| }, | ||
| intellij: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `idea://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| pycharm: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `pycharm://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| webstorm: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `webstorm://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| phpstorm: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `phpstorm://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| goland: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `goland://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| rider: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `rider://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| clion: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `clion://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| rubymine: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `rubymine://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| datagrip: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `datagrip://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| androidstudio: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `studio://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| fleet: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `fleet://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| sublime: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `subl://open?url=file://${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| zed: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `zed://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | ||
| }, | ||
| void: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `void://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | ||
| }, | ||
| pearai: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `pearai://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | ||
| }, | ||
| kiro: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `kiro://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | ||
| }, | ||
| aqua: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `aqua://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, | ||
| rustrover: (filePath, line) => { | ||
| const normalized = normalizePathForUri(filePath); | ||
| return `rustrover://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
URI encoding issue: Double-encoding breaks file paths.
Encoding the entire normalized path with encodeURIComponent will encode forward slashes (/ → %2F), breaking the URI structure. For example, /Users/test/file.ts becomes %2FUsers%2Ftest%2Ffile.ts, which VS Code won't interpret correctly.
🔎 Proposed fix - encode path segments individually
function normalizePathForUri(filePath: string): string {
- return filePath.replace(/\\/g, '/');
+ // Convert Windows backslashes to forward slashes and encode each segment
+ return filePath
+ .replace(/\\/g, '/')
+ .split('/')
+ .map(segment => encodeURIComponent(segment))
+ .join('/');
}
// IDE URI schemes mapping
const IDE_URI_SCHEMES: Record<SupportedIDE, (filePath: string, line?: number) => string> = {
vscode: (filePath, line) => {
const normalized = normalizePathForUri(filePath);
- return `vscode://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`;
+ return `vscode://file/${normalized}${line ? `:${line}` : ''}`;
},
// Apply similar changes to all other URI builders...📝 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.
| // IDE URI schemes mapping | |
| const IDE_URI_SCHEMES: Record<SupportedIDE, (filePath: string, line?: number) => string> = { | |
| vscode: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `vscode://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | |
| }, | |
| vscodium: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `vscodium://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | |
| }, | |
| cursor: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `cursor://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | |
| }, | |
| windsurf: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `windsurf://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | |
| }, | |
| intellij: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `idea://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| pycharm: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `pycharm://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| webstorm: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `webstorm://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| phpstorm: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `phpstorm://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| goland: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `goland://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| rider: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `rider://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| clion: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `clion://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| rubymine: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `rubymine://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| datagrip: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `datagrip://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| androidstudio: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `studio://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| fleet: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `fleet://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| sublime: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `subl://open?url=file://${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| zed: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `zed://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | |
| }, | |
| void: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `void://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | |
| }, | |
| pearai: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `pearai://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | |
| }, | |
| kiro: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `kiro://file/${encodeURIComponent(normalized)}${line ? `:${line}` : ''}`; | |
| }, | |
| aqua: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `aqua://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| rustrover: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `rustrover://open?file=${encodeURIComponent(normalized)}${line ? `&line=${line}` : ''}`; | |
| }, | |
| // Helper function to normalize file paths for URI usage | |
| function normalizePathForUri(filePath: string): string { | |
| // Convert Windows backslashes to forward slashes and encode each segment | |
| return filePath | |
| .replace(/\\/g, '/') | |
| .split('/') | |
| .map(segment => encodeURIComponent(segment)) | |
| .join('/'); | |
| } | |
| // IDE URI schemes mapping | |
| const IDE_URI_SCHEMES: Record<SupportedIDE, (filePath: string, line?: number) => string> = { | |
| vscode: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `vscode://file/${normalized}${line ? `:${line}` : ''}`; | |
| }, | |
| vscodium: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `vscodium://file/${normalized}${line ? `:${line}` : ''}`; | |
| }, | |
| cursor: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `cursor://file/${normalized}${line ? `:${line}` : ''}`; | |
| }, | |
| windsurf: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `windsurf://file/${normalized}${line ? `:${line}` : ''}`; | |
| }, | |
| intellij: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `idea://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| pycharm: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `pycharm://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| webstorm: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `webstorm://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| phpstorm: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `phpstorm://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| goland: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `goland://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| rider: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `rider://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| clion: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `clion://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| rubymine: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `rubymine://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| datagrip: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `datagrip://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| androidstudio: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `studio://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| fleet: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `fleet://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| sublime: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `subl://open?url=file://${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| zed: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `zed://file/${normalized}${line ? `:${line}` : ''}`; | |
| }, | |
| void: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `void://file/${normalized}${line ? `:${line}` : ''}`; | |
| }, | |
| pearai: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `pearai://file/${normalized}${line ? `:${line}` : ''}`; | |
| }, | |
| kiro: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `kiro://file/${normalized}${line ? `:${line}` : ''}`; | |
| }, | |
| aqua: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `aqua://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| rustrover: (filePath, line) => { | |
| const normalized = normalizePathForUri(filePath); | |
| return `rustrover://open?file=${normalized}${line ? `&line=${line}` : ''}`; | |
| }, | |
| }; |
🤖 Prompt for AI Agents
In apps/frontend/src/main/ipc-handlers/file-handlers.ts around lines 23 to 112,
the handlers call encodeURIComponent on the entire normalized path which
double-encodes slashes and breaks IDE URIs; fix by encoding each path segment
individually (split the normalized path on '/', encodeURIComponent each segment,
then rejoin with '/' while preserving a leading slash for absolute paths) and
use that segment-encoded path when building the URI for every IDE mapping so
forward slashes remain intact in the final URI.
| // Get language from settings | ||
| let language = 'en'; | ||
| try { | ||
| const settingsPath = path.join(app.getPath('userData'), 'settings.json'); | ||
| if (existsSync(settingsPath)) { | ||
| const settings: AppSettings = { ...DEFAULT_APP_SETTINGS, ...JSON.parse(readFileSync(settingsPath, 'utf-8')) }; | ||
| language = settings.language || 'en'; | ||
| } | ||
| } catch (err) { | ||
| console.warn('[TASK_START] Failed to read language from settings:', err); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Extract duplicated language-reading logic into a helper function.
The language-reading logic is duplicated three times with identical implementation. This violates DRY principles and creates maintenance burden.
🔎 Proposed refactor to extract helper function
Add this helper function near the top of the file:
+/**
+ * Read language setting from user settings file
+ */
+function readLanguageSetting(): string {
+ try {
+ const settingsPath = path.join(app.getPath('userData'), 'settings.json');
+ if (existsSync(settingsPath)) {
+ const settings: AppSettings = { ...DEFAULT_APP_SETTINGS, ...JSON.parse(readFileSync(settingsPath, 'utf-8')) };
+ return settings.language || 'en';
+ }
+ } catch (err) {
+ console.warn('[Task] Failed to read language from settings:', err);
+ }
+ return 'en';
+}Then replace all three blocks with:
- // Get language from settings
- let language = 'en';
- try {
- const settingsPath = path.join(app.getPath('userData'), 'settings.json');
- if (existsSync(settingsPath)) {
- const settings: AppSettings = { ...DEFAULT_APP_SETTINGS, ...JSON.parse(readFileSync(settingsPath, 'utf-8')) };
- language = settings.language || 'en';
- }
- } catch (err) {
- console.warn('[TASK_START] Failed to read language from settings:', err);
- }
+ const language = readLanguageSetting();Apply the same change at lines 506-517 and 796-807.
Also applies to: 506-517, 796-807
| {t('proxy.localProxyServer', 'שרת Proxy מקומי')} | ||
| </Label> | ||
| {/* Always show status badge */} | ||
| <div className={cn( | ||
| "px-2 py-0.5 rounded-full text-xs font-medium flex items-center gap-1", | ||
| proxyServerStatus?.running | ||
| ? "bg-success/20 text-success border border-success/30" | ||
| : "bg-muted text-muted-foreground border border-border" | ||
| )}> | ||
| <div className={cn( | ||
| "w-1.5 h-1.5 rounded-full", | ||
| proxyServerStatus?.running ? "bg-success animate-pulse" : "bg-muted-foreground" | ||
| )} /> | ||
| {proxyServerStatus?.running ? '🟢 Running' : '⚫ Stopped'} | ||
| </div> | ||
| </div> | ||
| <p className="text-xs text-muted-foreground"> | ||
| {t('proxy.localProxyServerHelp', 'הפעל שרת proxy מקומי לניתוב בקשות Claude API')} | ||
| </p> | ||
| </div> | ||
| </div> | ||
|
|
||
| {/* Server URL Display - Only when running */} | ||
| {proxyServerStatus?.running && ( | ||
| <div className="bg-gradient-to-br from-success/10 to-success/5 rounded-lg border border-success/30 p-4 space-y-2"> | ||
| <div className="flex items-center gap-2 text-xs font-medium text-success"> | ||
| <Activity className="h-3.5 w-3.5 animate-pulse" /> | ||
| {t('proxy.serverActive', 'שרת פעיל')} | ||
| </div> | ||
| <div className="bg-background/50 rounded-md p-2 border border-border"> | ||
| <p className="text-xs text-muted-foreground mb-1"> | ||
| {t('proxy.serverUrl', 'URL של השרת')}: | ||
| </p> | ||
| <code className="text-sm font-mono text-foreground bg-muted px-2 py-1 rounded block"> | ||
| {proxyServerStatus.url} | ||
| </code> | ||
| </div> | ||
| <p className="text-xs text-muted-foreground"> | ||
| 💡 {t('proxy.serverUrlHelp', 'השתמש ב-URL זה כ-Anthropic Base URL למעלה')} | ||
| </p> | ||
| </div> | ||
| )} | ||
|
|
||
| {/* Control Buttons */} | ||
| <div className="flex gap-2"> | ||
| {!proxyServerStatus?.running ? ( | ||
| <Button | ||
| variant="default" | ||
| size="default" | ||
| onClick={handleStartProxyServer} | ||
| disabled={isStartingServer} | ||
| className="gap-2 w-full bg-success hover:bg-success/90" | ||
| > | ||
| {isStartingServer ? ( | ||
| <> | ||
| <Loader2 className="h-4 w-4 animate-spin" /> | ||
| {t('proxy.starting', 'מפעיל...')} | ||
| </> | ||
| ) : ( | ||
| <> | ||
| <Activity className="h-4 w-4" /> | ||
| {t('proxy.startServer', '▶️ הפעל שרת')} | ||
| </> | ||
| )} | ||
| </Button> | ||
| ) : ( | ||
| <Button | ||
| variant="destructive" | ||
| size="default" | ||
| onClick={handleStopProxyServer} | ||
| disabled={isStoppingServer} | ||
| className="gap-2 w-full" | ||
| > | ||
| {isStoppingServer ? ( | ||
| <> | ||
| <Loader2 className="h-4 w-4 animate-spin" /> | ||
| {t('proxy.stopping', 'עוצר...')} | ||
| </> | ||
| ) : ( | ||
| <> | ||
| <X className="h-4 w-4" /> | ||
| {t('proxy.stopServer', '⏹️ עצור שרת')} | ||
| </> | ||
| )} | ||
| </Button> | ||
| )} | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Replace hardcoded UI strings with translation keys.
The proxy server control section contains hardcoded strings that should use translation keys for consistency with the i18n implementation:
- Line 1166-1167:
'🟢 Running' : '⚫ Stopped'- hardcoded status text - Several Hebrew strings appear to be mixed with translation keys
As per coding guidelines: "Always use i18n translation keys for all user-facing text in the frontend instead of hardcoded strings"
🔎 Proposed fix
proxyServerStatus?.running
- ? "bg-success/20 text-success border border-success/30"
+ ? "bg-success/20 text-success border border-success/30"
: "bg-muted text-muted-foreground border border-border"
)}>
<div className={cn(
"w-1.5 h-1.5 rounded-full",
proxyServerStatus?.running ? "bg-success animate-pulse" : "bg-muted-foreground"
)} />
- {proxyServerStatus?.running ? '🟢 Running' : '⚫ Stopped'}
+ {proxyServerStatus?.running ? `🟢 ${t('proxy.running')}` : `⚫ ${t('proxy.stopped')}`}
</div>Ensure these keys are added to the translation files:
proxy.runningproxy.stopped
Based on learnings, add these translation keys to all language files (minimum: en/.json and fr/.json).
📝 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.
| {t('proxy.localProxyServer', 'שרת Proxy מקומי')} | |
| </Label> | |
| {/* Always show status badge */} | |
| <div className={cn( | |
| "px-2 py-0.5 rounded-full text-xs font-medium flex items-center gap-1", | |
| proxyServerStatus?.running | |
| ? "bg-success/20 text-success border border-success/30" | |
| : "bg-muted text-muted-foreground border border-border" | |
| )}> | |
| <div className={cn( | |
| "w-1.5 h-1.5 rounded-full", | |
| proxyServerStatus?.running ? "bg-success animate-pulse" : "bg-muted-foreground" | |
| )} /> | |
| {proxyServerStatus?.running ? '🟢 Running' : '⚫ Stopped'} | |
| </div> | |
| </div> | |
| <p className="text-xs text-muted-foreground"> | |
| {t('proxy.localProxyServerHelp', 'הפעל שרת proxy מקומי לניתוב בקשות Claude API')} | |
| </p> | |
| </div> | |
| </div> | |
| {/* Server URL Display - Only when running */} | |
| {proxyServerStatus?.running && ( | |
| <div className="bg-gradient-to-br from-success/10 to-success/5 rounded-lg border border-success/30 p-4 space-y-2"> | |
| <div className="flex items-center gap-2 text-xs font-medium text-success"> | |
| <Activity className="h-3.5 w-3.5 animate-pulse" /> | |
| {t('proxy.serverActive', 'שרת פעיל')} | |
| </div> | |
| <div className="bg-background/50 rounded-md p-2 border border-border"> | |
| <p className="text-xs text-muted-foreground mb-1"> | |
| {t('proxy.serverUrl', 'URL של השרת')}: | |
| </p> | |
| <code className="text-sm font-mono text-foreground bg-muted px-2 py-1 rounded block"> | |
| {proxyServerStatus.url} | |
| </code> | |
| </div> | |
| <p className="text-xs text-muted-foreground"> | |
| 💡 {t('proxy.serverUrlHelp', 'השתמש ב-URL זה כ-Anthropic Base URL למעלה')} | |
| </p> | |
| </div> | |
| )} | |
| {/* Control Buttons */} | |
| <div className="flex gap-2"> | |
| {!proxyServerStatus?.running ? ( | |
| <Button | |
| variant="default" | |
| size="default" | |
| onClick={handleStartProxyServer} | |
| disabled={isStartingServer} | |
| className="gap-2 w-full bg-success hover:bg-success/90" | |
| > | |
| {isStartingServer ? ( | |
| <> | |
| <Loader2 className="h-4 w-4 animate-spin" /> | |
| {t('proxy.starting', 'מפעיל...')} | |
| </> | |
| ) : ( | |
| <> | |
| <Activity className="h-4 w-4" /> | |
| {t('proxy.startServer', '▶️ הפעל שרת')} | |
| </> | |
| )} | |
| </Button> | |
| ) : ( | |
| <Button | |
| variant="destructive" | |
| size="default" | |
| onClick={handleStopProxyServer} | |
| disabled={isStoppingServer} | |
| className="gap-2 w-full" | |
| > | |
| {isStoppingServer ? ( | |
| <> | |
| <Loader2 className="h-4 w-4 animate-spin" /> | |
| {t('proxy.stopping', 'עוצר...')} | |
| </> | |
| ) : ( | |
| <> | |
| <X className="h-4 w-4" /> | |
| {t('proxy.stopServer', '⏹️ עצור שרת')} | |
| </> | |
| )} | |
| </Button> | |
| )} | |
| </div> | |
| </div> | |
| {t('proxy.localProxyServer', 'שרת Proxy מקומי')} | |
| </Label> | |
| {/* Always show status badge */} | |
| <div className={cn( | |
| "px-2 py-0.5 rounded-full text-xs font-medium flex items-center gap-1", | |
| proxyServerStatus?.running | |
| ? "bg-success/20 text-success border border-success/30" | |
| : "bg-muted text-muted-foreground border border-border" | |
| )}> | |
| <div className={cn( | |
| "w-1.5 h-1.5 rounded-full", | |
| proxyServerStatus?.running ? "bg-success animate-pulse" : "bg-muted-foreground" | |
| )} /> | |
| {proxyServerStatus?.running ? `🟢 ${t('proxy.running')}` : `⚫ ${t('proxy.stopped')}`} | |
| </div> | |
| </div> | |
| <p className="text-xs text-muted-foreground"> | |
| {t('proxy.localProxyServerHelp', 'הפעל שרת proxy מקומי לניתוב בקשות Claude API')} | |
| </p> | |
| </div> | |
| </div> | |
| {/* Server URL Display - Only when running */} | |
| {proxyServerStatus?.running && ( | |
| <div className="bg-gradient-to-br from-success/10 to-success/5 rounded-lg border border-success/30 p-4 space-y-2"> | |
| <div className="flex items-center gap-2 text-xs font-medium text-success"> | |
| <Activity className="h-3.5 w-3.5 animate-pulse" /> | |
| {t('proxy.serverActive', 'שרת פעיל')} | |
| </div> | |
| <div className="bg-background/50 rounded-md p-2 border border-border"> | |
| <p className="text-xs text-muted-foreground mb-1"> | |
| {t('proxy.serverUrl', 'URL של השרת')}: | |
| </p> | |
| <code className="text-sm font-mono text-foreground bg-muted px-2 py-1 rounded block"> | |
| {proxyServerStatus.url} | |
| </code> | |
| </div> | |
| <p className="text-xs text-muted-foreground"> | |
| 💡 {t('proxy.serverUrlHelp', 'השתמש ב-URL זה כ-Anthropic Base URL למעלה')} | |
| </p> | |
| </div> | |
| )} | |
| {/* Control Buttons */} | |
| <div className="flex gap-2"> | |
| {!proxyServerStatus?.running ? ( | |
| <Button | |
| variant="default" | |
| size="default" | |
| onClick={handleStartProxyServer} | |
| disabled={isStartingServer} | |
| className="gap-2 w-full bg-success hover:bg-success/90" | |
| > | |
| {isStartingServer ? ( | |
| <> | |
| <Loader2 className="h-4 w-4 animate-spin" /> | |
| {t('proxy.starting', 'מפעיל...')} | |
| </> | |
| ) : ( | |
| <> | |
| <Activity className="h-4 w-4" /> | |
| {t('proxy.startServer', '▶️ הפעל שרת')} | |
| </> | |
| )} | |
| </Button> | |
| ) : ( | |
| <Button | |
| variant="destructive" | |
| size="default" | |
| onClick={handleStopProxyServer} | |
| disabled={isStoppingServer} | |
| className="gap-2 w-full" | |
| > | |
| {isStoppingServer ? ( | |
| <> | |
| <Loader2 className="h-4 w-4 animate-spin" /> | |
| {t('proxy.stopping', 'עוצר...')} | |
| </> | |
| ) : ( | |
| <> | |
| <X className="h-4 w-4" /> | |
| {t('proxy.stopServer', '⏹️ עצור שרת')} | |
| </> | |
| )} | |
| </Button> | |
| )} | |
| </div> | |
| </div> |
🤖 Prompt for AI Agents
In apps/frontend/src/renderer/components/settings/IntegrationSettings.tsx around
lines 1153 to 1240 the proxy control UI contains hardcoded user-facing text
(e.g. '🟢 Running' / '⚫ Stopped' and several Hebrew strings) that must be
replaced with i18n calls; replace those literals with t('proxy.running') and
t('proxy.stopped') (and convert any other remaining hardcoded Hebrew strings in
this block to appropriate t(...) keys), and add the new keys to the translation
files (at minimum en/*.json and fr/*.json) with corresponding translations so
the UI uses translations consistently.
| // Get current language from settings | ||
| const settings = await window.electronAPI.getSettings(); | ||
| const language = settings.success ? settings.data?.language : undefined; | ||
|
|
||
| useRoadmapStore.getState().setGenerationStatus({ | ||
| phase: 'analyzing', | ||
| progress: 0, | ||
| message: 'Starting roadmap generation...' | ||
| }); | ||
| window.electronAPI.generateRoadmap(projectId, enableCompetitorAnalysis, refreshCompetitorAnalysis); | ||
| window.electronAPI.generateRoadmap(projectId, enableCompetitorAnalysis, refreshCompetitorAnalysis, language); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider adding explicit language fallback for consistency.
Both generateRoadmap and refreshRoadmap pass undefined as the language parameter when settings fetch fails. While the backend likely has its own fallback, the main process (execution-handlers.ts) explicitly defaults to 'en' when language cannot be read from settings.
For consistency across the codebase, consider using an explicit fallback:
🔎 Proposed change for consistent fallback
// Get current language from settings
const settings = await window.electronAPI.getSettings();
- const language = settings.success ? settings.data?.language : undefined;
+ const language = settings.success ? (settings.data?.language || 'en') : 'en';Apply to both generateRoadmap (line 309) and refreshRoadmap (line 331).
Also applies to: 329-339
🤖 Prompt for AI Agents
In apps/frontend/src/renderer/stores/roadmap-store.ts around lines 307-316 (and
similarly 329-339), the language variable is set to undefined when settings
fetch fails which causes inconsistent fallbacks across the codebase; change the
assignment to use an explicit fallback (e.g., 'en') so that when
settings.success is false you pass 'en' into window.electronAPI.generateRoadmap
and window.electronAPI.refreshRoadmap instead of undefined, ensuring both calls
supply a concrete language value.
| // File explorer operations | ||
| FILE_EXPLORER_LIST: 'fileExplorer:list', | ||
| FILE_OPEN: 'open-file', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider consistent naming for FILE_OPEN channel.
The FILE_OPEN: 'open-file' value doesn't follow the namespace:action pattern used by other channels (e.g., FILE_EXPLORER_LIST: 'fileExplorer:list'). Consider using 'file:open' or 'fileExplorer:open' for consistency.
🔎 Proposed fix
// File explorer operations
FILE_EXPLORER_LIST: 'fileExplorer:list',
- FILE_OPEN: 'open-file',
+ FILE_OPEN: 'file:open',Note: This would require updating the handler registration in file-handlers.ts to use IPC_CHANNELS.FILE_OPEN as well.
📝 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.
| // File explorer operations | |
| FILE_EXPLORER_LIST: 'fileExplorer:list', | |
| FILE_OPEN: 'open-file', | |
| // File explorer operations | |
| FILE_EXPLORER_LIST: 'fileExplorer:list', | |
| FILE_OPEN: 'file:open', |
🤖 Prompt for AI Agents
In apps/frontend/src/shared/constants/ipc.ts around lines 348 to 350, the
FILE_OPEN channel value ('open-file') breaks the established 'namespace:action'
naming convention; change it to a namespaced form like 'file:open' or
'fileExplorer:open' and then update any registrations/usages (e.g., in
file-handlers.ts and any IPC senders/listeners) to reference
IPC_CHANNELS.FILE_OPEN so all handlers and callers use the new constant name
consistently.
| # 🔍 הסבר מפורט על בעיות האימות | ||
|
|
||
| ## 📊 סיכום הבעיות שזוהו: | ||
|
|
||
| ### ❌ 1. **Claude Authentication** - 401 Unauthorized | ||
| ``` | ||
| [UsageMonitor] CLI fallback not implemented, API method should be used | ||
| [UsageMonitor] Failed to fetch usage | ||
| Claude CLI not found. Please ensure it is installed and in your PATH. | ||
| ``` | ||
|
|
||
| ### ❌ 2. **GitHub Authentication** - טוקן לא תקין | ||
| ``` | ||
| [GitHub OAuth] Auth check failed (not authenticated): Command failed | ||
| The token in GITHUB_TOKEN is invalid. | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 🎯 מה באמת קורה כאן? | ||
|
|
||
| ### בעיה 1: Claude - אין Claude CLI מותקן | ||
|
|
||
| #### **מה הקוד מנסה לעשות:** | ||
|
|
||
| 1. **UsageMonitor** מנסה לבדוק שימוש ב-Claude API | ||
| 2. אם API נכשל (401) → מנסה **fallback ל-CLI** | ||
| 3. אבל ה-CLI לא מיושם! (קוד ריק): | ||
|
|
||
| ```typescript | ||
| // מ-usage-monitor.ts שורה 234 | ||
| private async fetchUsageViaCLI( | ||
| _profileId: string, | ||
| _profileName: string | ||
| ): Promise<ClaudeUsageSnapshot | null> { | ||
| // CLI-based usage fetching is not implemented yet. | ||
| console.warn('[UsageMonitor] CLI fallback not implemented, API method should be used'); | ||
| return null; // ← תמיד מחזיר null! | ||
| } | ||
| ``` | ||
|
|
||
| #### **למה זה קורה:** | ||
| - אין Claude CLI מותקן במערכת שלך | ||
| - גם אם היה מותקן, הקוד לא מיושם | ||
| - **זו לא בעיה בשמירת טוקן** - זו בעיה שאין טוקן בכלל! | ||
|
|
||
| --- | ||
|
|
||
| ### בעיה 2: GitHub - טוקן ישן חוסם את gh CLI | ||
|
|
||
| #### **מה הקוד מנסה לעשות:** | ||
|
|
||
| 1. המערכת שומרת `GITHUB_TOKEN` ב-`.env` (אם הוגדר) | ||
| 2. כשמפעילים `gh auth login`, ה-CLI אומר: | ||
| > "אני רואה שיש `GITHUB_TOKEN` ב-environment, אני לא יכול להתחבר כי הוא חוסם אותי" | ||
|
|
||
| #### **איפה הטוקן נשמר:** | ||
|
|
||
| מהקוד ב-`env-handlers.ts`: | ||
| ```typescript | ||
| // שורה 57 | ||
| existingVars['GITHUB_TOKEN'] = config.githubToken; | ||
|
|
||
| // שורה 133 - כתיבה ל-.env | ||
| ${existingVars['GITHUB_TOKEN'] ? `GITHUB_TOKEN=${existingVars['GITHUB_TOKEN']}` : '# GITHUB_TOKEN='} | ||
| ``` | ||
|
|
||
| #### **למה זה חוסם:** | ||
| - `gh auth login --web` לא יכול לעבוד אם יש `GITHUB_TOKEN` ב-environment | ||
| - זה מנגנון אבטחה של GitHub CLI | ||
| - צריך **למחוק את הטוקן הישן קודם** | ||
|
|
||
| --- | ||
|
|
||
| ## 🔧 הפתרונות המדויקים: | ||
|
|
||
| ### פתרון 1: Claude - התקנת Claude CLI | ||
|
|
||
| #### אופציה A: דרך npm (מומלץ) | ||
| ```powershell | ||
| npm install -g @anthropic-ai/claude-cli | ||
| ``` | ||
|
|
||
| #### אופציה B: דרך pip | ||
| ```powershell | ||
| pip install claude-cli | ||
| ``` | ||
|
|
||
| #### אופציה C: התחבר בלי CLI (עדכון קוד) | ||
| **אם אתה לא רוצה להתקין CLI**, צריך לעקוף את הנפילה ל-CLI: | ||
|
|
||
| --- | ||
|
|
||
| ### פתרון 2: GitHub - ניקוי טוקן ישן | ||
|
|
||
| #### שיטה A: דרך PowerShell (מהיר) | ||
| ```powershell | ||
| # מחק את GITHUB_TOKEN מה-environment | ||
| [System.Environment]::SetEnvironmentVariable('GITHUB_TOKEN', $null, 'User') | ||
| [System.Environment]::SetEnvironmentVariable('GITHUB_TOKEN', $null, 'Process') | ||
|
|
||
| # אתחל את הטרמינל | ||
| exit | ||
| # פתח טרמינל חדש | ||
|
|
||
| # עכשיו נסה שוב | ||
| gh auth login --web --scopes repo | ||
| ``` | ||
|
|
||
| #### שיטה B: דרך הממשק (מומלץ) | ||
| 1. עבור ל: **Settings > Environment Variables** | ||
| 2. מצא את `GITHUB_TOKEN` | ||
| 3. **מחק** או **השבת** אותו | ||
| 4. **Save Settings** | ||
| 5. **אתחל את האפליקציה** | ||
| 6. נסה: **Settings > Gitxxxxxxxxxxxxxxxxct** | ||
|
|
||
| #### שיטה C: עריכת .env ידנית | ||
| ```powershell | ||
| # ערוך את הקובץ | ||
| notepad "$env:USERPROFILE\.auto-claude\.env" | ||
|
|
||
| # מצא את השורה: | ||
| GITHUB_TOKEN=ghp_xxxxxxxxxxxxx | ||
|
|
||
| # שנה ל: | ||
| # GITHUB_TOKEN= | ||
|
|
||
| # שמור וסגור | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 🎭 האם הקוד מנסה לחבר דרך דפדפן? | ||
|
|
||
| ### תשובה: **כן, אבל רק ל-GitHub (לא ל-Claude)** | ||
|
|
||
| מה-`oauth-handlers.ts` שראינו: | ||
|
|
||
| ```typescript | ||
| // שורה 5 | ||
| import { shell } from 'electron'; | ||
|
|
||
| // מאוחר יותר בקוד: | ||
| await shell.openExternal(authUrl); // ← פותח דפדפן! | ||
| ``` | ||
|
|
||
| #### **מתי זה קורה:** | ||
| - רק כש**אתה לוחץ** על "Connect GitHub" | ||
| - GitHub OAuth דורש אישור בדפדפן | ||
| - זה **לא אוטומטי** - רק לפי בקשה שלך | ||
|
|
||
| #### **ל-Claude:** | ||
| - **אין** חיבור דרך דפדפן | ||
| - רק API עם OAuth token | ||
| - אם אין טוקן - פשוט נכשל | ||
|
|
||
| --- | ||
|
|
||
| ## 🧩 למה זה "שומר את הטוקן"? | ||
|
|
||
| ### הקוד שמציג מה אתה רואה: | ||
|
|
||
| ```typescript | ||
| // מ-env-handlers.ts | ||
| // כשקוראים הגדרות: | ||
| if (vars['GITHUB_TOKEN']) { | ||
| config.githubToken = vars['GITHUB_TOKEN']; | ||
| } | ||
|
|
||
| // כששומרים הגדרות: | ||
| existingVars['GITHUB_TOKEN'] = config.githubToken; | ||
| ``` | ||
|
|
||
| ### מה זה אומר: | ||
| 1. ✅ **כן, הקוד שומר טוקן** - זה נורמלי | ||
| 2. ✅ **זה נכון** - כך המערכת זוכרת את החיבור | ||
| 3. ❌ **הבעיה:** הטוקן **ישן/לא תקף** | ||
| 4. 🔧 **הפתרון:** צריך **למחוק אותו ולהתחבר מחדש** | ||
|
|
||
| --- | ||
|
|
||
| ## 📋 סדר פעולות מומלץ: | ||
|
|
||
| ### שלב 1: תקן GitHub (קריטי) | ||
| ```powershell | ||
| # 1. מחק environment variable | ||
| $env:GITHUB_TOKEN = $null | ||
| [System.Environment]::SetEnvironmentVariable('GITHUB_TOKEN', $null, 'User') | ||
|
|
||
| # 2. נקה את ה-gh CLI cache | ||
| Remove-Item "$env:APPDATA\GitHub CLI\hosts.yml" -ErrorAction SilentlyContinue | ||
|
|
||
| # 3. התחבר מחדש | ||
| gh auth login --web --scopes repo | ||
|
|
||
| # 4. בדוק שעובד | ||
| gh auth status | ||
| ``` | ||
|
|
||
| **תוצאה צפויה:** | ||
| ``` | ||
| ✓ Logged in to github.com as YOUR_USERNAME | ||
| ✓ Token: gho_xxxxxxxxxxxxx | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### שלב 2: תקן Claude (אופציונלי אם אתה משתמש ב-Claude) | ||
|
|
||
| #### אם **אתה צריך** UsageMonitor: | ||
| ```powershell | ||
| # התקן Claude CLI | ||
| npm install -g @anthropic-ai/claude-cli | ||
|
|
||
| # התחבר | ||
| claude auth login | ||
|
|
||
| # בדוק | ||
| claude config get oauth_token | ||
| ``` | ||
|
|
||
| #### אם **אתה לא צריך** UsageMonitor: | ||
| השבת אותו בקוד (אני יכול לעזור עם זה). | ||
|
|
||
| --- | ||
|
|
||
| ### שלב 3: וידוא | ||
| ```powershell | ||
| # הפעל מחדש | ||
| cd C:\Users\Koperberg\Auto-Claude | ||
| npm run dev | ||
| ``` | ||
|
|
||
| **חפש בלוגים:** | ||
| ``` | ||
| ✅ [GitHub OAuth] Auth check passed (authenticated) | ||
| ✅ [UsageMonitor] Successfully fetched via API (אם התקנת Claude CLI) | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 🎯 שאלות נפוצות: | ||
|
|
||
| ### ש: "למה הקוד לא אומר לי שהטוקן ישן?" | ||
| **ת:** כי `gh auth login` רק בודק אם יש `GITHUB_TOKEN` ב-environment - לא אם הוא תקף. | ||
|
|
||
| ### ש: "איך אני מונע שטוקן יהיה ישן?" | ||
| **ת:** | ||
| 1. GitHub tokens יכולים לפוג (expiration date) | ||
| 2. אם מחקת אותו ב-GitHub.com | ||
| 3. אם שינית הרשאות | ||
|
|
||
| **פתרון:** השתמש ב-`gh auth refresh` כל כמה שבועות. | ||
|
|
||
| ### ש: "האפליקציה פותחת דפדפן אוטומטית?" | ||
| **ת:** **לא.** רק כשאתה לוחץ "Connect GitHub" בהגדרות. | ||
|
|
||
| ### ש: "אני צריך Claude CLI?" | ||
| **ת:** **לא חובה** אם אתה לא משתמש ב-UsageMonitor. אפשר להשבית אותו. | ||
|
|
||
| --- | ||
|
|
||
| ## ✅ סיכום: | ||
|
|
||
| | בעיה | סיבה | פתרון | | ||
| |------|------|--------| | ||
| | Claude 401 | אין CLI מותקן | התקן: `npm install -g @anthropic-ai/claude-cli` | | ||
| | GitHub token invalid | טוקן ישן חוסם | מחק: `$env:GITHUB_TOKEN = $null` והתחבר מחדש | | ||
| | Browser opens | GitHub OAuth זקוק לאישור | נורמלי - רק כשלוחצים "Connect" | | ||
| | Token saving | המערכת זוכרת חיבור | נורמלי - זו תכונה, לא באג | | ||
|
|
||
| --- | ||
|
|
||
| **נוצר:** 30 בדצמבר 2025 | ||
| **סטטוס:** מחכה לניקוי GITHUB_TOKEN והתקנת Claude CLI | ||
| **Priority:** 🔥 HIGH - חוסם GitHub operations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Markdown formatting issues flagged by linter.
Static analysis detected multiple markdown formatting issues:
- Missing blank lines around headings (MD022)
- Missing blank lines around code blocks (MD031)
- Code blocks without language specifiers (MD040)
- Trailing space at line 249 (MD009)
While these don't affect content accuracy, fixing them improves readability and consistency.
🔎 Example fixes
### ❌ 1. **Claude Authentication** - 401 Unauthorized
+[UsageMonitor] CLI fallback not implemented...
+
### ❌ 2. **GitHub Authentication** - טוקן לא תקין
Add a blank line before and after each code block and heading throughout the document.
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
5-5: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
6-6: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
6-6: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
12-12: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
13-13: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
13-13: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
42-42: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
60-60: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
68-68: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
79-79: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
80-80: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
84-84: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
85-85: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
89-89: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
96-96: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
97-97: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
110-110: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
118-118: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
119-119: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
148-148: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
153-153: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
175-175: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
185-185: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
186-186: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
202-202: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
202-202: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
211-211: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
212-212: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
223-223: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
228-228: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
229-229: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
236-236: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
236-236: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
245-245: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
248-248: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
249-249: Trailing spaces
Expected: 0 or 2; Actual: 1
(MD009, no-trailing-spaces)
256-256: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
259-259: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🤖 Prompt for AI Agents
In AUTH_ISSUES_EXPLAINED.md around lines 1 to 277, the linter flagged markdown
formatting problems (MD022, MD031, MD040, MD009); fix by adding a blank line
before and after every heading and each fenced code block, ensure every fenced
code block includes a language specifier (e.g., ```typescript or ```powershell)
where appropriate, remove the trailing whitespace on line 249, and then re-run
markdownlint to confirm all MD022/MD031/MD040/MD009 violations are cleared.
| 6. נסה: **Settings > Gitxxxxxxxxxxxxxxxxct** | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrupted text detected in the documentation.
Line 116 contains Gitxxxxxxxxxxxxxxxxct which appears to be corrupted or placeholder text. This should likely be "GitHub Connect" or similar.
🔎 Proposed fix
-6. נסה: **Settings > Gitxxxxxxxxxxxxxxxxct**
+6. נסה: **Settings > GitHub Connect**📝 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.
| 6. נסה: **Settings > Gitxxxxxxxxxxxxxxxxct** | |
| 6. נסה: **Settings > GitHub Connect** |
🤖 Prompt for AI Agents
In AUTH_ISSUES_EXPLAINED.md around lines 116-117, the text
"Gitxxxxxxxxxxxxxxxxct" is corrupted; replace it with the intended label (e.g.,
"GitHub Connect") so the line reads something like: "6. נסה: **Settings > GitHub
Connect**" and verify surrounding formatting/encoding remains UTF-8.
🌐 Internationalization Infrastructure & Hebrew Translation
Overview
This PR introduces a complete internationalization (i18n) infrastructure for Auto-Claude and implements full Hebrew (RTL) language support as the first non-English language.
✨ Key Features
1. 🏗️ i18n Infrastructure
2. 🇮🇱 Hebrew Translation (First Implementation)
3. 🎨 UI/UX Improvements
📦 Technical Implementation
Translation Files Structure
Key Components Updated
🔧 How to Add New Languages
locales/[lang-code]/en/as templatesSUPPORTED_LANGUAGESini18n/index.tsdir="rtl"support✅ Testing
📁 Files Changed
Core i18n Infrastructure:
apps/frontend/src/shared/i18n/index.ts- i18n setupapps/frontend/src/shared/constants/i18n.ts- constantsEnglish Translations (extracted):
locales/en/Hebrew Translations (new):
locales/he/Components Updated:
useTranslation()hookDocumentation:
INSIGHTS_IMPROVEMENTS.md- roadmap for chat enhancements🎯 Impact
This PR enables:
🚀 Future Work
After this PR, contributors can easily add:
Contributor: @sumca1
Languages Added: Hebrew (עברית) 🇮🇱
Type: Feature - Internationalization Infrastructure
Breaking Changes: None
Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.