From dbc220053d28414835977ea00395efedeee857eb Mon Sep 17 00:00:00 2001 From: Nigel1992 Date: Sat, 29 Mar 2025 23:53:45 +0100 Subject: [PATCH 1/3] fix: improve Linux path handling for config file detection --- config.py | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/config.py b/config.py index 808f103..1f75a86 100644 --- a/config.py +++ b/config.py @@ -68,6 +68,9 @@ def setup_config(translator=None): 'updater_path': os.path.join(localappdata, "cursor-updater"), 'update_yml_path': os.path.join(localappdata, "Programs", "Cursor", "resources", "app-update.yml") } + # Create storage directory + os.makedirs(os.path.dirname(default_config['WindowsPaths']['storage_path']), exist_ok=True) + elif sys.platform == "darwin": default_config['MacPaths'] = { 'storage_path': os.path.abspath(os.path.expanduser("~/Library/Application Support/Cursor/User/globalStorage/storage.json")), @@ -77,17 +80,81 @@ def setup_config(translator=None): 'updater_path': os.path.expanduser("~/Library/Application Support/cursor-updater"), 'update_yml_path': "/Applications/Cursor.app/Contents/Resources/app-update.yml" } + # Create storage directory + os.makedirs(os.path.dirname(default_config['MacPaths']['storage_path']), exist_ok=True) + elif sys.platform == "linux": - sudo_user = os.environ.get('SUDO_USER') - actual_home = f"/home/{sudo_user}" if sudo_user else os.path.expanduser("~") + # Get the actual user's home directory, handling both sudo and normal cases + current_user = os.getenv('USER') or os.getenv('USERNAME') or os.getenv('SUDO_USER') + if not current_user: + current_user = os.path.expanduser('~').split('/')[-1] + + actual_home = f"/home/{current_user}" + if not os.path.exists(actual_home): + actual_home = os.path.expanduser("~") + + # Define Linux paths + storage_path = os.path.abspath(os.path.join(actual_home, ".config/cursor/User/globalStorage/storage.json")) + storage_dir = os.path.dirname(storage_path) + + # Verify paths and permissions + try: + # Check if Cursor config directory exists + cursor_config_dir = os.path.join(actual_home, ".config/cursor") + if not os.path.exists(cursor_config_dir): + print(f"{Fore.YELLOW}{EMOJI['WARNING']} Cursor config directory not found: {cursor_config_dir}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") + + # Check storage directory + if not os.path.exists(storage_dir): + print(f"{Fore.YELLOW}{EMOJI['WARNING']} Storage directory not found: {storage_dir}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") + + # Check storage.json with more detailed verification + if os.path.exists(storage_path): + # Get file stats + try: + stat = os.stat(storage_path) + print(f"{Fore.GREEN}{EMOJI['INFO']} Storage file found: {storage_path}{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['INFO']} File size: {stat.st_size} bytes{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['INFO']} File permissions: {oct(stat.st_mode & 0o777)}{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['INFO']} File owner: {stat.st_uid}{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['INFO']} File group: {stat.st_gid}{Style.RESET_ALL}") + except Exception as e: + print(f"{Fore.RED}{EMOJI['ERROR']} Error getting file stats: {str(e)}{Style.RESET_ALL}") + + # Check if file is readable and writable + if not os.access(storage_path, os.R_OK | os.W_OK): + print(f"{Fore.RED}{EMOJI['ERROR']} Permission denied: {storage_path}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} Try running: chown {current_user}:{current_user} {storage_path}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} And: chmod 644 {storage_path}{Style.RESET_ALL}") + + # Try to read the file to verify it's not corrupted + try: + with open(storage_path, 'r') as f: + content = f.read() + if not content.strip(): + print(f"{Fore.YELLOW}{EMOJI['WARNING']} Storage file is empty: {storage_path}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") + else: + print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Storage file is valid and contains data{Style.RESET_ALL}") + except Exception as e: + print(f"{Fore.RED}{EMOJI['ERROR']} Error reading storage file: {str(e)}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} The file might be corrupted. Please reinstall Cursor{Style.RESET_ALL}") + else: + print(f"{Fore.YELLOW}{EMOJI['WARNING']} Storage file not found: {storage_path}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") + + except (OSError, IOError) as e: + print(f"{Fore.RED}{EMOJI['ERROR']} Error checking Linux paths: {str(e)}{Style.RESET_ALL}") default_config['LinuxPaths'] = { - 'storage_path': os.path.abspath(os.path.join(actual_home, ".config/cursor/User/globalStorage/storage.json")), + 'storage_path': storage_path, 'sqlite_path': os.path.abspath(os.path.join(actual_home, ".config/cursor/User/globalStorage/state.vscdb")), - 'machine_id_path': os.path.expanduser("~/.config/cursor/machineid"), + 'machine_id_path': os.path.join(actual_home, ".config/cursor/machineid"), 'cursor_path': get_linux_cursor_path(), - 'updater_path': os.path.expanduser("~/.config/cursor-updater"), - 'update_yml_path': "/Applications/Cursor.app/Contents/Resources/app-update.yml" + 'updater_path': os.path.join(actual_home, ".config/cursor-updater"), + 'update_yml_path': os.path.join(actual_home, ".config/cursor/resources/app-update.yml") } # Read existing configuration and merge From f00678ddcbd8421f65efbd77037eecfbe70a3fac Mon Sep 17 00:00:00 2001 From: Nigel1992 Date: Sat, 29 Mar 2025 23:59:04 +0100 Subject: [PATCH 2/3] fix: add case-insensitive handling for Cursor/cursor directory --- config.py | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/config.py b/config.py index 1f75a86..82dfdd8 100644 --- a/config.py +++ b/config.py @@ -93,25 +93,34 @@ def setup_config(translator=None): if not os.path.exists(actual_home): actual_home = os.path.expanduser("~") - # Define Linux paths - storage_path = os.path.abspath(os.path.join(actual_home, ".config/cursor/User/globalStorage/storage.json")) - storage_dir = os.path.dirname(storage_path) + # Define base config directory + config_base = os.path.join(actual_home, ".config") + + # Try both "Cursor" and "cursor" directory names + cursor_dir = None + for dir_name in ["Cursor", "cursor"]: + test_dir = os.path.join(config_base, dir_name) + if os.path.exists(test_dir): + cursor_dir = test_dir + break + + if not cursor_dir: + print(f"{Fore.YELLOW}{EMOJI['WARNING']} Neither Cursor nor cursor directory found in {config_base}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") + + # Define Linux paths using the found cursor directory + storage_path = os.path.abspath(os.path.join(cursor_dir, "User/globalStorage/storage.json")) if cursor_dir else "" + storage_dir = os.path.dirname(storage_path) if storage_path else "" # Verify paths and permissions try: - # Check if Cursor config directory exists - cursor_config_dir = os.path.join(actual_home, ".config/cursor") - if not os.path.exists(cursor_config_dir): - print(f"{Fore.YELLOW}{EMOJI['WARNING']} Cursor config directory not found: {cursor_config_dir}{Style.RESET_ALL}") - print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") - # Check storage directory - if not os.path.exists(storage_dir): + if storage_dir and not os.path.exists(storage_dir): print(f"{Fore.YELLOW}{EMOJI['WARNING']} Storage directory not found: {storage_dir}{Style.RESET_ALL}") print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") # Check storage.json with more detailed verification - if os.path.exists(storage_path): + if storage_path and os.path.exists(storage_path): # Get file stats try: stat = os.stat(storage_path) @@ -141,20 +150,21 @@ def setup_config(translator=None): except Exception as e: print(f"{Fore.RED}{EMOJI['ERROR']} Error reading storage file: {str(e)}{Style.RESET_ALL}") print(f"{Fore.YELLOW}{EMOJI['INFO']} The file might be corrupted. Please reinstall Cursor{Style.RESET_ALL}") - else: + elif storage_path: print(f"{Fore.YELLOW}{EMOJI['WARNING']} Storage file not found: {storage_path}{Style.RESET_ALL}") print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") except (OSError, IOError) as e: print(f"{Fore.RED}{EMOJI['ERROR']} Error checking Linux paths: {str(e)}{Style.RESET_ALL}") + # Define all paths using the found cursor directory default_config['LinuxPaths'] = { 'storage_path': storage_path, - 'sqlite_path': os.path.abspath(os.path.join(actual_home, ".config/cursor/User/globalStorage/state.vscdb")), - 'machine_id_path': os.path.join(actual_home, ".config/cursor/machineid"), + 'sqlite_path': os.path.abspath(os.path.join(cursor_dir, "User/globalStorage/state.vscdb")) if cursor_dir else "", + 'machine_id_path': os.path.join(cursor_dir, "machineid") if cursor_dir else "", 'cursor_path': get_linux_cursor_path(), - 'updater_path': os.path.join(actual_home, ".config/cursor-updater"), - 'update_yml_path': os.path.join(actual_home, ".config/cursor/resources/app-update.yml") + 'updater_path': os.path.join(config_base, "cursor-updater"), + 'update_yml_path': os.path.join(cursor_dir, "resources/app-update.yml") if cursor_dir else "" } # Read existing configuration and merge From cb202e08e5d5644d32ac83e147c9f5a769c8aab8 Mon Sep 17 00:00:00 2001 From: yeongpin Date: Mon, 31 Mar 2025 00:58:51 +0800 Subject: [PATCH 3/3] refactor: enhance configuration error messages with translation support and improve user feedback --- config.py | 52 ++++++++++++++++++++++------------------------ locales/en.json | 23 +++++++++++++++++++- locales/zh_cn.json | 23 +++++++++++++++++++- locales/zh_tw.json | 23 +++++++++++++++++++- 4 files changed, 91 insertions(+), 30 deletions(-) diff --git a/config.py b/config.py index 82dfdd8..2fb5954 100644 --- a/config.py +++ b/config.py @@ -105,8 +105,8 @@ def setup_config(translator=None): break if not cursor_dir: - print(f"{Fore.YELLOW}{EMOJI['WARNING']} Neither Cursor nor cursor directory found in {config_base}{Style.RESET_ALL}") - print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['WARNING']} {translator.get('config.neither_cursor_nor_cursor_directory_found', config_base=config_base)}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('config.please_make_sure_cursor_is_installed_and_has_been_run_at_least_once')}{Style.RESET_ALL}") # Define Linux paths using the found cursor directory storage_path = os.path.abspath(os.path.join(cursor_dir, "User/globalStorage/storage.json")) if cursor_dir else "" @@ -116,46 +116,46 @@ def setup_config(translator=None): try: # Check storage directory if storage_dir and not os.path.exists(storage_dir): - print(f"{Fore.YELLOW}{EMOJI['WARNING']} Storage directory not found: {storage_dir}{Style.RESET_ALL}") - print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['WARNING']} {translator.get('config.storage_directory_not_found', storage_dir=storage_dir)}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('config.please_make_sure_cursor_is_installed_and_has_been_run_at_least_once')}{Style.RESET_ALL}") # Check storage.json with more detailed verification if storage_path and os.path.exists(storage_path): # Get file stats try: stat = os.stat(storage_path) - print(f"{Fore.GREEN}{EMOJI['INFO']} Storage file found: {storage_path}{Style.RESET_ALL}") - print(f"{Fore.GREEN}{EMOJI['INFO']} File size: {stat.st_size} bytes{Style.RESET_ALL}") - print(f"{Fore.GREEN}{EMOJI['INFO']} File permissions: {oct(stat.st_mode & 0o777)}{Style.RESET_ALL}") - print(f"{Fore.GREEN}{EMOJI['INFO']} File owner: {stat.st_uid}{Style.RESET_ALL}") - print(f"{Fore.GREEN}{EMOJI['INFO']} File group: {stat.st_gid}{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['INFO']} {translator.get('config.storage_file_found', storage_path=storage_path)}{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['INFO']} {translator.get('config.file_size', stat.st_size)}{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['INFO']} {translator.get('config.file_permissions', oct(stat.st_mode & 0o777))}{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['INFO']} {translator.get('config.file_owner', stat.st_uid)}{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['INFO']} {translator.get('config.file_group', stat.st_gid)}{Style.RESET_ALL}") except Exception as e: - print(f"{Fore.RED}{EMOJI['ERROR']} Error getting file stats: {str(e)}{Style.RESET_ALL}") + print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('config.error_getting_file_stats', error=str(e))}{Style.RESET_ALL}") # Check if file is readable and writable if not os.access(storage_path, os.R_OK | os.W_OK): - print(f"{Fore.RED}{EMOJI['ERROR']} Permission denied: {storage_path}{Style.RESET_ALL}") - print(f"{Fore.YELLOW}{EMOJI['INFO']} Try running: chown {current_user}:{current_user} {storage_path}{Style.RESET_ALL}") - print(f"{Fore.YELLOW}{EMOJI['INFO']} And: chmod 644 {storage_path}{Style.RESET_ALL}") + print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('config.permission_denied', storage_path=storage_path)}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('config.try_running', current_user=current_user, storage_path=storage_path)}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('config.and', storage_path=storage_path)}{Style.RESET_ALL}") # Try to read the file to verify it's not corrupted try: with open(storage_path, 'r') as f: content = f.read() if not content.strip(): - print(f"{Fore.YELLOW}{EMOJI['WARNING']} Storage file is empty: {storage_path}{Style.RESET_ALL}") - print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['WARNING']} {translator.get('config.storage_file_is_empty', storage_path=storage_path)}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('config.please_make_sure_cursor_is_installed_and_has_been_run_at_least_once')}{Style.RESET_ALL}") else: - print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Storage file is valid and contains data{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('config.storage_file_is_valid_and_contains_data')}{Style.RESET_ALL}") except Exception as e: - print(f"{Fore.RED}{EMOJI['ERROR']} Error reading storage file: {str(e)}{Style.RESET_ALL}") - print(f"{Fore.YELLOW}{EMOJI['INFO']} The file might be corrupted. Please reinstall Cursor{Style.RESET_ALL}") + print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('config.error_reading_storage_file', error=str(e))}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('config.the_file_might_be_corrupted_please_reinstall_cursor')}{Style.RESET_ALL}") elif storage_path: - print(f"{Fore.YELLOW}{EMOJI['WARNING']} Storage file not found: {storage_path}{Style.RESET_ALL}") - print(f"{Fore.YELLOW}{EMOJI['INFO']} Please make sure Cursor is installed and has been run at least once{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['WARNING']} {translator.get('config.storage_file_not_found', storage_path=storage_path)}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('config.please_make_sure_cursor_is_installed_and_has_been_run_at_least_once')}{Style.RESET_ALL}") except (OSError, IOError) as e: - print(f"{Fore.RED}{EMOJI['ERROR']} Error checking Linux paths: {str(e)}{Style.RESET_ALL}") + print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('config.error_checking_linux_paths', error=str(e))}{Style.RESET_ALL}") # Define all paths using the found cursor directory default_config['LinuxPaths'] = { @@ -181,13 +181,13 @@ def setup_config(translator=None): config.set(section, option, str(value)) config_modified = True if translator: - print(f"{Fore.YELLOW}ℹ️ {translator.get('register.config_option_added', option=f'{section}.{option}')}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('register.config_option_added', option=f'{section}.{option}')}{Style.RESET_ALL}") if config_modified: with open(config_file, 'w', encoding='utf-8') as f: config.write(f) if translator: - print(f"{Fore.GREEN}✅ {translator.get('register.config_updated')}{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('register.config_updated')}{Style.RESET_ALL}") else: for section, options in default_config.items(): config.add_section(section) @@ -197,15 +197,13 @@ def setup_config(translator=None): with open(config_file, 'w', encoding='utf-8') as f: config.write(f) if translator: - print(f"{Fore.GREEN}✅ {translator.get('register.config_created')}: {config_file}{Style.RESET_ALL}") + print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('register.config_created')}: {config_file}{Style.RESET_ALL}") return config except Exception as e: if translator: - print(f"{Fore.RED}❌ {translator.get('register.config_setup_error', error=str(e))}{Style.RESET_ALL}") - else: - print(f"{Fore.RED}❌ Error setting up config: {e}{Style.RESET_ALL}") + print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('register.config_setup_error', error=str(e))}{Style.RESET_ALL}") return None def print_config(config, translator=None): diff --git a/locales/en.json b/locales/en.json index 5fddde1..c3bef05 100644 --- a/locales/en.json +++ b/locales/en.json @@ -493,6 +493,27 @@ "configuration": "Configuration", "enabled": "Enabled", "disabled": "Disabled", - "config_directory": "Config Directory" + "config_directory": "Config Directory", + "neither_cursor_nor_cursor_directory_found": "Neither Cursor nor Cursor directory found in {config_base}", + "please_make_sure_cursor_is_installed_and_has_been_run_at_least_once": "Please make sure Cursor is installed and has been run at least once", + "storage_directory_not_found": "Storage directory not found: {storage_dir}", + "storage_file_found": "Storage file found: {storage_path}", + "file_size": "File size: {size}", + "file_permissions": "File permissions: {permissions}", + "file_owner": "File owner: {owner}", + "file_group": "File group: {group}", + "error_getting_file_stats": "Error getting file stats: {error}", + "permission_denied": "Permission denied: {storage_path}", + "try_running": "Try running 'cursor --help' to check if it's installed", + "and": "and", + "storage_file_is_empty": "Storage file is empty: {storage_path}", + "the_file_might_be_corrupted_please_reinstall_cursor": "The file might be corrupted, please reinstall Cursor", + "storage_file_not_found": "Storage file not found: {storage_path}", + "error_checking_linux_paths": "Error checking Linux paths: {error}", + "config_option_added": "Config option added: {option}", + "config_updated": "Config updated", + "config_created": "Config created: {config_file}", + "config_setup_error": "Error setting up config: {error}" + } } \ No newline at end of file diff --git a/locales/zh_cn.json b/locales/zh_cn.json index 910941a..05710fe 100644 --- a/locales/zh_cn.json +++ b/locales/zh_cn.json @@ -488,6 +488,27 @@ "configuration": "配置", "enabled": "已启用", "disabled": "已禁用", - "config_directory": "配置目录" + "config_directory": "配置目录", + "neither_cursor_nor_cursor_directory_found": "未找到 Cursor 或 Cursor 目录", + "please_make_sure_cursor_is_installed_and_has_been_run_at_least_once": "请确保 Cursor 已安装并至少运行一次", + "storage_directory_not_found": "未找到存储目录", + "storage_file_found": "找到存储文件", + "file_size": "文件大小", + "file_permissions": "文件权限", + "file_owner": "文件所有者", + "file_group": "文件组", + "error_getting_file_stats": "获取文件统计信息时出错", + "permission_denied": "权限拒绝", + "try_running": "尝试运行 'cursor --help' 检查是否已安装", + "and": "和", + "storage_file_is_empty": "存储文件为空", + "the_file_might_be_corrupted_please_reinstall_cursor": "文件可能已损坏,请重新安装 Cursor", + "storage_file_not_found": "未找到存储文件", + "error_checking_linux_paths": "检查 Linux 路径时出错", + "config_option_added": "添加配置选项", + "config_updated": "配置更新", + "config_created": "配置已创建", + "config_setup_error": "配置设置错误" } + } \ No newline at end of file diff --git a/locales/zh_tw.json b/locales/zh_tw.json index 8cfb910..c88ae6e 100644 --- a/locales/zh_tw.json +++ b/locales/zh_tw.json @@ -467,6 +467,27 @@ "configuration": "配置", "enabled": "已啟用", "disabled": "已禁用", - "config_directory": "配置目錄" + "config_directory": "配置目錄", + "neither_cursor_nor_cursor_directory_found": "未找到 Cursor 或 Cursor 目錄", + "please_make_sure_cursor_is_installed_and_has_been_run_at_least_once": "請確保 Cursor 已安裝並至少運行一次", + "storage_directory_not_found": "未找到儲存目錄", + "storage_file_found": "找到儲存文件", + "file_size": "文件大小", + "file_permissions": "文件權限", + "file_owner": "文件所有者", + "file_group": "文件組", + "error_getting_file_stats": "獲取文件統計信息時出錯", + "permission_denied": "權限拒絕", + "try_running": "嘗試運行 'cursor --help' 檢查是否已安裝", + "and": "和", + "storage_file_is_empty": "儲存文件為空", + "the_file_might_be_corrupted_please_reinstall_cursor": "文件可能已損壞,請重新安裝 Cursor", + "storage_file_not_found": "未找到儲存文件", + "error_checking_linux_paths": "檢查 Linux 路徑時出錯", + "config_option_added": "添加配置選項", + "config_updated": "配置更新", + "config_created": "配置已創建", + "config_setup_error": "配置設置錯誤" + } } \ No newline at end of file