Stop autonomous agent after Linear project is feature-complete
This commit is contained in:
@@ -330,3 +330,5 @@ Pour créer une nouvelle application :
|
|||||||
5. **Suivez le progrès** dans Linear
|
5. **Suivez le progrès** dans Linear
|
||||||
|
|
||||||
Le framework s'occupe du reste ! 🚀
|
Le framework s'occupe du reste ! 🚀
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
30
agent.py
30
agent.py
@@ -42,11 +42,13 @@ async def run_agent_session(
|
|||||||
Returns:
|
Returns:
|
||||||
(status, response_text) where status is:
|
(status, response_text) where status is:
|
||||||
- "continue" if agent should continue working
|
- "continue" if agent should continue working
|
||||||
|
- "done" if the project appears to be complete
|
||||||
- "error" if an error occurred
|
- "error" if an error occurred
|
||||||
"""
|
"""
|
||||||
print("Sending prompt to Claude Agent SDK...\n")
|
print("Sending prompt to Claude Agent SDK...\n")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
project_done = False
|
||||||
# Send the query
|
# Send the query
|
||||||
await client.query(message)
|
await client.query(message)
|
||||||
|
|
||||||
@@ -63,7 +65,14 @@ async def run_agent_session(
|
|||||||
if block_type == "TextBlock" and hasattr(block, "text"):
|
if block_type == "TextBlock" and hasattr(block, "text"):
|
||||||
response_text += block.text
|
response_text += block.text
|
||||||
print(block.text, end="", flush=True)
|
print(block.text, end="", flush=True)
|
||||||
|
# Early guard: if the assistant declares the project feature-complete,
|
||||||
|
# we stop streaming and end the loop as "done" to avoid extra work.
|
||||||
|
if "feature-complete" in block.text.lower():
|
||||||
|
project_done = True
|
||||||
|
break
|
||||||
elif block_type == "ToolUseBlock" and hasattr(block, "name"):
|
elif block_type == "ToolUseBlock" and hasattr(block, "name"):
|
||||||
|
if project_done:
|
||||||
|
break
|
||||||
print(f"\n[Tool: {block.name}]", flush=True)
|
print(f"\n[Tool: {block.name}]", flush=True)
|
||||||
if hasattr(block, "input"):
|
if hasattr(block, "input"):
|
||||||
input_str = str(block.input)
|
input_str = str(block.input)
|
||||||
@@ -74,6 +83,9 @@ async def run_agent_session(
|
|||||||
|
|
||||||
# Handle UserMessage (tool results)
|
# Handle UserMessage (tool results)
|
||||||
elif msg_type == "UserMessage" and hasattr(msg, "content"):
|
elif msg_type == "UserMessage" and hasattr(msg, "content"):
|
||||||
|
if project_done:
|
||||||
|
# Ignore further tool results once we've determined the project is done
|
||||||
|
continue
|
||||||
for block in msg.content:
|
for block in msg.content:
|
||||||
block_type = type(block).__name__
|
block_type = type(block).__name__
|
||||||
|
|
||||||
@@ -92,7 +104,20 @@ async def run_agent_session(
|
|||||||
# Tool succeeded - just show brief confirmation
|
# Tool succeeded - just show brief confirmation
|
||||||
print(" [Done]", flush=True)
|
print(" [Done]", flush=True)
|
||||||
|
|
||||||
|
if project_done:
|
||||||
|
# Stop processing further streamed messages
|
||||||
|
break
|
||||||
|
|
||||||
print("\n" + "-" * 70 + "\n")
|
print("\n" + "-" * 70 + "\n")
|
||||||
|
|
||||||
|
# Detect completion signals in the assistant's response to stop the loop
|
||||||
|
lower_text = response_text.lower()
|
||||||
|
if (
|
||||||
|
"feature-complete" in lower_text
|
||||||
|
or ("all" in lower_text and "issues" in lower_text and "completed" in lower_text)
|
||||||
|
):
|
||||||
|
return "done", response_text
|
||||||
|
|
||||||
return "continue", response_text
|
return "continue", response_text
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -205,6 +230,11 @@ async def run_autonomous_agent(
|
|||||||
print("Will retry with a fresh session...")
|
print("Will retry with a fresh session...")
|
||||||
await asyncio.sleep(AUTO_CONTINUE_DELAY_SECONDS)
|
await asyncio.sleep(AUTO_CONTINUE_DELAY_SECONDS)
|
||||||
|
|
||||||
|
elif status == "done":
|
||||||
|
print("\nAgent reports that the project is complete (all issues done).")
|
||||||
|
print_progress_summary(project_dir)
|
||||||
|
break
|
||||||
|
|
||||||
# Small delay between sessions
|
# Small delay between sessions
|
||||||
if max_iterations is None or iteration < max_iterations:
|
if max_iterations is None or iteration < max_iterations:
|
||||||
print("\nPreparing next session...\n")
|
print("\nPreparing next session...\n")
|
||||||
|
|||||||
179
prompts/app_spec_language_selection.completion.txt
Normal file
179
prompts/app_spec_language_selection.completion.txt
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
<project_specification>
|
||||||
|
<project_name>Language selection & i18n completion (FR default, EN/FR only)</project_name>
|
||||||
|
|
||||||
|
<overview>
|
||||||
|
This specification complements the existing "app_spec_language_selection.txt" file.
|
||||||
|
It does NOT replace the original spec. Instead, it adds additional requirements and
|
||||||
|
corrective steps to fully complete the language selection and i18n implementation.
|
||||||
|
|
||||||
|
Main goals:
|
||||||
|
- Support exactly two UI languages: English ("en") and French ("fr").
|
||||||
|
- Make French ("fr") the default language when no preference exists.
|
||||||
|
- Ensure that all user-facing text is translated via the i18n system (no hardcoded strings).
|
||||||
|
- Align the language selector UI with the actual supported languages.
|
||||||
|
</overview>
|
||||||
|
|
||||||
|
<relationship_to_original_spec>
|
||||||
|
- The original file "app_spec_language_selection.txt" defines the initial language selection
|
||||||
|
feature and i18n architecture (context, translation files, etc.).
|
||||||
|
- This completion spec:
|
||||||
|
* keeps that architecture,
|
||||||
|
* tightens some requirements (FR as default),
|
||||||
|
* and adds missing work items (removal of hardcoded English strings, cleanup of extra languages).
|
||||||
|
- The original spec remains valid; this completion spec should be applied on top of it.
|
||||||
|
</relationship_to_original_spec>
|
||||||
|
|
||||||
|
<constraints>
|
||||||
|
- Officially supported UI languages:
|
||||||
|
* English ("en")
|
||||||
|
* French ("fr")
|
||||||
|
- Default language:
|
||||||
|
* French ("fr") MUST be the default language when there is no stored preference.
|
||||||
|
- No other languages (es, de, ja, etc.) are considered part of this completion scope.
|
||||||
|
They may be added later in a separate spec with full translation coverage.
|
||||||
|
- The existing i18n architecture (LanguageContext, useLanguage hook, en.json, fr.json)
|
||||||
|
must be reused, not replaced.
|
||||||
|
</constraints>
|
||||||
|
|
||||||
|
<current_state_summary>
|
||||||
|
- LanguageContext and useLanguage already exist and manage language + translations.
|
||||||
|
- en.json and fr.json exist with a significant subset of strings translated.
|
||||||
|
- Some components already call t('...') correctly (e.g. welcome screen, many settings labels).
|
||||||
|
- However:
|
||||||
|
* Many UI strings are still hardcoded in English in "src/App.jsx".
|
||||||
|
* The language selector UI mentions more languages than are actually implemented.
|
||||||
|
* The default language behavior is not explicitly enforced as French.
|
||||||
|
</current_state_summary>
|
||||||
|
|
||||||
|
<target_state>
|
||||||
|
- French is used as the default language for new/anonymous users.
|
||||||
|
- Only English and French appear in the language selector.
|
||||||
|
- All user-facing UI strings in "src/App.jsx" and its inline components use t('key').
|
||||||
|
- Every key used by the UI is defined in both en.json and fr.json.
|
||||||
|
- No leftover English UI text appears when French is selected.
|
||||||
|
</target_state>
|
||||||
|
|
||||||
|
<implementation_details>
|
||||||
|
<default_language>
|
||||||
|
- In the language context code:
|
||||||
|
* Ensure there is a constant DEFAULT_LANGUAGE set to "fr".
|
||||||
|
Example:
|
||||||
|
const DEFAULT_LANGUAGE = 'fr';
|
||||||
|
- Initial language resolution MUST follow this order:
|
||||||
|
1. If a valid language ("en" or "fr") is found in localStorage, use it.
|
||||||
|
2. Otherwise, fall back to DEFAULT_LANGUAGE = "fr".
|
||||||
|
- This guarantees that first-time users and users without a stored preference see the UI in French.
|
||||||
|
</default_language>
|
||||||
|
|
||||||
|
<supported_languages>
|
||||||
|
- SUPPORTED_LANGUAGES must contain exactly:
|
||||||
|
* { code: 'en', name: 'English', nativeName: 'English' }
|
||||||
|
* { code: 'fr', name: 'French', nativeName: 'Français' }
|
||||||
|
- The Settings > Language dropdown must iterate only over SUPPORTED_LANGUAGES.
|
||||||
|
- Any explicit references to "es", "de", "ja" as selectable languages must be removed
|
||||||
|
or commented out as "future languages" (but not shown to users).
|
||||||
|
</supported_languages>
|
||||||
|
|
||||||
|
<hardcoded_strings_audit>
|
||||||
|
- Perform a systematic audit of "src/App.jsx" to identify every user-visible English string
|
||||||
|
that is still hardcoded. Typical areas include:
|
||||||
|
* ThemePreview sample messages (e.g. “Hello! Can you help me with something?”).
|
||||||
|
* About section in Settings > General (product name, description, “Built with …” text).
|
||||||
|
* Default model description and option labels.
|
||||||
|
* Project modals: “Cancel”, “Save Changes”, etc.
|
||||||
|
* Any toasts, confirmation messages, help texts, or labels still in English.
|
||||||
|
- For each identified string:
|
||||||
|
* Define a stable translation key (e.g. "themePreview.sampleUser1",
|
||||||
|
"settings.defaultModelDescription", "projectModal.cancel", "projectModal.saveChanges").
|
||||||
|
* Add this key to both en.json and fr.json.
|
||||||
|
</hardcoded_strings_audit>
|
||||||
|
|
||||||
|
<refactor_to_use_t>
|
||||||
|
- Replace each hardcoded string with a call to the translation function, for example:
|
||||||
|
BEFORE:
|
||||||
|
<p>Hello! Can you help me with something?</p>
|
||||||
|
AFTER:
|
||||||
|
<p>{t('themePreview.sampleUser1')}</p>
|
||||||
|
- Ensure that:
|
||||||
|
* The component (or function) imports useLanguage.
|
||||||
|
* const { t } = useLanguage() is declared in the correct scope.
|
||||||
|
- Apply this systematically across:
|
||||||
|
* Settings / General and Appearance sections.
|
||||||
|
* Theme preview component.
|
||||||
|
* Project-related modals.
|
||||||
|
* Any remaining banners, tooltips, or messages defined inside App.jsx.
|
||||||
|
</refactor_to_use_t>
|
||||||
|
|
||||||
|
<translation_files_update>
|
||||||
|
- Update translations/en.json:
|
||||||
|
* Add all new keys with natural English text.
|
||||||
|
- Update translations/fr.json:
|
||||||
|
* Add the same keys with accurate French translations.
|
||||||
|
- Goal:
|
||||||
|
* For every key used in code, both en.json and fr.json must contain a value.
|
||||||
|
</translation_files_update>
|
||||||
|
|
||||||
|
<fallback_behavior>
|
||||||
|
- Keep existing fallback behavior in LanguageContext:
|
||||||
|
* If a key is missing in the current language, fall back to English.
|
||||||
|
* If the key is also missing in English, return the key and log a warning.
|
||||||
|
- However, after this completion spec is implemented:
|
||||||
|
* No fallback warnings should appear in normal operation, because all keys are defined.
|
||||||
|
</fallback_behavior>
|
||||||
|
|
||||||
|
<settings_language_section>
|
||||||
|
- In the Settings > General tab:
|
||||||
|
* The language section heading must be translated via t('settings.language').
|
||||||
|
* Any helper text/description for the language selector must also use t('...').
|
||||||
|
* The select's value is bound to the language from useLanguage.
|
||||||
|
* The onChange handler calls setLanguage(newLanguageCode).
|
||||||
|
- Expected behavior:
|
||||||
|
* Switching to French instantly updates the UI and saves "fr" in localStorage.
|
||||||
|
* Switching to English instantly updates the UI and saves "en" in localStorage.
|
||||||
|
</settings_language_section>
|
||||||
|
</implementation_details>
|
||||||
|
|
||||||
|
<testing_plan>
|
||||||
|
<manual_tests>
|
||||||
|
1. Clear the language preference from localStorage.
|
||||||
|
2. Load the application:
|
||||||
|
- Confirm that the UI is initially in French (FR as default).
|
||||||
|
3. Open the Settings modal and navigate to the General tab.
|
||||||
|
- Verify that the language selector shows only "Français" and "English".
|
||||||
|
4. Switch to English:
|
||||||
|
- Verify that Sidebar, Settings, Welcome screen, Chat area, and modals are all in English.
|
||||||
|
5. Refresh the page:
|
||||||
|
- Confirm that the UI stays in English (preference persisted).
|
||||||
|
6. Switch back to French and repeat quick checks to confirm all UI text is in French.
|
||||||
|
</manual_tests>
|
||||||
|
|
||||||
|
<coverage_checks>
|
||||||
|
- Check in both languages:
|
||||||
|
* Main/empty state (welcome screen).
|
||||||
|
* Chat area (input placeholder, send/stop/regenerate buttons).
|
||||||
|
* Sidebar (navigation sections, search placeholder, pinned/archived labels).
|
||||||
|
* Settings (all tabs).
|
||||||
|
* Project creation and edit modals.
|
||||||
|
* Delete/confirmation dialogs and any share/export flows.
|
||||||
|
- Confirm:
|
||||||
|
* In French, there is no remaining English UI text.
|
||||||
|
* In English, there is no accidental French UI text.
|
||||||
|
</coverage_checks>
|
||||||
|
|
||||||
|
<regression>
|
||||||
|
- Verify:
|
||||||
|
* Chat behavior is unchanged except for translated labels/text.
|
||||||
|
* Project operations (create/update/delete) still work.
|
||||||
|
* No new console errors appear when switching languages or reloading.
|
||||||
|
</regression>
|
||||||
|
</testing_plan>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- "app_spec_language_selection.txt" remains the original base spec.
|
||||||
|
- This completion spec ("app_spec_language_selection.completion.txt") is fully implemented.
|
||||||
|
- French is used as default language when no preference exists.
|
||||||
|
- Only English and French are presented in the language selector.
|
||||||
|
- All user-facing strings in App.jsx go through t('key') and exist in both en.json and fr.json.
|
||||||
|
- No stray English text is visible when the French language is selected.
|
||||||
|
</success_criteria>
|
||||||
|
</project_specification>
|
||||||
525
prompts/app_spec_language_selection.txt
Normal file
525
prompts/app_spec_language_selection.txt
Normal file
@@ -0,0 +1,525 @@
|
|||||||
|
<project_specification>
|
||||||
|
<project_name>Claude.ai Clone - Language Selection Bug Fix</project_name>
|
||||||
|
|
||||||
|
<overview>
|
||||||
|
This specification fixes a bug in the language selection functionality. The feature was
|
||||||
|
originally planned in the initial app_spec.txt (line 127: "Language preferences") and a UI
|
||||||
|
component already exists in the settings panel (App.jsx lines 1412-1419), but the functionality
|
||||||
|
is incomplete and non-functional.
|
||||||
|
|
||||||
|
Currently, there is a language selector dropdown in the settings with options for English,
|
||||||
|
Español, Français, Deutsch, and 日本語, but it lacks:
|
||||||
|
- State management for the selected language
|
||||||
|
- Event handlers (onChange) to handle language changes
|
||||||
|
- A translation system (i18n)
|
||||||
|
- Translation files (en.json, fr.json, etc.)
|
||||||
|
- Language context/provider
|
||||||
|
- Persistence of language preference
|
||||||
|
|
||||||
|
This bug fix will complete the implementation by adding the missing functionality so that when
|
||||||
|
a language is selected, the entire interface updates immediately to display all text in the
|
||||||
|
chosen language. The language preference should persist across sessions.
|
||||||
|
|
||||||
|
Focus will be on English (default) and French as the primary languages, with the existing
|
||||||
|
UI supporting additional languages for future expansion.
|
||||||
|
</overview>
|
||||||
|
|
||||||
|
<current_state>
|
||||||
|
<existing_ui>
|
||||||
|
Location: src/App.jsx, lines 1412-1419
|
||||||
|
Component: Language selector dropdown in settings panel (General/Preferences section)
|
||||||
|
Current options: English (en), Español (es), Français (fr), Deutsch (de), 日本語 (ja)
|
||||||
|
Status: UI exists but is non-functional (no onChange handler, no state, no translations)
|
||||||
|
</existing_ui>
|
||||||
|
|
||||||
|
<specification_reference>
|
||||||
|
Original spec: prompts/app_spec.txt, line 127
|
||||||
|
Mentioned as: "Language preferences" in settings_preferences section
|
||||||
|
Status: Feature was planned but not fully implemented
|
||||||
|
</specification_reference>
|
||||||
|
</current_state>
|
||||||
|
|
||||||
|
<safety_requirements>
|
||||||
|
<critical>
|
||||||
|
- DO NOT remove or modify the existing language selector UI (lines 1412-1419 in App.jsx)
|
||||||
|
- DO NOT break existing functionality when language is changed
|
||||||
|
- English must remain the default language
|
||||||
|
- Language changes should apply immediately without page refresh
|
||||||
|
- All translations must be complete (no missing translations)
|
||||||
|
- Maintain backward compatibility with existing code
|
||||||
|
- Language preference should be stored and persist across sessions
|
||||||
|
- Keep the existing dropdown structure and styling
|
||||||
|
- Connect the existing select element to the new translation system
|
||||||
|
</critical>
|
||||||
|
</safety_requirements>
|
||||||
|
|
||||||
|
<bug_fixes>
|
||||||
|
<fix_language_selection>
|
||||||
|
<title>Fix Language Selection Functionality</title>
|
||||||
|
<description>
|
||||||
|
Complete the implementation of the existing language selector in the settings menu.
|
||||||
|
The UI already exists (App.jsx lines 1412-1419) but needs to be made functional.
|
||||||
|
|
||||||
|
The fix should:
|
||||||
|
- Connect the existing select element to state management
|
||||||
|
- Add onChange handler to the existing select element
|
||||||
|
- Display current selected language (load from localStorage on mount)
|
||||||
|
- Apply language changes immediately to the entire interface
|
||||||
|
- Save language preference to localStorage
|
||||||
|
- Persist language choice across sessions
|
||||||
|
|
||||||
|
The existing selector is already in the correct location (General/Preferences section
|
||||||
|
of settings panel) and has the correct styling, so only the functionality needs to be added.
|
||||||
|
</description>
|
||||||
|
<priority>1</priority>
|
||||||
|
<category>bug_fix</category>
|
||||||
|
<type>completion_of_existing_feature</type>
|
||||||
|
<implementation_approach>
|
||||||
|
- Keep the existing select element in App.jsx (lines 1412-1419)
|
||||||
|
- Add useState hook to manage selected language state
|
||||||
|
- Add value prop to select element (bound to state)
|
||||||
|
- Add onChange handler to select element
|
||||||
|
- Load language preference from localStorage on component mount
|
||||||
|
- Save language preference to localStorage on change
|
||||||
|
- Create translation files/dictionaries for each language
|
||||||
|
- Implement language context/provider to manage current language
|
||||||
|
- Create translation utility function to retrieve translated strings
|
||||||
|
- Update all hardcoded text to use translation function
|
||||||
|
- Apply language changes reactively throughout the application
|
||||||
|
</implementation_approach>
|
||||||
|
<test_steps>
|
||||||
|
1. Open settings menu
|
||||||
|
2. Navigate to "General" or "Preferences" section
|
||||||
|
3. Locate the existing "Language" selector (should already be visible)
|
||||||
|
4. Verify the select element now has a value bound to state (not empty)
|
||||||
|
5. Verify default language is "English" (en) on first load
|
||||||
|
6. Select "Français" (fr) from the existing language dropdown
|
||||||
|
7. Verify onChange handler fires and updates state
|
||||||
|
8. Verify entire interface updates immediately to French
|
||||||
|
9. Check that all UI elements are translated (buttons, labels, menus)
|
||||||
|
10. Navigate to different pages and verify translations persist
|
||||||
|
11. Refresh the page and verify language preference is maintained (loaded from localStorage)
|
||||||
|
12. Switch back to "English" and verify interface returns to English
|
||||||
|
13. Test with new conversations and verify messages/UI are in selected language
|
||||||
|
14. Verify the existing select element styling and structure remain unchanged
|
||||||
|
</test_steps>
|
||||||
|
</fix_language_selection>
|
||||||
|
|
||||||
|
<fix_translation_system>
|
||||||
|
<title>Translation System Infrastructure</title>
|
||||||
|
<description>
|
||||||
|
Implement a translation system that:
|
||||||
|
- Stores translations for English and French
|
||||||
|
- Provides a translation function/utility to retrieve translated strings
|
||||||
|
- Supports dynamic language switching
|
||||||
|
- Handles missing translations gracefully (fallback to English)
|
||||||
|
- Organizes translations by feature/component
|
||||||
|
|
||||||
|
Translation keys should be organized logically:
|
||||||
|
- Common UI elements (buttons, labels, placeholders)
|
||||||
|
- Settings panel
|
||||||
|
- Chat interface
|
||||||
|
- Navigation menus
|
||||||
|
- Error messages
|
||||||
|
- Success messages
|
||||||
|
- Tooltips and help text
|
||||||
|
</description>
|
||||||
|
<priority>1</priority>
|
||||||
|
<category>infrastructure</category>
|
||||||
|
<type>new_implementation</type>
|
||||||
|
<implementation_approach>
|
||||||
|
- Create translation files (JSON or JS objects):
|
||||||
|
* translations/en.json (English)
|
||||||
|
* translations/fr.json (French)
|
||||||
|
- Create translation context/provider (React Context)
|
||||||
|
- Create useTranslation hook for components
|
||||||
|
- Create translation utility function (t() or translate())
|
||||||
|
- Organize translations by namespace/feature
|
||||||
|
- Implement fallback mechanism for missing translations
|
||||||
|
- Ensure type safety for translation keys (TypeScript if applicable)
|
||||||
|
</implementation_approach>
|
||||||
|
<test_steps>
|
||||||
|
1. Verify translation files exist for both languages
|
||||||
|
2. Test translation function with valid keys
|
||||||
|
3. Test translation function with invalid keys (should fallback)
|
||||||
|
4. Verify all translation keys have values in both languages
|
||||||
|
5. Test language switching updates all components
|
||||||
|
6. Verify no console errors when switching languages
|
||||||
|
</test_steps>
|
||||||
|
</fix_translation_system>
|
||||||
|
|
||||||
|
<fix_ui_translations>
|
||||||
|
<title>Complete UI Translation Coverage</title>
|
||||||
|
<description>
|
||||||
|
Translate all user-facing text in the application to support both English and French:
|
||||||
|
|
||||||
|
Navigation & Menus:
|
||||||
|
- Sidebar navigation items
|
||||||
|
- Menu labels
|
||||||
|
- Breadcrumbs
|
||||||
|
|
||||||
|
Chat Interface:
|
||||||
|
- Input placeholder text
|
||||||
|
- Send button
|
||||||
|
- Message status indicators
|
||||||
|
- Empty state messages
|
||||||
|
- Loading states
|
||||||
|
|
||||||
|
Settings:
|
||||||
|
- All setting section titles
|
||||||
|
- Setting option labels
|
||||||
|
- Setting descriptions
|
||||||
|
- Save/Cancel buttons
|
||||||
|
|
||||||
|
Buttons & Actions:
|
||||||
|
- Primary action buttons
|
||||||
|
- Secondary buttons
|
||||||
|
- Delete/Remove actions
|
||||||
|
- Edit actions
|
||||||
|
- Save actions
|
||||||
|
|
||||||
|
Messages & Notifications:
|
||||||
|
- Success messages
|
||||||
|
- Error messages
|
||||||
|
- Warning messages
|
||||||
|
- Info messages
|
||||||
|
|
||||||
|
Forms:
|
||||||
|
- Form labels
|
||||||
|
- Input placeholders
|
||||||
|
- Validation messages
|
||||||
|
- Help text
|
||||||
|
|
||||||
|
Modals & Dialogs:
|
||||||
|
- Modal titles
|
||||||
|
- Modal content
|
||||||
|
- Confirmation dialogs
|
||||||
|
- Cancel/Confirm buttons
|
||||||
|
</description>
|
||||||
|
<priority>1</priority>
|
||||||
|
<category>ui</category>
|
||||||
|
<type>translation_implementation</type>
|
||||||
|
<implementation_approach>
|
||||||
|
- Audit all hardcoded text in the application
|
||||||
|
- Replace all hardcoded strings with translation function calls
|
||||||
|
- Create translation keys for each text element
|
||||||
|
- Add French translations for all keys
|
||||||
|
- Test each screen/page to ensure complete translation coverage
|
||||||
|
- Verify no English text remains when French is selected
|
||||||
|
</implementation_approach>
|
||||||
|
<test_steps>
|
||||||
|
1. Set language to French
|
||||||
|
2. Navigate through all pages/screens
|
||||||
|
3. Verify every text element is translated
|
||||||
|
4. Check all buttons, labels, placeholders
|
||||||
|
5. Test all modals and dialogs
|
||||||
|
6. Verify form validation messages
|
||||||
|
7. Check error and success notifications
|
||||||
|
8. Verify no English text appears when French is selected
|
||||||
|
9. Repeat test with English to ensure nothing broke
|
||||||
|
</test_steps>
|
||||||
|
</fix_ui_translations>
|
||||||
|
|
||||||
|
<fix_language_persistence>
|
||||||
|
<title>Language Preference Persistence</title>
|
||||||
|
<description>
|
||||||
|
Ensure that the selected language preference is saved and persists across:
|
||||||
|
- Page refreshes
|
||||||
|
- Browser sessions
|
||||||
|
- Tab closures
|
||||||
|
- Application restarts
|
||||||
|
|
||||||
|
The language preference should be:
|
||||||
|
- Stored in localStorage (client-side) or backend user preferences
|
||||||
|
- Loaded on application startup
|
||||||
|
- Applied immediately when the app loads
|
||||||
|
- Synchronized if user is logged in (multi-device support)
|
||||||
|
</description>
|
||||||
|
<priority>1</priority>
|
||||||
|
<category>persistence</category>
|
||||||
|
<type>bug_fix</type>
|
||||||
|
<implementation_approach>
|
||||||
|
- Save language selection to localStorage on change
|
||||||
|
- Load language preference on app initialization
|
||||||
|
- Apply saved language before rendering UI
|
||||||
|
- Optionally sync with backend user preferences if available
|
||||||
|
- Handle case where no preference is saved (default to English)
|
||||||
|
</implementation_approach>
|
||||||
|
<test_steps>
|
||||||
|
1. Select French language
|
||||||
|
2. Refresh the page
|
||||||
|
3. Verify interface is still in French
|
||||||
|
4. Close browser tab and reopen
|
||||||
|
5. Verify language preference persists
|
||||||
|
6. Clear localStorage and verify defaults to English
|
||||||
|
7. Select language again and verify it saves
|
||||||
|
</test_steps>
|
||||||
|
</fix_language_persistence>
|
||||||
|
</bug_fixes>
|
||||||
|
|
||||||
|
<implementation_notes>
|
||||||
|
<existing_code>
|
||||||
|
Location: src/App.jsx, lines 1412-1419
|
||||||
|
Current code:
|
||||||
|
```jsx
|
||||||
|
<div>
|
||||||
|
<h3 className="text-sm font-medium text-gray-900 dark:text-gray-100 mb-3">Language</h3>
|
||||||
|
<select className="w-full px-3 py-2 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg text-sm text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-claude-orange focus:border-transparent">
|
||||||
|
<option value="en">English</option>
|
||||||
|
<option value="es">Español</option>
|
||||||
|
<option value="fr">Français</option>
|
||||||
|
<option value="de">Deutsch</option>
|
||||||
|
<option value="ja">日本語</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
Required changes:
|
||||||
|
- Add value={language} to select element
|
||||||
|
- Add onChange={(e) => setLanguage(e.target.value)} to select element
|
||||||
|
- Add useState for language state
|
||||||
|
- Load from localStorage on mount
|
||||||
|
- Save to localStorage on change
|
||||||
|
</existing_code>
|
||||||
|
|
||||||
|
<code_structure>
|
||||||
|
frontend/
|
||||||
|
src/
|
||||||
|
App.jsx # UPDATE: Add language state and connect existing select
|
||||||
|
components/
|
||||||
|
LanguageSelector.jsx # Optional: Extract to component if needed (NEW)
|
||||||
|
contexts/
|
||||||
|
LanguageContext.jsx # Language context provider (NEW)
|
||||||
|
hooks/
|
||||||
|
useLanguage.js # Hook to access language and translations (NEW)
|
||||||
|
utils/
|
||||||
|
translations.js # Translation utility functions (NEW)
|
||||||
|
translations/
|
||||||
|
en.json # English translations (NEW)
|
||||||
|
fr.json # French translations (NEW)
|
||||||
|
</code_structure>
|
||||||
|
|
||||||
|
<translation_structure>
|
||||||
|
Translation files should be organized by feature/namespace:
|
||||||
|
{
|
||||||
|
"common": {
|
||||||
|
"save": "Save",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"delete": "Delete",
|
||||||
|
"edit": "Edit",
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"title": "Settings",
|
||||||
|
"language": "Language",
|
||||||
|
"theme": "Theme",
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"chat": {
|
||||||
|
"placeholder": "Message Claude...",
|
||||||
|
"send": "Send",
|
||||||
|
...
|
||||||
|
},
|
||||||
|
...
|
||||||
|
}
|
||||||
|
</translation_structure>
|
||||||
|
|
||||||
|
<storage_approach>
|
||||||
|
Store language preference in:
|
||||||
|
- localStorage key: "app_language" (value: "en" or "fr")
|
||||||
|
- Or backend user preferences if available:
|
||||||
|
{
|
||||||
|
language: "en" | "fr"
|
||||||
|
}
|
||||||
|
|
||||||
|
Default value: "en" (English)
|
||||||
|
</storage_approach>
|
||||||
|
|
||||||
|
<translation_function>
|
||||||
|
Example implementation:
|
||||||
|
- useTranslation() hook returns { t, language, setLanguage }
|
||||||
|
- t(key) function retrieves translation for current language
|
||||||
|
- t("common.save") returns "Save" (en) or "Enregistrer" (fr)
|
||||||
|
- Supports nested keys: t("settings.general.title")
|
||||||
|
- Falls back to English if translation missing
|
||||||
|
</translation_function>
|
||||||
|
|
||||||
|
<safety_guidelines>
|
||||||
|
- Keep all existing functionality intact
|
||||||
|
- Default to English if no language preference set
|
||||||
|
- Gracefully handle missing translations (fallback to English)
|
||||||
|
- Ensure language changes don't cause re-renders that break functionality
|
||||||
|
- Test thoroughly to ensure no English text remains when French is selected
|
||||||
|
- Maintain code readability with clear translation key naming
|
||||||
|
</safety_guidelines>
|
||||||
|
</implementation_notes>
|
||||||
|
|
||||||
|
<ui_components>
|
||||||
|
<language_selector>
|
||||||
|
<description>Language selector component in settings (ALREADY EXISTS - needs functionality)</description>
|
||||||
|
<location>Settings > General/Preferences section (App.jsx lines 1412-1419)</location>
|
||||||
|
<current_state>
|
||||||
|
- UI exists with dropdown/select element
|
||||||
|
- Has 5 language options: English (en), Español (es), Français (fr), Deutsch (de), 日本語 (ja)
|
||||||
|
- Styling is already correct
|
||||||
|
- Missing: value binding, onChange handler, state management
|
||||||
|
</current_state>
|
||||||
|
<required_changes>
|
||||||
|
- Add value prop bound to language state
|
||||||
|
- Add onChange handler to update language state
|
||||||
|
- Connect to translation system
|
||||||
|
- Add persistence (localStorage)
|
||||||
|
</required_changes>
|
||||||
|
<display>
|
||||||
|
- Keep existing dropdown/select element (no UI changes needed)
|
||||||
|
- Shows current selection (via value prop)
|
||||||
|
- Updates interface immediately on change (via onChange)
|
||||||
|
</display>
|
||||||
|
</language_selector>
|
||||||
|
</ui_components>
|
||||||
|
|
||||||
|
<translation_coverage>
|
||||||
|
<required_translations>
|
||||||
|
All text visible to users must be translated:
|
||||||
|
- Navigation menu items
|
||||||
|
- Page titles and headers
|
||||||
|
- Button labels
|
||||||
|
- Form labels and placeholders
|
||||||
|
- Input field labels
|
||||||
|
- Error messages
|
||||||
|
- Success messages
|
||||||
|
- Tooltips
|
||||||
|
- Help text
|
||||||
|
- Modal titles and content
|
||||||
|
- Dialog confirmations
|
||||||
|
- Empty states
|
||||||
|
- Loading states
|
||||||
|
- Settings labels and descriptions
|
||||||
|
- Chat interface elements
|
||||||
|
</required_translations>
|
||||||
|
|
||||||
|
<translation_examples>
|
||||||
|
English -> French:
|
||||||
|
- "Settings" -> "Paramètres"
|
||||||
|
- "Save" -> "Enregistrer"
|
||||||
|
- "Cancel" -> "Annuler"
|
||||||
|
- "Delete" -> "Supprimer"
|
||||||
|
- "Language" -> "Langue"
|
||||||
|
- "Theme" -> "Thème"
|
||||||
|
- "Send" -> "Envoyer"
|
||||||
|
- "New Conversation" -> "Nouvelle conversation"
|
||||||
|
- "Message Claude..." -> "Message à Claude..."
|
||||||
|
</translation_examples>
|
||||||
|
</translation_coverage>
|
||||||
|
|
||||||
|
<api_endpoints>
|
||||||
|
<if_backend_storage>
|
||||||
|
If storing language preference in backend:
|
||||||
|
- GET /api/user/preferences - Get user preferences (includes language)
|
||||||
|
- PUT /api/user/preferences - Update user preferences (includes language)
|
||||||
|
- GET /api/user/preferences/language - Get language preference only
|
||||||
|
- PUT /api/user/preferences/language - Update language preference only
|
||||||
|
</if_backend_storage>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
If using localStorage only, no API endpoints needed.
|
||||||
|
Backend storage is optional but recommended for multi-device sync.
|
||||||
|
</note>
|
||||||
|
</api_endpoints>
|
||||||
|
|
||||||
|
<accessibility_requirements>
|
||||||
|
- Language selector must be keyboard navigable
|
||||||
|
- Language changes must be announced to screen readers
|
||||||
|
- Translation quality must be accurate (no machine translation errors)
|
||||||
|
- Text direction should be handled correctly (LTR for both languages)
|
||||||
|
- Font rendering should support both languages properly
|
||||||
|
</accessibility_requirements>
|
||||||
|
|
||||||
|
<testing_requirements>
|
||||||
|
<regression_tests>
|
||||||
|
- Verify existing functionality works in both languages
|
||||||
|
- Verify language change doesn't break any features
|
||||||
|
- Test that default language (English) still works as before
|
||||||
|
- Verify all existing features are accessible in both languages
|
||||||
|
</regression_tests>
|
||||||
|
|
||||||
|
<feature_tests>
|
||||||
|
- Test language selector in settings
|
||||||
|
- Test immediate language change on selection
|
||||||
|
- Test language persistence across page refresh
|
||||||
|
- Test language persistence across browser sessions
|
||||||
|
- Test all UI elements are translated
|
||||||
|
- Test translation fallback for missing keys
|
||||||
|
- Test switching between languages multiple times
|
||||||
|
- Verify no English text appears when French is selected
|
||||||
|
- Verify all pages/screens are translated
|
||||||
|
</feature_tests>
|
||||||
|
|
||||||
|
<translation_tests>
|
||||||
|
- Verify all translation keys have values in both languages
|
||||||
|
- Test translation accuracy (no machine translation errors)
|
||||||
|
- Verify consistent terminology across the application
|
||||||
|
- Test special characters and accents in French
|
||||||
|
- Verify text doesn't overflow UI elements in French (may be longer)
|
||||||
|
</translation_tests>
|
||||||
|
|
||||||
|
<compatibility_tests>
|
||||||
|
- Test with different browsers (Chrome, Firefox, Safari, Edge)
|
||||||
|
- Test with different screen sizes (responsive design)
|
||||||
|
- Test language switching during active conversations
|
||||||
|
- Test language switching with modals open
|
||||||
|
- Verify language preference syncs across tabs (if applicable)
|
||||||
|
</compatibility_tests>
|
||||||
|
</testing_requirements>
|
||||||
|
|
||||||
|
<summary>
|
||||||
|
<bug_description>
|
||||||
|
The language selection feature was planned in the original specification (app_spec.txt line 127)
|
||||||
|
and a UI component was created (App.jsx lines 1412-1419), but the implementation is incomplete.
|
||||||
|
The select dropdown exists but has no functionality - it lacks state management, event handlers,
|
||||||
|
and a translation system.
|
||||||
|
</bug_description>
|
||||||
|
|
||||||
|
<fix_scope>
|
||||||
|
This is a bug fix that completes the existing feature by:
|
||||||
|
1. Connecting the existing UI to state management
|
||||||
|
2. Adding the missing translation system
|
||||||
|
3. Implementing language persistence
|
||||||
|
4. Translating all UI text to support English and French
|
||||||
|
</fix_scope>
|
||||||
|
|
||||||
|
<key_principle>
|
||||||
|
DO NOT remove or significantly modify the existing language selector UI. Only add the
|
||||||
|
missing functionality to make it work.
|
||||||
|
</key_principle>
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
<functionality>
|
||||||
|
- Users can select language from the existing settings dropdown (English or French)
|
||||||
|
- Language changes apply immediately to entire interface
|
||||||
|
- Language preference persists across sessions
|
||||||
|
- All UI elements are translated when language is changed
|
||||||
|
- English remains the default language
|
||||||
|
- No functionality is broken by language changes
|
||||||
|
- The existing select element in App.jsx (lines 1412-1419) is now functional
|
||||||
|
</functionality>
|
||||||
|
|
||||||
|
<user_experience>
|
||||||
|
- Language selector is easy to find in settings
|
||||||
|
- Language change is instant and smooth
|
||||||
|
- All text is properly translated (no English text in French mode)
|
||||||
|
- Translations are accurate and natural
|
||||||
|
- Interface layout works well with both languages
|
||||||
|
</user_experience>
|
||||||
|
|
||||||
|
<technical>
|
||||||
|
- Translation system is well-organized and maintainable
|
||||||
|
- Translation keys are logically structured
|
||||||
|
- Language preference is stored reliably
|
||||||
|
- No performance degradation with language switching
|
||||||
|
- Code is clean and follows existing patterns
|
||||||
|
- Easy to add more languages in the future
|
||||||
|
</technical>
|
||||||
|
</success_criteria>
|
||||||
|
</project_specification>
|
||||||
@@ -130,3 +130,5 @@
|
|||||||
-->
|
-->
|
||||||
</deployment>
|
</deployment>
|
||||||
</project_specification>
|
</project_specification>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user