-
Notifications
You must be signed in to change notification settings - Fork 614
feat: Hebrew (he-IL) Translation #1157
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
Conversation
WalkthroughAdds full ACP workspace support (main presenters, process/session/FS managers, IPC events, renderer store/components, types) and introduces Hebrew (he-IL) i18n plus RTL handling; includes supporting preload path helpers, UI adjustments (chat/MessageList/ModelSelect), docs/README updates, and various translations. Changes
Sequence Diagram(s)sequenceDiagram
participant Renderer as Renderer (Window)
participant Store as AcpWorkspaceStore
participant Main as Main Presenter
participant FS as Filesystem
participant Agent as ACP Agent Process
Renderer->>Store: user requests expand file / append path
Store-->>Renderer: emit append-file-path event
Renderer->>Main: IPC readDirectory(dirPath)
Main->>FS: read directory (readDirectoryShallow)
FS-->>Main: directory entries
Main-->>Renderer: return AcpFileNode[]
Renderer->>Store: update fileTree
Agent-->>Main: emits plan update / terminal snippet
Main->>Main: PlanStateManager.updateEntries()
Main->>Renderer: IPC emit ACP_WORKSPACE_EVENTS.PLAN_UPDATED / TERMINAL_OUTPUT / FILES_CHANGED
Renderer->>Store: IPC handler updates plan/terminal/fileTree
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes
Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/renderer/src/stores/language.ts (1)
8-8: Consider including thehealias in RTL_LIST
'he-IL'here correctly enables RTL for the new locale. To be robust against code paths that might use thehealias, you could extend this to['fa-IR', 'he-IL', 'he'].src/renderer/settings/components/DisplaySettings.vue (1)
329-345: Hebrew language option wiring looks correctAdding
{ value: 'he-IL', label: 'עברית (ישראל)' }keepslanguageOptionsin sync withConfigPresenter.getSystemLanguage()and the new he-IL i18n bundle, and mirrors the existing pattern used for other languages (includingda-DK).
If you later centralize language-display names into i18n, remember to add a he-IL label key as well.src/renderer/src/i18n/index.ts (1)
34-34: Consider removing debug console.log statement.The console.log at line 34 appears to be debug code that may have been left in unintentionally. Consider removing it unless it serves a specific purpose in production.
Apply this diff to remove the debug statement:
-console.log('locales', locales) export default locales
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (25)
src/main/presenter/configPresenter/index.ts(1 hunks)src/renderer/settings/components/DisplaySettings.vue(1 hunks)src/renderer/src/i18n/he-IL/about.json(1 hunks)src/renderer/src/i18n/he-IL/artifacts.json(1 hunks)src/renderer/src/i18n/he-IL/chat.json(1 hunks)src/renderer/src/i18n/he-IL/common.json(1 hunks)src/renderer/src/i18n/he-IL/components.json(1 hunks)src/renderer/src/i18n/he-IL/contextMenu.json(1 hunks)src/renderer/src/i18n/he-IL/dialog.json(1 hunks)src/renderer/src/i18n/he-IL/index.ts(1 hunks)src/renderer/src/i18n/he-IL/mcp.json(1 hunks)src/renderer/src/i18n/he-IL/model.json(1 hunks)src/renderer/src/i18n/he-IL/newThread.json(1 hunks)src/renderer/src/i18n/he-IL/plan.json(1 hunks)src/renderer/src/i18n/he-IL/promptSetting.json(1 hunks)src/renderer/src/i18n/he-IL/routes.json(1 hunks)src/renderer/src/i18n/he-IL/settings.json(1 hunks)src/renderer/src/i18n/he-IL/sync.json(1 hunks)src/renderer/src/i18n/he-IL/thread.json(1 hunks)src/renderer/src/i18n/he-IL/toolCall.json(1 hunks)src/renderer/src/i18n/he-IL/traceDialog.json(1 hunks)src/renderer/src/i18n/he-IL/update.json(1 hunks)src/renderer/src/i18n/he-IL/welcome.json(1 hunks)src/renderer/src/i18n/index.ts(2 hunks)src/renderer/src/stores/language.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (29)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.tssrc/renderer/settings/components/DisplaySettings.vue
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and maintain strict TypeScript type checking for all files
**/*.{ts,tsx}: Always use try-catch to handle possible errors in TypeScript code
Provide meaningful error messages when catching errors
Log detailed error logs including error details, context, and stack traces
Distinguish and handle different error types (UserError, NetworkError, SystemError, BusinessError) with appropriate handlers in TypeScript
Use structured logging with logger.error(), logger.warn(), logger.info(), logger.debug() methods from logging utilities
Do not suppress errors (avoid empty catch blocks or silently ignoring errors)
Provide user-friendly error messages for user-facing errors in TypeScript components
Implement error retry mechanisms for transient failures in TypeScript
Avoid logging sensitive information (passwords, tokens, PII) in logs
Files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
src/main/presenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Organize core business logic into dedicated Presenter classes, with one presenter per functional domain
Files:
src/main/presenter/configPresenter/index.ts
src/main/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use EventBus from
src/main/eventbus.tsfor main-to-renderer communication, broadcasting events viamainWindow.webContents.send()
src/main/**/*.ts: Use EventBus pattern for inter-process communication within the main process to decouple modules
Use Electron's built-in APIs for file system and native dialogs instead of Node.js or custom implementations
src/main/**/*.ts: Electron main process code belongs insrc/main/with presenters inpresenter/(Window/Tab/Thread/Mcp/Config/LLMProvider) andeventbus.tsfor app events
Use the Presenter pattern in the main process for UI coordination
Files:
src/main/presenter/configPresenter/index.ts
src/main/presenter/configPresenter/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Store and retrieve custom prompts via
configPresenter.getCustomPrompts()for config-based data source management
Files:
src/main/presenter/configPresenter/index.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not include AI co-authoring information (e.g., 'Co-Authored-By: Claude') in git commits
Files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
Write logs and comments in English
Files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
{src/main/presenter/**/*.ts,src/renderer/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)
Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs
Files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
src/**/*
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
New features should be developed in the
srcdirectory
Files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/i18n/he-IL/dialog.jsonsrc/renderer/src/i18n/he-IL/sync.jsonsrc/renderer/src/i18n/he-IL/contextMenu.jsonsrc/renderer/src/i18n/he-IL/common.jsonsrc/renderer/src/i18n/he-IL/model.jsonsrc/renderer/src/i18n/he-IL/thread.jsonsrc/renderer/src/i18n/he-IL/newThread.jsonsrc/renderer/src/i18n/he-IL/plan.jsonsrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/promptSetting.jsonsrc/renderer/src/i18n/he-IL/toolCall.jsonsrc/renderer/src/i18n/he-IL/routes.jsonsrc/renderer/src/i18n/he-IL/chat.jsonsrc/renderer/src/i18n/he-IL/mcp.jsonsrc/renderer/src/i18n/he-IL/traceDialog.jsonsrc/renderer/src/i18n/he-IL/artifacts.jsonsrc/renderer/src/i18n/he-IL/index.tssrc/renderer/src/i18n/he-IL/settings.jsonsrc/renderer/src/i18n/he-IL/components.jsonsrc/renderer/src/i18n/he-IL/about.jsonsrc/renderer/src/i18n/he-IL/welcome.jsonsrc/renderer/src/i18n/he-IL/update.jsonsrc/renderer/settings/components/DisplaySettings.vue
src/main/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Main process code for Electron should be placed in
src/main
Files:
src/main/presenter/configPresenter/index.ts
src/**/*.{ts,tsx,vue,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier with single quotes, no semicolons, and 100 character width
Files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.tssrc/renderer/settings/components/DisplaySettings.vue
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use OxLint for linting JavaScript and TypeScript files
Files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use camelCase for variable and function names in TypeScript files
Use PascalCase for type and class names in TypeScript
Use SCREAMING_SNAKE_CASE for constant names
Files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use EventBus for inter-process communication events
Files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
src/renderer/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use the
usePresenter.tscomposable for renderer-to-main IPC communication to call presenter methods directly
Files:
src/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
src/renderer/src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)
src/renderer/src/**/*.{vue,ts,tsx}: All user-facing strings must use i18n keys with vue-i18n framework in the renderer
Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files
Use the dynamic locale.value property to switch languages at runtime
Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system
Files:
src/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
src/renderer/**/*.{vue,js,ts}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Renderer process code should be placed in
src/renderer(Vue 3 application)
Files:
src/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.tssrc/renderer/settings/components/DisplaySettings.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability in Vue.js applications
Implement proper state management with Pinia in Vue.js applications
Utilize Vue Router for navigation and route management in Vue.js applications
Leverage Vue's built-in reactivity system for efficient data handling
Files:
src/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
src/renderer/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,tsx,vue}: Write concise, technical TypeScript code with accurate examples
Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
Avoid enums; use const objects instead
Use arrow functions for methods and computed properties
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statementsVue 3 app code in
src/renderer/srcshould be organized intocomponents/,stores/,views/,i18n/,lib/directories with shell UI insrc/renderer/shell/
Files:
src/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.tssrc/renderer/settings/components/DisplaySettings.vue
src/renderer/**
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use lowercase with dashes for directories (e.g., components/auth-wizard)
Files:
src/renderer/src/i18n/index.tssrc/renderer/src/i18n/he-IL/dialog.jsonsrc/renderer/src/i18n/he-IL/sync.jsonsrc/renderer/src/i18n/he-IL/contextMenu.jsonsrc/renderer/src/i18n/he-IL/common.jsonsrc/renderer/src/i18n/he-IL/model.jsonsrc/renderer/src/i18n/he-IL/thread.jsonsrc/renderer/src/i18n/he-IL/newThread.jsonsrc/renderer/src/i18n/he-IL/plan.jsonsrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/promptSetting.jsonsrc/renderer/src/i18n/he-IL/toolCall.jsonsrc/renderer/src/i18n/he-IL/routes.jsonsrc/renderer/src/i18n/he-IL/chat.jsonsrc/renderer/src/i18n/he-IL/mcp.jsonsrc/renderer/src/i18n/he-IL/traceDialog.jsonsrc/renderer/src/i18n/he-IL/artifacts.jsonsrc/renderer/src/i18n/he-IL/index.tssrc/renderer/src/i18n/he-IL/settings.jsonsrc/renderer/src/i18n/he-IL/components.jsonsrc/renderer/src/i18n/he-IL/about.jsonsrc/renderer/src/i18n/he-IL/welcome.jsonsrc/renderer/src/i18n/he-IL/update.jsonsrc/renderer/settings/components/DisplaySettings.vue
src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use TypeScript for all code; prefer types over interfaces
Files:
src/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
src/renderer/**/*.{ts,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching
Leverage ref, reactive, and computed for reactive state management
Use provide/inject for dependency injection when appropriate
Use Iconify/Vue for icon implementation
Files:
src/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.tssrc/renderer/settings/components/DisplaySettings.vue
src/renderer/src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
src/renderer/src/**/*.{ts,tsx,vue}: Use TypeScript with Vue 3 Composition API for the renderer application
All user-facing strings must use vue-i18n keys insrc/renderer/src/i18n
Files:
src/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/index.ts
src/renderer/src/i18n/**/*.json
📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)
src/renderer/src/i18n/**/*.json: Translation key naming convention: use dot-separated hierarchical structure with lowercase letters and descriptive names (e.g., 'common.button.submit')
Maintain consistent key-value structure across all language translation files (zh-CN, en-US, ko-KR, ru-RU, zh-HK, fr-FR, fa-IR)
Files:
src/renderer/src/i18n/he-IL/dialog.jsonsrc/renderer/src/i18n/he-IL/sync.jsonsrc/renderer/src/i18n/he-IL/contextMenu.jsonsrc/renderer/src/i18n/he-IL/common.jsonsrc/renderer/src/i18n/he-IL/model.jsonsrc/renderer/src/i18n/he-IL/thread.jsonsrc/renderer/src/i18n/he-IL/newThread.jsonsrc/renderer/src/i18n/he-IL/plan.jsonsrc/renderer/src/i18n/he-IL/promptSetting.jsonsrc/renderer/src/i18n/he-IL/toolCall.jsonsrc/renderer/src/i18n/he-IL/routes.jsonsrc/renderer/src/i18n/he-IL/chat.jsonsrc/renderer/src/i18n/he-IL/mcp.jsonsrc/renderer/src/i18n/he-IL/traceDialog.jsonsrc/renderer/src/i18n/he-IL/artifacts.jsonsrc/renderer/src/i18n/he-IL/settings.jsonsrc/renderer/src/i18n/he-IL/components.jsonsrc/renderer/src/i18n/he-IL/about.jsonsrc/renderer/src/i18n/he-IL/welcome.jsonsrc/renderer/src/i18n/he-IL/update.json
src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/pinia-best-practices.mdc)
src/renderer/src/stores/**/*.{vue,ts,tsx,js,jsx}: Use modules to organize related state and actions in Pinia stores
Implement proper state persistence for maintaining data across sessions in Pinia stores
Use getters for computed state properties in Pinia stores
Utilize actions for side effects and asynchronous operations in Pinia stores
Keep Pinia stores focused on global state, not component-specific data
Files:
src/renderer/src/stores/language.ts
src/renderer/**/stores/*.ts
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Use Pinia for state management
Files:
src/renderer/src/stores/language.ts
src/renderer/src/stores/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use Pinia for state management
Files:
src/renderer/src/stores/language.ts
**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.vue: Use Vue 3 Composition API for all components instead of Options API
Use Tailwind CSS with scoped styles for component styling
Files:
src/renderer/settings/components/DisplaySettings.vue
src/renderer/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
src/renderer/**/*.vue: All user-facing strings must use i18n keys via vue-i18n for internationalization
Ensure proper error handling and loading states in all UI components
Implement responsive design using Tailwind CSS utilities for all UI components
src/renderer/**/*.vue: Use composition API and declarative programming patterns; avoid options API
Structure files: exported component, composables, helpers, static content, types
Use PascalCase for component names (e.g., AuthWizard.vue)
Use Vue 3 with TypeScript, leveraging defineComponent and PropType
Use template syntax for declarative rendering
Use Shadcn Vue, Radix Vue, and Tailwind for components and styling
Implement responsive design with Tailwind CSS; use a mobile-first approach
Use Suspense for asynchronous components
Use <script setup> syntax for concise component definitions
Prefer 'lucide:' icon family as the primary choice for Iconify icons
Import Icon component from '@iconify/vue' and use with lucide icons following pattern '{collection}:{icon-name}'
Files:
src/renderer/settings/components/DisplaySettings.vue
🧠 Learnings (10)
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/i18n/**/*.json : Maintain consistent key-value structure across all language translation files (zh-CN, en-US, ko-KR, ru-RU, zh-HK, fr-FR, fa-IR)
Applied to files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/i18n/he-IL/dialog.jsonsrc/renderer/src/i18n/he-IL/sync.jsonsrc/renderer/src/i18n/he-IL/contextMenu.jsonsrc/renderer/src/i18n/he-IL/model.jsonsrc/renderer/src/i18n/he-IL/thread.jsonsrc/renderer/src/i18n/he-IL/newThread.jsonsrc/renderer/src/i18n/he-IL/plan.jsonsrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/promptSetting.jsonsrc/renderer/src/i18n/he-IL/toolCall.jsonsrc/renderer/src/i18n/he-IL/routes.jsonsrc/renderer/src/i18n/he-IL/chat.jsonsrc/renderer/src/i18n/he-IL/mcp.jsonsrc/renderer/src/i18n/he-IL/traceDialog.jsonsrc/renderer/src/i18n/he-IL/artifacts.jsonsrc/renderer/src/i18n/he-IL/index.tssrc/renderer/src/i18n/he-IL/settings.jsonsrc/renderer/src/i18n/he-IL/components.jsonsrc/renderer/src/i18n/he-IL/about.jsonsrc/renderer/src/i18n/he-IL/welcome.jsonsrc/renderer/src/i18n/he-IL/update.json
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to **/*.{ts,tsx,js,jsx,vue} : Use English for logs and comments (Chinese text exists in legacy code, but new code should use English)
Applied to files:
src/main/presenter/configPresenter/index.tssrc/renderer/src/i18n/index.tssrc/renderer/src/i18n/he-IL/index.ts
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx} : Use the dynamic locale.value property to switch languages at runtime
Applied to files:
src/renderer/src/i18n/index.tssrc/renderer/src/stores/language.tssrc/renderer/settings/components/DisplaySettings.vue
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx} : All user-facing strings must use i18n keys with vue-i18n framework in the renderer
Applied to files:
src/renderer/src/i18n/index.tssrc/renderer/src/i18n/he-IL/model.jsonsrc/renderer/src/i18n/he-IL/routes.jsonsrc/renderer/src/i18n/he-IL/index.tssrc/renderer/src/i18n/he-IL/components.json
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx} : Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system
Applied to files:
src/renderer/src/i18n/index.tssrc/renderer/src/i18n/he-IL/model.jsonsrc/renderer/src/i18n/he-IL/thread.jsonsrc/renderer/src/stores/language.tssrc/renderer/src/i18n/he-IL/routes.jsonsrc/renderer/src/i18n/he-IL/index.tssrc/renderer/src/i18n/he-IL/components.jsonsrc/renderer/settings/components/DisplaySettings.vue
📚 Learning: 2025-11-25T05:28:20.513Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T05:28:20.513Z
Learning: Applies to src/renderer/src/**/*.{ts,tsx,vue} : All user-facing strings must use vue-i18n keys in `src/renderer/src/i18n`
Applied to files:
src/renderer/src/i18n/index.tssrc/renderer/src/i18n/he-IL/routes.jsonsrc/renderer/src/i18n/he-IL/index.ts
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx} : Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files
Applied to files:
src/renderer/src/i18n/index.ts
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/renderer/**/*.vue : All user-facing strings must use i18n keys via vue-i18n for internationalization
Applied to files:
src/renderer/src/i18n/index.ts
📚 Learning: 2025-11-25T05:26:43.510Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-11-25T05:26:43.510Z
Learning: Applies to src/renderer/src/i18n/**/*.json : Translation key naming convention: use dot-separated hierarchical structure with lowercase letters and descriptive names (e.g., 'common.button.submit')
Applied to files:
src/renderer/src/i18n/he-IL/dialog.jsonsrc/renderer/src/i18n/he-IL/model.jsonsrc/renderer/src/i18n/he-IL/thread.jsonsrc/renderer/src/i18n/he-IL/toolCall.jsonsrc/renderer/src/i18n/he-IL/routes.jsonsrc/renderer/src/i18n/he-IL/mcp.jsonsrc/renderer/src/i18n/he-IL/traceDialog.jsonsrc/renderer/src/i18n/he-IL/artifacts.jsonsrc/renderer/src/i18n/he-IL/settings.jsonsrc/renderer/src/i18n/he-IL/components.json
📚 Learning: 2025-11-25T05:26:11.312Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T05:26:11.312Z
Learning: Applies to src/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`
Applied to files:
src/renderer/src/i18n/he-IL/mcp.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build-windows (x64)
- GitHub Check: build-check (x64)
🔇 Additional comments (27)
src/renderer/src/i18n/he-IL/plan.json (1)
1-4: Plan translations aligned with existing structure
completedandtitlemirror the expectedplan.jsonshape from other locales; JSON is valid and consistent. Based on learnings, this keeps the cross-locale key set aligned.src/renderer/src/i18n/he-IL/promptSetting.json (1)
1-95: Prompt settings he-IL resource looks structurally correctKeys and nested structure match a typical
promptSetting.json; interpolation tokens ({added},{updated},{count},{name},{openBrace}/{closeBrace}) are well-formed and should integrate cleanly with existing code. Based on learnings, this preserves the shared key schema across locales.src/renderer/src/i18n/he-IL/newThread.json (1)
1-4: New-thread Hebrew strings are fine
greetingandpromptfollow the expectednewThread.jsonlayout and introduce no structural/i18n issues.src/main/presenter/configPresenter/index.ts (1)
675-691: System language detection correctly extended for he-IL (and da-DK)Adding
'he-IL'(and'da-DK') tosupportedLanguagesletsgetSystemLanguage()exact-match these locales before falling back to partial matching or English, which is consistent with the new i18n resources and DisplaySettings options.src/renderer/src/i18n/he-IL/routes.json (1)
1-17: Routes he-IL mapping matches existing key setRoute identifiers (
chat,welcome,playground,settings-*) align with the established routes.json schema; translations look reasonable and JSON is valid. Based on learnings, this keeps the cross-locale route key structure consistent.src/renderer/src/i18n/he-IL/dialog.json (1)
1-44: Dialog he-IL translations are structurally soundThe dialog keys (basic actions, delete/rename/clean/fork flows,
mutualExclusiveblock) match the expected shape from other locales; JSON is valid and there are no placeholder or key inconsistencies. Based on learnings, this remains aligned with the shared dialog.json contract.src/renderer/src/i18n/index.ts (1)
12-12: LGTM! Hebrew locale registration follows existing patterns.The Hebrew locale import and registration correctly follow the established pattern for other locales, including both the full locale code ('he-IL') and a short alias ('he').
Also applies to: 26-27, 31-32
src/renderer/src/i18n/he-IL/traceDialog.json (1)
1-17: LGTM! Consistency verified.The Hebrew translations for traceDialog are well-structured with clear key names. All 15 keys match identically across all language files (zh-CN, en-US, ja-JP, ko-KR, zh-HK, zh-TW, ru-RU, fr-FR, fa-IR, pt-BR, da-DK, he-IL). The inclusion of English technical terms in parentheses (e.g., "API Endpoint", "Headers", "Body", "JSON") is helpful for technical clarity.
src/renderer/src/i18n/he-IL/welcome.json (1)
1-37: LGTM! Clear onboarding flow structure with consistent key structure.The Hebrew translations for the welcome/onboarding flow are well-organized with a clear hierarchical structure that follows the multi-step wizard pattern (steps → welcome/provider/configuration/complete). The translations are clear and user-friendly. The key structure is consistent across all 12 locale files (zh-CN, en-US, ja-JP, ko-KR, zh-HK, zh-TW, ru-RU, fr-FR, fa-IR, pt-BR, da-DK, he-IL), maintaining the dot-separated hierarchical naming convention as required.
src/renderer/src/i18n/he-IL/about.json (1)
1-19: Structure verification complete — consistent across all locales.The Hebrew translations are well-structured with clear device info organization. Key structure matches exactly with all other locale files (12 locales verified), with consistent deviceInfo nesting of 6 keys (platform, arch, cpuModel, totalMemory, osVersion, title) across all languages. The inclusion of English technical terms in parentheses for "Stable" and "Canary" maintains helpful technical clarity for users.
src/renderer/src/i18n/he-IL/toolCall.json (1)
1-19: Keys verified as consistent across all locales.The Hebrew translations for toolCall.json are properly structured with all 17 keys matching the reference en-US file and all other supported locales (da-DK, fa-IR, fr-FR, ja-JP, ko-KR, pt-BR, ru-RU, zh-CN, zh-HK, zh-TW). The file maintains the required key-value consistency across the i18n system.
src/renderer/src/i18n/he-IL/contextMenu.json (1)
1-17: No structural inconsistency exists—all contextMenu.json files across all 12 locales (including he-IL) have identical key structures.All locales consistently use the same pattern:
translateandaskAIas nested objects with identical sub-keys (title, original/question, translated/answer, error), andcopy,paste,cutas flat string values. The Hebrew translation is fully compliant with the established convention.src/renderer/src/i18n/he-IL/model.json (1)
1-30: Structure verified: he-IL model.json matches other locale files perfectly.The Hebrew translations are excellently organized with a clear hierarchical structure (search, error, type, add, actions, tags). The nested key structure is identical to en-US and follows the required dot-separated naming convention with lowercase letters. The inclusion of English technical terms in parentheses (e.g., "חשיבה (Reasoning)", "Context", "ID") enhances clarity for technical users.
src/renderer/src/i18n/he-IL/sync.json (1)
1-17: LGTM! Key structure and interpolation syntax verified across all locales.The Hebrew translations for sync functionality are well-organized with clear separation between success and error messages. The use of the
{count}placeholder in line 3 for dynamic interpolation matches the vue-i18n standard format used consistently across all 12 supported locales.Key structure verification:
- ✓ Matches other locale files exactly (11 identical keys)
- ✓ Follows dot-separated hierarchical naming convention (e.g.,
success.importComplete,error.configNotExists)- ✓
{count}interpolation syntax is consistent across all locales (da-DK, en-US, fa-IR, fr-FR, he-IL, ja-JP, ko-KR, pt-BR, ru-RU, zh-CN, zh-HK, zh-TW)The he-IL locale is properly registered in the renderer i18n system with RTL support enabled for Hebrew text rendering.
src/renderer/src/i18n/he-IL/common.json (1)
1-82: Translation structure and key naming follow conventions.The file maintains consistent nested hierarchies and descriptive camelCase key naming (e.g.,
copySuccess,copyFailedDesc). No structural issues identified.src/renderer/src/i18n/he-IL/thread.json (1)
1-46: Consistent structure and logical organization.Translation keys follow the established pattern with clear semantic nesting (e.g.,
actions.rename,toolbar.save,export.success). Structure aligns with conventions.src/renderer/src/i18n/he-IL/chat.json (2)
1-10: Clarify placeholder escaping in line 3.Line 3 uses
{'@'}syntax in the placeholder string, which differs from the standard{variableName}pattern used throughout this and other translation files. Please verify this is intentional; if the intent is to display a literal@symbol, consider using plain text instead.- "placeholder": "שאל משהו? ניתן לצטט כלים, קבצים ומשאבים באמצעות {'@'}...", + "placeholder": "שאל משהו? ניתן לצטט כלים, קבצים ומשאבים באמצעות @...",
11-97: Translation structure and placeholder consistency otherwise sound.Remaining sections use standard placeholder syntax (e.g.,
{count},{seconds},{mode}) and maintain consistent semantic key naming. The nested hierarchy for input, features, search, messages, rateLimit, and other domains is well-organized.src/renderer/src/i18n/he-IL/update.json (1)
1-16: Simple, focused structure with consistent key naming.All translation keys follow the established lowercase naming convention. The flat structure is appropriate for this compact set of update-related strings.
src/renderer/src/i18n/he-IL/mcp.json (1)
1-316: Comprehensive structure with consistent placeholder usage.This large configuration file maintains clear semantic hierarchies across tools, servers, sampling, prompts, resources, and marketplace sections. All placeholders use the standard
{variable}syntax consistently (e.g., lines 142, 156, 164, 276). Key naming is descriptive throughout.src/renderer/src/i18n/he-IL/components.json (1)
1-41: Well-organized with consistent placeholder patterns.The file maintains clear semantic grouping of UI components (emoji picker, message actions, permission requests, prompt parameters). Placeholders use consistent
{variable}syntax (lines 31-33, 37).src/renderer/src/i18n/he-IL/artifacts.json (1)
1-52: Consistent naming and appropriate parameterization.The file uses descriptive lowercase keys for artifact types and diagram representations, with parameterized variants (e.g.,
flowchartOf,sequenceDiagramBetween) using consistent{variable}placeholders (lines 20-25). The nested mermaid error handling follows the established structure.src/renderer/src/i18n/he-IL/settings.json (2)
1-100: Comprehensive settings structure with proper placeholder and escaping patterns.The file maintains clear semantic organization across multiple settings domains (common, data, model, provider, knowledge base, MCP, ACP, rate limiting). Placeholder syntax is consistent throughout using
{variable}format (e.g., lines 22, 31, 87, 105). Escaped brace patterns in lines 26–27 ({'{'}query{'}'}) correctly produce literal placeholder examples in UI text.
101-963: Extensive nested hierarchies maintain consistent naming and structure throughout.The deep nesting in sections like provider (supporting multiple provider types), knowledgeBase (multiple knowledge base backends), and MCP (extensive server/tool configuration) demonstrates well-organized semantic grouping. All nested keys follow lowercase naming convention. No structural inconsistencies detected.
src/renderer/src/i18n/he-IL/index.ts (3)
22-34: Verify Hebrew translation accuracy for searchDisclaimer.The structure of the
othersobject is correct. Provider names are appropriately kept untranslated as they are brand names. However, thesearchDisclaimercontains a lengthy legal text in Hebrew that should be verified for translation accuracy and legal terminology correctness.Please verify the Hebrew translation quality and legal terminology accuracy with a native Hebrew speaker or professional translator, particularly for legal terms and compliance requirements mentioned in the disclaimer.
36-58: LGTM! Export structure follows locale pattern.The default export correctly merges all translation domains and spreads the
othersobject at the root level, following the standard pattern for locale index files.
1-20: No issues identified. All 20 JSON files in the he-IL locale exist and maintain consistent key-value structure with other language translation files. The import pattern and export structure follow the established convention used across all locales (zh-CN, en-US, ko-KR, ru-RU, zh-HK, fr-FR, fa-IR). The Hebrew translation of searchDisclaimer is properly localized.
* feat: add workspaceview for acp agent * feat: support workspace dirs * fix: workspace file refresh * fix: tool call status * fix: review refactor
* fix: keep last file list * feat(acp-workspace): add file context actions * fix(acp-workspace): move path helpers to preload * fix(preload): allow empty relative path * fix(preload): escape quotes when formatting paths
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: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
src/main/presenter/threadPresenter/utils/promptBuilder.ts (1)
361-365: Align token estimation with newbuildUserMessageContextusageUsing
buildUserMessageContextfor historical user context messages is a good change: it keeps context message text consistent with how you build the current user message (including file context) and should improve completeness of context.However,
selectContextMessagesstill estimates tokens for user messages usinggetNormalizedUserMessageText, which no longer matches the actual string now generated bybuildUserMessageContext. This can lead to underestimating token usage and slightly exceeding the intendedcontextLength, especially when file context strings are non-trivial.You can keep behavior consistent by basing token estimation on
buildUserMessageContextas well:function selectContextMessages( contextMessages: Message[], userMessage: Message, remainingContextLength: number ): Message[] { @@ - for (const msg of messages) { + for (const msg of messages) { if (msg.status !== 'sent') { continue } const msgContent = msg.role === 'user' ? (msg.content as UserMessageContent) : null - const msgTokens = approximateTokenSize( - msgContent ? getNormalizedUserMessageText(msgContent) : JSON.stringify(msg.content) - ) + const msgTokens = approximateTokenSize( + msgContent ? buildUserMessageContext(msgContent) : JSON.stringify(msg.content) + ) @@ }As an optional cleanup, the two branches in
addContextMessages(with and withoutsupportsFunctionCall) now share nearly identical logic for user messages (including the vision/images path). You could extract a small helper likebuildUserChatMessageFromContext(msgContent, vision)to reduce duplication, but that’s not urgent.Also applies to: 444-465, 532-552
src/main/presenter/threadPresenter/index.ts (1)
177-191: Unhandled promise rejection: try-catch does not cover promise chain.The change from awaited flow to a fire-and-forget promise chain means the
try-catchblock (lines 185-190) is now dead code. IfsummaryTitlesorrenameConversationrejects, it will be an unhandled promise rejection.Either add
.catch()to handle errors in the promise chain, or remove the now-ineffective try-catch:if (conversation.is_new === 1) { - try { this.summaryTitles(undefined, state.conversationId) .then((title) => { return this.renameConversation(state.conversationId, title) }) .then(() => { console.log('renameConversation success') }) - } catch (error) { - console.error('[ThreadPresenter] Failed to summarize title', { - conversationId: state.conversationId, - err: error - }) - } + .catch((error) => { + console.error('[ThreadPresenter] Failed to summarize title', { + conversationId: state.conversationId, + err: error + }) + }) }src/renderer/src/i18n/ko-KR/chat.json (1)
20-23: Missing Korean translations for ACP workdir keys.These keys are in English while the rest of the file is localized to Korean. They should be translated for consistency with other locales.
"acpWorkdir": "ACP 작업 디렉토리", "acpWorkdirTooltip": "ACP 작업 디렉토리 설정", "acpWorkdirSelect": "ACP 작업 디렉토리로 사용할 폴더를 선택하세요", "acpWorkdirCurrent": "현재 작업 디렉토리: {path}",src/renderer/src/i18n/pt-BR/chat.json (1)
20-23: Missing Portuguese translations for ACP workdir keys.These keys are in English while the rest of the file is localized to Portuguese. They should be translated for consistency.
"acpWorkdir": "Diretório de Trabalho ACP", "acpWorkdirTooltip": "Definir diretório de trabalho ACP", "acpWorkdirSelect": "Selecione uma pasta para usar como diretório de trabalho ACP", "acpWorkdirCurrent": "Diretório atual: {path}",
🧹 Nitpick comments (17)
src/renderer/src/components/message/MessageBlockPlan.vue (2)
7-9: Consider using a single i18n key with interpolation for better RTL support.The current approach concatenates separate parts (
completedCount,totalCount, and the translated "completed" text). For RTL languages like Hebrew, this may not flow naturally. Consider using a single i18n key with interpolation:<span class="text-xs text-muted-foreground"> {{ t('plan.progress', { completed: completedCount, total: totalCount }) }} </span>Then in your i18n files, define:
- English:
"plan.progress": "{completed}/{total} completed"- Hebrew:
"plan.progress": "הושלם {completed}/{total}"This allows translators to control the word order and formatting for each locale.
34-36: Strengthen type safety for plan entries.The type assertion
as Array<{ status?: string | null }>is fragile and could fail silently if the data structure changes. Consider defining a proper interface and adding runtime validation:interface PlanEntryStatus { status?: string | null } const planEntries = computed(() => { const entries = props.block.extra?.plan_entries if (!Array.isArray(entries)) return [] return entries as PlanEntryStatus[] })This provides better type safety and handles edge cases more gracefully.
src/renderer/src/components/message/MessageBlockPermissionRequest.vue (1)
13-19: Tool name truncation logic is sound and avoids layout blow‑upsUsing
truncatedNamewith a 200‑char cap plus ellipsis is a good balance between readability and safety; the computed correctly handles empty names and avoids off‑by‑one issues when appending'...'. If other components later need the same truncation behavior, consider extracting this into a small shared helper/composable, but it’s fine to keep localized for now.Also applies to: 35-46, 103-118
src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts (1)
155-185: Workdir-aware session creation and ACP mode exposure look correctPassing
workdirintogetConnection()and then intonewSession({ cwd })aligns the process CWD with the workspace, and surfacingavailableModes/currentModeIdfrom the response gives the renderer/store everything it needs without recomputation. The optional chaining guards cover the “no modes” case cleanly, and the log messages are informative.As a follow‑up, you might consider routing the
console.info/console.warn/console.errorcalls in this file through whatever structured logger the app uses for main‑process logs to keep logging consistent.Also applies to: 221-246
CONTRIBUTING.zh.md (1)
118-139: Add language identifier to fenced code block.The fenced code block at line 118 should specify a language identifier for proper syntax highlighting and rendering.
Apply this diff:
-``` +```text ┌─────────────────────────────────────────────────────────────┐ │ Electron Main (TS) │src/renderer/src/components/ChatView.vue (1)
3-21: Use English for comments in new code.Lines 4 and 13 contain Chinese comments (
消息列表区域,ACP Workspace 面板). Per coding guidelines, new code should use English for logs and comments.<div class="flex flex-1 overflow-hidden"> - <!-- 消息列表区域 --> + <!-- Message list area --> <div class="flex min-w-0 flex-1 overflow-hidden"> <MessageList :key="chatStore.getActiveThreadId() ?? 'default'" ref="messageList" :messages="chatStore.getMessages()" /> </div> - <!-- ACP Workspace 面板 --> + <!-- ACP Workspace panel --> <Transition name="workspace-slide">src/main/presenter/llmProviderPresenter/agent/acpFsHandler.ts (1)
108-112: Consider wrapping callback invocation in try-catch.If
onFileChangethrows, the error will propagate and thewriteTextFileoperation will appear to fail even though the file was successfully written. This could lead to confusing behavior where the file exists but the caller receives an error.// Notify file change if (this.onFileChange) { - this.onFileChange(filePath) + try { + this.onFileChange(filePath) + } catch (error) { + console.error('[AcpFsHandler] onFileChange callback failed:', error) + } }src/renderer/src/stores/searchAssistantStore.ts (1)
100-113: Consider simplifying the nested ternary for readability.The
usableSavedModelassignment uses a complex conditional. While functionally correct, the logic could be clearer.- const usableSavedModel = - savedModel && - isProviderAllowed(savedModel.providerId) && - (!hasEnabledModels || isModelEnabledForProvider(savedModel.model, savedModel.providerId)) - ? savedModel - : null + const isValidSavedModel = + savedModel && + isProviderAllowed(savedModel.providerId) && + (!hasEnabledModels || isModelEnabledForProvider(savedModel.model, savedModel.providerId)) + + const usableSavedModel = isValidSavedModel ? savedModel : nullsrc/main/presenter/llmProviderPresenter/providers/acpProvider.ts (1)
329-333: Consider using debug-level logging instead of commenting out.Commenting out logging makes it harder to enable when debugging issues. Consider using a debug log level that can be controlled via configuration.
onSessionUpdate: (notification) => { - // console.log('[ACP] onSessionUpdate: notification:', JSON.stringify(notification)) + // Debug-level logging can be enabled via environment variable + if (import.meta.env.VITE_LOG_ACP_SESSION === '1') { + console.log('[ACP] onSessionUpdate: notification:', JSON.stringify(notification)) + } const mapped = this.contentMapper.map(notification) mapped.events.forEach((event) => queue.push(event)) },src/renderer/src/components/acp-workspace/AcpWorkspacePlan.vue (1)
115-120: Fixedmax-heightmay clip long plan lists during transition.The
max-height: 300pxin the transition could cause visual clipping if the plan has many entries. Consider using a larger value or a JavaScript-based height calculation for smoother transitions with variable content..workspace-collapse-enter-to, .workspace-collapse-leave-from { opacity: 1; transform: translateY(0); - max-height: 300px; + max-height: 600px; /* Accommodate larger plan lists */ }src/renderer/src/stores/acpWorkspace.ts (1)
107-119: Direct mutation ofnodeparameter may cause reactivity issues.The
loadDirectoryChildrenfunction directly mutates thenodeobject passed to it. While this works because the node is part of the reactivefileTree, it's a subtle pattern that could break if the node reference changes. Consider returning the updated node or using a more explicit update pattern.const loadDirectoryChildren = async (node: AcpFileNode): Promise<void> => { if (!node.isDirectory) return try { const children = (await acpWorkspacePresenter.expandDirectory(node.path)) ?? [] - node.children = children - node.expanded = true + // Explicitly update through Vue's reactivity system + Object.assign(node, { children, expanded: true }) } catch (error) { console.error('[AcpWorkspace] Failed to load directory children:', error) - node.children = [] - node.expanded = true + Object.assign(node, { children: [], expanded: true }) } }src/renderer/src/components/acp-workspace/AcpWorkspaceFiles.vue (2)
96-100: Consider increasingmax-heightfor larger file trees.The
max-height: 300pxtransition constraint may clip content when the file tree exceeds this height. For deeply nested directories, this could cause visual truncation during animation..workspace-collapse-enter-to, .workspace-collapse-leave-from { opacity: 1; transform: translateY(0); - max-height: 300px; + max-height: 1000px; }
61-70: Consider memoizing file count for performance.The
countFilesfunction recursively traverses the entire tree on every render. For large file trees, this could impact performance. Vue'scomputedalready provides caching, but the recursion itself runs each timefileTreechanges.The current implementation is acceptable for typical workspace sizes. If performance becomes an issue with very large trees, consider maintaining a count in the store.
src/main/presenter/acpWorkspacePresenter/directoryReader.ts (1)
46-51: Consider handling symbolic links to prevent directory traversal.If a symlink points outside the workspace directory,
path.joinwill follow it. For security, consider checking if the resolved path stays within the workspace root.+import { realpath } from 'fs/promises' + +// Add helper to validate path is within workspace +async function isPathWithinRoot(targetPath: string, rootPath: string): Promise<boolean> { + try { + const resolvedTarget = await realpath(targetPath) + const resolvedRoot = await realpath(rootPath) + return resolvedTarget.startsWith(resolvedRoot + path.sep) || resolvedTarget === resolvedRoot + } catch { + return false + } +}Then validate before adding nodes:
const fullPath = path.join(dirPath, entry.name) if (!await isPathWithinRoot(fullPath, workspaceRoot)) { continue // Skip symlinks pointing outside workspace }src/renderer/src/components/acp-workspace/AcpWorkspaceFileNode.vue (1)
92-117: Consider extractingextensionIconMapfor reusability.The extension-to-icon mapping could be useful in other components. Consider extracting it to a shared utility if file type icons are needed elsewhere.
This is a minor suggestion for future maintainability. The current inline implementation is acceptable.
src/main/presenter/acpWorkspacePresenter/planStateManager.ts (1)
74-94: Consider pruning other terminal statuses.Currently, only
completedentries are pruned. Entries withfailedorskippedstatus will accumulate indefinitely. If conversations are long-running, consider also pruning these terminal statuses, or document thatclear()must be called at conversation end to prevent memory growth.src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts (1)
378-383: Remove or document commented-out stdout logging.Commented-out code should either be removed or documented with a reason for keeping it disabled. If this is intentionally disabled for noise reduction, consider adding a brief comment explaining why.
- // child.stdout?.on('data', (chunk: Buffer) => { - // const output = chunk.toString().trim() - // if (output) { - // console.info(`[ACP] ${agent.id} stdout: ${output}`) - // } - // }) + // Note: stdout logging disabled to reduce noise - ACP protocol uses stdout for JSON-RPC
| "contextMenu": { | ||
| "insertPath": "Insira na caixa de entrada", | ||
| "openFile": "abrir arquivo", | ||
| "revealInFolder": "Abrir no gerenciador de arquivos" | ||
| } |
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.
Inconsistent capitalization in context menu items.
Line 113 uses lowercase "abrir arquivo" while other items use title case. Consider using "Abrir arquivo" for consistency.
"contextMenu": {
"insertPath": "Insira na caixa de entrada",
- "openFile": "abrir arquivo",
+ "openFile": "Abrir arquivo",
"revealInFolder": "Abrir no gerenciador de arquivos"
}📝 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.
| "contextMenu": { | |
| "insertPath": "Insira na caixa de entrada", | |
| "openFile": "abrir arquivo", | |
| "revealInFolder": "Abrir no gerenciador de arquivos" | |
| } | |
| "contextMenu": { | |
| "insertPath": "Insira na caixa de entrada", | |
| "openFile": "Abrir arquivo", | |
| "revealInFolder": "Abrir no gerenciador de arquivos" | |
| } |
🤖 Prompt for AI Agents
In src/renderer/src/i18n/pt-BR/chat.json around lines 111 to 115, the
contextMenu translations use inconsistent capitalization: "openFile" is "abrir
arquivo" (lowercase) while other entries use title case; change "abrir arquivo"
to "Abrir arquivo" to match the casing style of the surrounding items and keep
translations consistent.
| watch( | ||
| () => chatStore.getActiveThreadId(), | ||
| async (newId) => { | ||
| if (newId !== lastSyncedConversationId.value) { | ||
| lastSyncedConversationId.value = newId ?? null | ||
| if (newId && isAcpMode.value) { | ||
| await Promise.all([refreshPlanEntries(), refreshFileTree()]) | ||
| } else { | ||
| clearData() | ||
| } | ||
| } | ||
| } | ||
| ) |
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:
# Find the chat store file and check getActiveThreadId implementation
find src/renderer/src/stores -name "*chat*" -type fRepository: ThinkInAIXYZ/deepchat
Length of output: 96
🏁 Script executed:
# Read the chat store to find getActiveThreadId implementation
cat -n src/renderer/src/stores/chat.ts | head -100Repository: ThinkInAIXYZ/deepchat
Length of output: 3974
🏁 Script executed:
# Look for more of the chat store to see if there are any issues with reactivity
wc -l src/renderer/src/stores/chat.tsRepository: ThinkInAIXYZ/deepchat
Length of output: 101
🏁 Script executed:
# Check how setActiveThreadId is implemented and used
rg -n "setActiveThreadId" src/renderer/src/stores/chat.ts -B 2 -A 5Repository: ThinkInAIXYZ/deepchat
Length of output: 1316
🏁 Script executed:
# Check the watcher implementation in acpWorkspace.ts around lines 202-214
sed -n '195,225p' src/renderer/src/stores/acpWorkspace.tsRepository: ThinkInAIXYZ/deepchat
Length of output: 767
🌐 Web query:
Vue 3 watch function reactivity Map mutations tracking
💡 Result:
Short answer
- Vue 3's reactivity supports Map/Set when you wrap them with reactive(); Map.prototype.set/delete/clear mutations are tracked. Use watchEffect or a watch getter that reads the Map (or its size/entries) to observe mutations. Don't replace the reactive Map reference (that breaks tracking). [1][2][3]
How to do it (examples)
-
Reactive Map + watchEffect (recommended for mutation tracking)
const map = reactive(new Map())
map.set('a', 1) // reactive
watchEffect(() => {
// touching map.size or iterating map makes this effect re-run on set/delete/clear
console.log(map.size, Array.from(map.entries()))
}) -
watch with a getter (only re-runs when the getter's accessed parts change)
const map = reactive(new Map())
watch(
() => [map.size, Array.from(map.entries())],
(newVal, oldVal) => { /* react to mutations */ }
)
Notes / caveats
- Replacing the reactive Map (map = new Map()) breaks reactivity — keep the same reactive object or re-wrap it. [2]
- If you need to observe nested object mutations inside values stored in the Map, ensure those values are reactive (reactive/ref) or use a deep/watchEffect pattern. [1][2]
- For timing with DOM updates, use watch/watchEffect options (flush: 'post') if you need the DOM to be updated before your callback runs. [1]
Sources
- Vue 3 watch/arrays & migration notes. [1]
- Vue reactivity fundamentals (reactive limitations, Map/Set support). [2]
- Deep-dive explanation of collection reactivity (Map/Set mutation tracking). [3]
🏁 Script executed:
# Search for any related issue comments or tests that might indicate if this is actually a problem
rg -n "getActiveThreadId\|activeThreadIdMap" src/renderer/src/stores/acpWorkspace.ts -B 2 -A 2Repository: ThinkInAIXYZ/deepchat
Length of output: 47
🏁 Script executed:
# Check how often activeThreadIdMap is modified and if there might be reactivity issues
rg -n "setActiveThreadId\|activeThreadIdMap.value.set" src/renderer/src/stores/chat.ts | head -20Repository: ThinkInAIXYZ/deepchat
Length of output: 47
Watcher may not reliably trigger on active thread changes due to suboptimal Map reactivity pattern.
getActiveThreadId() accesses reactive state (activeThreadIdMap.value), but activeThreadIdMap is defined as ref<Map> rather than reactive(Map). Vue 3 tracks Map mutations less reliably with ref<Map> compared to reactive(Map). Consider converting activeThreadIdMap to use reactive(new Map()) instead, or implementing a computed property that explicitly signals changes to ensure the watcher triggers reliably when the active thread ID changes.
| /** | ||
| * Raw plan entry from acpContentMapper | ||
| */ | ||
| export type AcpRawPlanEntry = { | ||
| content: string | ||
| status?: string | null | ||
| priority?: string | null | ||
| } |
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:
# Search for AcpRawPlanEntry usage in implementation files
rg -A 10 -B 2 'AcpRawPlanEntry' --type ts -g '!*.d.ts'Repository: ThinkInAIXYZ/deepchat
Length of output: 4702
🏁 Script executed:
# Look for acpContentMapper file
fd 'acp.*mapper' -type fRepository: ThinkInAIXYZ/deepchat
Length of output: 235
🏁 Script executed:
# Search for status validation against allowed values
rg 'AcpPlanStatus' --type ts | head -20Repository: ThinkInAIXYZ/deepchat
Length of output: 604
🏁 Script executed:
# Search for any validation of status field
rg -A 5 'status' src/shared/types/presenters/acp-workspace.d.tsRepository: ThinkInAIXYZ/deepchat
Length of output: 480
🏁 Script executed:
cat -n src/main/presenter/acpWorkspacePresenter/planStateManager.tsRepository: ThinkInAIXYZ/deepchat
Length of output: 4493
Validation exists but lacks logging for invalid status values.
The implementation properly validates raw status strings in planStateManager.ts via the normalizeStatus() method (lines 104-118), mapping them to the AcpPlanStatus enum. However, per coding guidelines requiring "log detailed error logs" and "distinguish different error types", invalid status values are silently converted to 'pending' without logging. Consider adding a warning log when unexpected status values are encountered to help detect data issues from acpContentMapper.
🤖 Prompt for AI Agents
In src/shared/types/presenters/acp-workspace.d.ts around lines 63 to 70, the
AcpRawPlanEntry.status can contain invalid strings that are currently normalized
silently to 'pending' in planStateManager.ts (see normalizeStatus() at ~lines
104-118); update normalizeStatus() in planStateManager.ts to log a warning when
an unexpected status value is encountered (include the raw status value and the
plan id/context if available), then continue to default to 'pending'. Use the
existing application logger (follow the same logger instance/pattern used
elsewhere in that file) and ensure the log message clearly identifies the field
and source so data issues from acpContentMapper can be traced.
* fix: Multiple Issues Affecting Conversation Flow and Model Settings (#1166) * fix: #1164 support maxtoken 2 * fix: mcp tool panel close btn #1163 * fix: #1162 file content in converation * fix(search-assistant): exclude acp models * fix: #1072 thinkcontent respects the global font size set * feat: Hebrew (he-IL) Translation (#1157) * feat: Hebrew (he-IL) Translation * feat: add workspace view to acp agents (#1158) * feat: add workspaceview for acp agent * feat: support workspace dirs * fix: workspace file refresh * fix: tool call status * fix: review refactor * chore: update readme * fix: add file context actions (#1160) * fix: keep last file list * feat(acp-workspace): add file context actions * fix(acp-workspace): move path helpers to preload * fix(preload): allow empty relative path * fix(preload): escape quotes when formatting paths * chore: update docs * fix: Multiple Issues Affecting Conversation Flow and Model Settings (#1166) * fix: #1164 support maxtoken 2 * fix: mcp tool panel close btn #1163 * fix: #1162 file content in converation * fix(search-assistant): exclude acp models * fix: #1072 thinkcontent respects the global font size set * feat: add new i18n translation * feat: add custom font setting (#1167) * feat(settings): add font customization controls * feat: change font with monaco * chore: remove log and remove unuse key * fix: linux font parse * feat: use font-list to get font * fix: font setting not work on settings page (#1169) * style: unify scroll bar style (#1173) * feat: acp init and process manage (#1171) * feat: init acp process on select * feat: warm up acp process on new thread * fix: reuse warmup process * fix: vue warning * chore: add plan for acp debug panel * feat: add debugview for acp * feat: add i18n for debug * fix: code review * fix: ai review * fix: Shutdown may skip releasing warmup‑only processes due to using warmupKey instead of agentId. * chore: update markdown renderer * chore: update mermaid node * Merge commit from fork * chore: update markstream-vue to version 0.0.3-beta.3 fix link renderer feat html_inline render * fix: increase button size for web content limit adjustment * fix: close app kill all acp processes (#1175) * fix: close app kill all acp processes * fix: disable tool call merge * fix: handle uncatch error * fix: remove redundant type * feat: add shell to powerpack (#1178) * chore(powerpack): randomize shell workdir * feat: exclusive inmem server in terminal display * fix: add sandbox in shell script --------- Co-authored-by: xiaomo <wegi866@gmail.com> Co-authored-by: Simon He <674949287@qq.com> Co-authored-by: Simon He <57086651+Simon-He95@users.noreply.github.com>
finished #1143
All contributions in this pull request were made by @uhbudrs
Summary by CodeRabbit
New Features
Documentation
Tweaks
✏️ Tip: You can customize this high-level summary in your review settings.