Skip to content

Conversation

@zerob13
Copy link
Collaborator

@zerob13 zerob13 commented Dec 3, 2025

Summary by CodeRabbit

  • New Features

    • Plan blocks with progress, statuses and collapsible tasks; message mode‑change indicators
    • In‑app terminal rendering and file‑operation displays; per‑session filesystem & terminal support
    • ACP session mode controls in chat input (cycle/set/view) and session APIs
    • Improved Mermaid rendering and masked ENV display in profile UI
  • Localization

    • Added plan and tool‑call translations across many locales
  • Documentation

    • Comprehensive ACP protocol gap analysis and rollout roadmap
  • Tests

    • New tests for capabilities, filesystem handler, and content/plan/mode handling

✏️ Tip: You can customize this high-level summary in your review settings.

- Add AcpCapabilities module for client capability declaration
- Implement AcpFsHandler for read_text_file and write_text_file
  with workspace boundary validation
- Implement AcpTerminalManager for PTY-based terminal execution
  with output buffering and lifecycle management
- Update acpProcessManager to wire fs/terminal handlers and
  advertise capabilities during initialization
- Register session workdirs for fs operation security checks
- Improve plan updates with structured PlanEntry type
- Add status icons and formatted plan display
- Handle current_mode_update notifications
- Store plan entries and mode changes in MappedContent
- Add extra metadata to reasoning blocks for UI access
…nt mapper

- Add tests for buildClientCapabilities options
- Add comprehensive tests for AcpFsHandler:
  - Path validation and workspace boundary checks
  - Read with line offset and limit parameters
  - Write with directory creation
- Add tests for plan and mode update handling in content mapper:
  - Structured plan entries with status icons
  - Mode change notifications
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 3, 2025

Walkthrough

Adds ACP protocol support: client capability builder, per-session filesystem and PTY-backed terminal manager, plan/mode handling and types, renderer plan & terminal UI with i18n, presenter APIs for session modes, tests, docs, and a minor version bump.

Changes

Cohort / File(s) Summary
ACP Core Infrastructure
src/main/presenter/llmProviderPresenter/agent/acpCapabilities.ts, src/main/presenter/llmProviderPresenter/agent/acpFsHandler.ts, src/main/presenter/llmProviderPresenter/agent/acpTerminalManager.ts
Add buildClientCapabilities; add AcpFsHandler (workspace-bound read/write, maxReadSize, ACP error mapping); add AcpTerminalManager (PTY-backed terminals, buffered UTF‑8-safe output, lifecycle APIs).
Process & Session Management
src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts, src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
Per-session workdir registration, per-session FS handlers, TerminalManager integration, capability injection on connect, expose FS/terminal RPC surface, persist available/current modes, and cleanup on session removal/shutdown.
Content Mapping & Types
src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts, src/shared/chat.d.ts
Add PlanEntry and planEntries/currentModeId to mapped content; handle plan and current_mode_update notifications (emit plan/reasoning blocks); add 'plan' to AssistantMessageBlock.type.
Renderer: Plan & Tool UI
src/renderer/src/components/message/MessageBlockPlan.vue, src/renderer/src/components/message/MessageBlockToolCall.vue, src/renderer/src/components/message/MessageBlockThink.vue, src/renderer/src/components/message/MessageItemAssistant.vue
New Plan component (collapsible); ToolCall: terminal detection + xterm rendering and file-operation UI; Think: mode-change header; wire Plan into assistant rendering.
Chat Input / ACP Mode
src/renderer/src/components/chat-input/ChatInput.vue, src/renderer/src/components/chat-input/composables/useAcpMode.ts, src/renderer/src/components/chat-input/composables/useAcpWorkdir.ts
Replace workdir toggle with ACP mode UI; add useAcpMode composable (load/cycle modes, backend calls); remove clearWorkdir from useAcpWorkdir API.
Presenter APIs & Providers
src/main/presenter/llmProviderPresenter/index.ts, src/main/presenter/llmProviderPresenter/providers/acpProvider.ts, src/main/presenter/threadPresenter/index.ts, src/shared/types/presenters/*.d.ts
Add presenter APIs to set/get ACP session modes; provider implementations to set/get modes; update presenter type declarations.
Internationalization
src/renderer/src/i18n/*/plan.json, src/renderer/src/i18n/*/toolCall.json, src/renderer/src/i18n/*/chat.json, src/renderer/src/i18n/*/index.ts (locales: en-US, zh-CN, ja-JP, ko-KR, ru-RU, fr-FR, da-DK, fa-IR, pt-BR, zh-HK, zh-TW)
Add plan translations and export in locale indexes; add modeChanged and ACP mode keys to chat locales; expand toolCall keys for terminal/file operations across locales.
Docs
docs/ACP_PROTOCOL_GAP_ANALYSIS.md, docs/ACP_UI_IMPLEMENTATION_SUMMARY.md
Add ACP protocol gap analysis and ACP UI implementation summary (design, architecture notes, rollout/testing plans).
Tests
test/main/presenter/llmProviderPresenter/acpCapabilities.test.ts, test/main/presenter/llmProviderPresenter/acpContentMapper.test.ts, test/main/presenter/llmProviderPresenter/acpFsHandler.test.ts
Unit tests for capability builder, content mapper plan/mode handling, and AcpFsHandler path/read/write behaviors.
Renderer: Mermaid Update
src/renderer/src/components/artifacts/MermaidArtifact.vue
Replace iframe rendering with direct DOM mermaid rendering, add sanitizer, theming support, MutationObserver for theme changes, and improved error handling.
Version Bump
package.json
Bumped package version from 0.5.1 to 0.5.2.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant SessionMgr as AcpSessionManager
  participant ProcessMgr as AcpProcessManager
  participant TerminalMgr as AcpTerminalManager
  participant FsHandler as AcpFsHandler
  participant Renderer

  Client->>SessionMgr: initializeSession()/createSession()
  SessionMgr->>ProcessMgr: registerSessionWorkdir(sessionId, workdir)
  ProcessMgr->>FsHandler: create per-session FsHandler(workdir)
  ProcessMgr->>TerminalMgr: ensure TerminalManager
  Client->>ProcessMgr: openConnection(capabilities from buildClientCapabilities)
  Client->>ProcessMgr: send tool_call / notifications
  alt terminal tool
    ProcessMgr->>TerminalMgr: createTerminal(request)
    TerminalMgr-->>ProcessMgr: terminalId
    TerminalMgr-->>ProcessMgr: terminalOutput events
    ProcessMgr->>Renderer: emit terminal output block
  else filesystem tool
    ProcessMgr->>FsHandler: readTextFile / writeTextFile
    FsHandler-->>ProcessMgr: response or ACP error
    ProcessMgr->>Renderer: emit file-operation block
  end
  Client->>SessionMgr: mode change / plan update
  SessionMgr->>ProcessMgr: persist currentModeId / planEntries
  ProcessMgr->>Renderer: emit plan or reasoning block
  Client->>ProcessMgr: clearSession / shutdown
  ProcessMgr->>TerminalMgr: releaseSessionTerminals(sessionId)
  ProcessMgr->>FsHandler: cleanup per-session handlers
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas needing careful review:
    • acpTerminalManager.ts — PTY spawn, cross-platform shell selection, UTF‑8 truncation, exit semantics.
    • acpFsHandler.ts — path validation, workspace-bound enforcement, symlink/escape handling, maxReadSize and ACP error mapping.
    • acpProcessManager.ts — per-session resource mapping, capability injection, RPC surface additions, cleanup ordering.
    • acpContentMapper.ts — event emission order and payload shaping for plan/mode updates and tool param capture.
    • MessageBlockToolCall.vue — xterm lifecycle, DOM refs, and terminal vs response rendering.
    • i18n index files — ensure plan import/export added consistently across locales.

Possibly related PRs

Suggested labels

codex

Suggested reviewers

  • deepinfect

Poem

🐇 I nibbled paths and spawned a shell,

plans and modes I learned to tell,
terminals hummed and files read well,
i18n stitched from shore to shore —
a hopping rabbit claps once more!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add support for acp plan and file' clearly summarizes the main change—adding support for ACP (Agent Control Protocol) plan and file operations.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/full-acp-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts (1)

606-618: Resource leak: clearSessionsForAgent does not clean up sessionWorkdirs and fsHandlers.

When an agent exits, clearSessionsForAgent cleans session listeners and permission resolvers but leaves sessionWorkdirs and fsHandlers entries orphaned for those sessions.

  private clearSessionsForAgent(agentId: string): void {
    for (const [sessionId, entry] of this.sessionListeners.entries()) {
      if (entry.agentId === agentId) {
        this.sessionListeners.delete(sessionId)
+       this.sessionWorkdirs.delete(sessionId)
+       this.fsHandlers.delete(sessionId)
+       void this.terminalManager.releaseSessionTerminals(sessionId)
      }
    }

    for (const [sessionId, entry] of this.permissionResolvers.entries()) {
      if (entry.agentId === agentId) {
        this.permissionResolvers.delete(sessionId)
      }
    }
  }
🟠 Major comments (16)
src/renderer/src/i18n/zh-HK/plan.json-2-3 (1)

2-3: Provide Hong Kong Chinese translations instead of English values.

The plan.json file for zh-HK locale contains English text ("Task Plan", "completed") rather than Traditional Chinese translations. All user-facing strings must be localized to the target language.

Provide the Hong Kong Chinese translations for these keys:

 {
-  "title": "Task Plan",
-  "completed": "completed"
+  "title": "任務計劃",
+  "completed": "已完成"
 }
src/renderer/src/i18n/zh-TW/plan.json-2-3 (1)

2-3: Provide Traditional Chinese translations instead of English values.

The plan.json file for zh-TW locale contains English text ("Task Plan", "completed") rather than Traditional Chinese translations. Per coding guidelines and the i18n pattern across the codebase, user-facing strings must be localized to their target language.

Provide the Traditional Chinese translations for these keys:

 {
-  "title": "Task Plan",
-  "completed": "completed"
+  "title": "任務計劃",
+  "completed": "已完成"
 }
src/renderer/src/i18n/ko-KR/plan.json-2-3 (1)

2-3: Provide Korean translations instead of English values.

The plan.json file for ko-KR locale contains English text ("Task Plan", "completed") rather than Korean translations. All user-facing strings must be localized to the target language.

Provide the Korean translations for these keys:

 {
-  "title": "Task Plan",
-  "completed": "completed"
+  "title": "작업 계획",
+  "completed": "완료됨"
 }
src/renderer/src/i18n/fr-FR/plan.json-2-3 (1)

2-3: Provide French translations instead of English values.

The plan.json file for fr-FR locale contains English text ("Task Plan", "completed") rather than French translations. All user-facing strings must be localized to the target language per coding guidelines and i18n best practices.

Provide the French translations for these keys:

 {
-  "title": "Task Plan",
-  "completed": "completed"
+  "title": "Plan de Tâche",
+  "completed": "complété"
 }
src/main/presenter/llmProviderPresenter/agent/acpFsHandler.ts-34-45 (1)

34-45: Fix workspace-relative path handling in validatePath

When workspaceRoot is set, validatePath currently resolves relative paths against process.cwd() rather than the session workspace:

  • const resolved = path.resolve(filePath) resolves relative to process.cwd()
  • path.relative(this.workspaceRoot, resolved) then checks if the resolved path escapes the workspace

This causes two problems:

  1. Valid workspace-relative paths (sent by ACP agents) are rejected as "escapes workspace" when process.cwd() differs from workspaceRoot
  2. Relative paths resolve to unintended locations if the Electron process cwd differs from the session workspace

Fix by anchoring resolution to the workspace root when present:

  private validatePath(filePath: string): string {
-   const resolved = path.resolve(filePath)
+   const baseDir = this.workspaceRoot ?? process.cwd()
+   const resolved = path.resolve(baseDir, filePath)
 
    if (this.workspaceRoot) {
      const relative = path.relative(this.workspaceRoot, resolved)
      if (relative.startsWith('..') || path.isAbsolute(relative)) {
        throw RequestError.invalidParams({ path: filePath }, `Path escapes workspace: ${filePath}`)
      }
    }
 
    return resolved
  }

This preserves the security boundary check while ensuring relative paths resolve within the session workspace.

src/renderer/src/i18n/da-DK/plan.json-1-4 (1)

1-4: Translate English strings to Danish.

Both translation values are in English instead of Danish. This will display English text in the plan UI for Danish-speaking users.

Apply proper Danish translations:

 {
-  "title": "Task Plan",
-  "completed": "completed"
+  "title": "Opgaveplan",
+  "completed": "fuldført"
 }
src/renderer/src/i18n/ja-JP/chat.json-31-31 (1)

31-31: Translate English string to Japanese.

The modeChanged value is in English instead of Japanese. This will display English text to Japanese-speaking users when the mode changes.

Apply proper Japanese translation:

-    "modeChanged": "Mode changed to: {mode}"
+    "modeChanged": "モードが {mode} に変更されました"
src/renderer/src/i18n/fa-IR/chat.json-31-31 (1)

31-31: Translate English string to Persian.

The modeChanged value is in English instead of Persian. This will display English text to Persian-speaking users when the mode changes.

Apply proper Persian translation:

-    "modeChanged": "Mode changed to: {mode}"
+    "modeChanged": "حالت به {mode} تغییر یافت"
src/renderer/src/i18n/pt-BR/chat.json-31-31 (1)

31-31: Translate English string to Portuguese.

The modeChanged value is in English instead of Portuguese. This will display English text to Brazilian Portuguese speakers when the mode changes.

Apply proper Portuguese translation:

-    "modeChanged": "Mode changed to: {mode}"
+    "modeChanged": "Modo alterado para: {mode}"
src/renderer/src/i18n/fr-FR/toolCall.json-12-18 (1)

12-18: Translate English strings to French.

The new translation keys contain English text instead of French translations. This will display English text to French-speaking users in the terminal and file operation UI.

Apply proper French translations for these keys:

-  "terminalOutput": "Terminal Output",
-  "fileOperation": "File Operation",
-  "fileRead": "Read File",
-  "fileWrite": "Write File",
-  "filePath": "File Path",
-  "success": "Success",
-  "failed": "Failed"
+  "terminalOutput": "Sortie du terminal",
+  "fileOperation": "Opération de fichier",
+  "fileRead": "Lire le fichier",
+  "fileWrite": "Écrire le fichier",
+  "filePath": "Chemin du fichier",
+  "success": "Succès",
+  "failed": "Échec"
src/renderer/src/i18n/da-DK/toolCall.json-12-18 (1)

12-18: Translate English strings to Danish.

The new translation keys contain English text instead of Danish translations. This will display English text to users who have selected Danish as their language, breaking the localized user experience.

Apply proper Danish translations for these keys:

-  "terminalOutput": "Terminal Output",
-  "fileOperation": "File Operation",
-  "fileRead": "Read File",
-  "fileWrite": "Write File",
-  "filePath": "File Path",
-  "success": "Success",
-  "failed": "Failed"
+  "terminalOutput": "Terminal Output",
+  "fileOperation": "Filhandling",
+  "fileRead": "Læs fil",
+  "fileWrite": "Skriv fil",
+  "filePath": "Filsti",
+  "success": "Succes",
+  "failed": "Mislykkedes"
src/renderer/src/i18n/ja-JP/toolCall.json-12-18 (1)

12-18: Translate new keys to Japanese.

The new translation keys (terminalOutput, fileOperation, fileRead, fileWrite, filePath, success, failed) contain English values in a Japanese locale file. All user-facing strings in ja-JP should be translated to Japanese to maintain consistency with existing translations.

Based on coding guidelines for i18n consistency across all language translation files.

src/renderer/src/i18n/pt-BR/toolCall.json-12-18 (1)

12-18: Translate new keys to Portuguese.

The new translation keys (terminalOutput, fileOperation, fileRead, fileWrite, filePath, success, failed) contain English values in a Brazilian Portuguese locale file. All user-facing strings in pt-BR should be translated to Portuguese to maintain consistency with existing translations.

Based on coding guidelines for i18n consistency across all language translation files.

src/renderer/src/i18n/da-DK/chat.json-7-7 (1)

7-7: Translate new key to Danish.

The modeChanged key contains an English value in a Danish locale file. This should be translated to Danish to maintain consistency with other translations in this file.

Based on coding guidelines for i18n consistency across all language translation files.

src/renderer/src/components/message/MessageBlockToolCall.vue-283-294 (1)

283-294: Terminal may be re-initialized on each watch trigger.

The watch callback calls initTerminal() on every change to isExpanded or response, but initTerminal() creates a new terminal without checking if one already exists. This could cause multiple terminals to be created or memory leaks.

 const initTerminal = () => {
   if (!terminalContainer.value || !isTerminalTool.value) return
+  if (terminal) return // Already initialized
 
   terminal = new Terminal({

Or add cleanup before re-initialization if you want to support re-rendering:

 const initTerminal = () => {
   if (!terminalContainer.value || !isTerminalTool.value) return
+  
+  // Dispose existing terminal before creating new one
+  if (terminal) {
+    terminal.dispose()
+  }
 
   terminal = new Terminal({

Committable suggestion skipped: line range outside the PR's diff.

src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts-94-104 (1)

94-104: Security: Fallback to unrestricted file system handler is risky.

Creating an unrestricted handler (workspaceRoot: null) when no session is registered allows the agent to access any file on the system. This fallback should either throw an error or restrict access to a safe default directory.

Consider failing fast instead of falling back to unrestricted access:

  private getFsHandler(sessionId: string): AcpFsHandler {
    const handler = this.fsHandlers.get(sessionId)
    if (!handler) {
-     // Fallback: create handler with no workspace restriction
-     console.warn(
-       `[ACP] No fs handler registered for session ${sessionId}, using unrestricted handler`
-     )
-     return new AcpFsHandler({ workspaceRoot: null })
+     throw new Error(
+       `[ACP] No fs handler registered for session ${sessionId}. ` +
+       `Call registerSessionWorkdir before performing fs operations.`
+     )
    }
    return handler
  }

Alternatively, if a fallback is required, use a safe restricted directory like a temp folder.

🟡 Minor comments (1)
src/renderer/src/i18n/ru-RU/toolCall.json-12-18 (1)

12-18: Missing Russian translations for new keys.

The new keys use English text instead of Russian translations. This breaks localization consistency for Russian users. Based on learnings, all language files should maintain consistent key-value structure with proper translations.

Suggested Russian translations:

-  "terminalOutput": "Terminal Output",
-  "fileOperation": "File Operation",
-  "fileRead": "Read File",
-  "fileWrite": "Write File",
-  "filePath": "File Path",
-  "success": "Success",
-  "failed": "Failed"
+  "terminalOutput": "Вывод терминала",
+  "fileOperation": "Операция с файлом",
+  "fileRead": "Чтение файла",
+  "fileWrite": "Запись файла",
+  "filePath": "Путь к файлу",
+  "success": "Успешно",
+  "failed": "Ошибка"
🧹 Nitpick comments (16)
docs/ACP_PROTOCOL_GAP_ANALYSIS.md (1)

1-12: Wrap bare URLs in markdown link syntax and add language specifiers to code blocks.

The markdown linter flags bare URLs (lines 4–11) and missing language specifiers on fenced code blocks throughout the document. While not blocking, these should be fixed for consistency with markdown best practices.

For bare URLs, wrap them in markdown link syntax:

-https://agentclientprotocol.com/protocol/prompt-turn
+[Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)

For fenced code blocks, add language specifiers (e.g., ```typescript instead of ```). This applies to lines 115, 146, 206, 644, 676, 722, 750, 839, 856, 875.

src/renderer/src/i18n/zh-HK/toolCall.json (1)

11-18: Localize new tool-call labels for zh-HK

The newly added keys (terminalOutput, fileOperation, fileRead, fileWrite, filePath, success, failed) are currently English in a Traditional Chinese (zh-HK) file, whereas the rest of the file is localized.

Consider providing Traditional Chinese translations for these values (or confirming that English is intentional for this locale) to keep the user experience consistent across keys.

src/main/presenter/llmProviderPresenter/agent/acpTerminalManager.ts (2)

53-64: Revisit command construction and argument handling for terminals

The non‑Windows branch runs:

shell = '/bin/bash'
shellArgs = ['-c', [params.command, ...(params.args ?? [])].join(' ')]

This effectively treats command + args as a single shell script string. That:

  • Changes semantics from “command + argv” to “bash -c ''”
  • Loses explicit argument boundaries (spaces, quoting, special characters in args may break or be interpreted by the shell)
  • Potentially broadens what the agent can execute vs. a more direct spawn(command, args, …) style

If ACP’s CreateTerminalRequest semantics are intended to be “run this executable with these args”, you may want to:

  • Either call spawn(params.command, params.args ?? [], …) directly, or
  • Explicitly document that this manager provides a shell and that command/args are combined into one shell command, and ensure any callers match that contract.

Clarifying this now will avoid subtle cross‑platform differences and quoting bugs later.


229-243: truncateAtCharBoundary likely doesn’t enforce UTF‑8 boundaries as intended

The helper currently does:

const buf = Buffer.from(str, 'utf-8')
if (buf.length <= maxBytes) return str

let truncated = buf.subarray(0, maxBytes)
while (truncated.length > 0) {
  try {
    return truncated.toString('utf-8')
  } catch {
    truncated = truncated.subarray(0, truncated.length - 1)
  }
}

In Node, Buffer.toString('utf8') decodes invalid sequences with replacement characters and does not throw, so the while loop will almost always return on the first iteration. That means:

  • You may still end up cutting a multi‑byte character in the middle.
  • The loop and try/catch add complexity but don’t change behavior.

If you do care about strict character boundaries, consider either:

  • Using a dedicated UTF‑8 boundary calculation (e.g., scanning backward from maxBytes until you hit a valid leading byte), or
  • Simplifying the function to just slice by bytes and accept that the last character may be replaced, updating the comment accordingly.

Right now the code works functionally, but the implementation doesn’t match the comment’s intent.

src/renderer/src/i18n/pt-BR/plan.json (1)

1-4: Consider localizing plan strings for pt-BR

This new plan.json for pt-BR uses English values:

  • "title": "Task Plan"
  • "completed": "completed"

For consistency with the rest of the pt-BR locale, consider translating these strings into Brazilian Portuguese (or explicitly confirming that English is acceptable as a temporary fallback).

src/renderer/src/i18n/ko-KR/chat.json (1)

30-31: Localize features.modeChanged for ko-KR

The new modeChanged key currently has an English value:

"modeChanged": "Mode changed to: {mode}"

Since the rest of the features section is in Korean, consider translating this string to Korean to keep the KO locale consistent for end users.

src/renderer/src/i18n/fr-FR/chat.json (1)

30-31: Localize features.modeChanged for fr-FR

The new modeChanged key is currently:

"modeChanged": "Mode changed to: {mode}"

In a French locale where surrounding strings are translated, this will stand out. Consider providing a French translation (e.g., along the lines of “Mode changé en : {mode}”) to keep the UX consistent.

src/renderer/src/i18n/fa-IR/plan.json (1)

1-4: Localize plan strings for fa-IR

The new fa-IR/plan.json defines:

"title": "Task Plan",
"completed": "completed"

For a Persian locale, these English values are functional but inconsistent with a fully localized UI. When translation resources are available, consider replacing them with Persian equivalents to align with other i18n files.

src/renderer/src/i18n/zh-HK/chat.json (1)

30-31: New modeChanged key wiring is correct; consider localizing text

The features.modeChanged key aligns with the usage in MessageBlockThink.vue (t('chat.features.modeChanged', { mode })), and the placeholder {mode} is consistent.

However, the value is English ("Mode changed to: {mode}") in an otherwise Traditional Chinese zh-HK file. If you want fully localized UX here, consider providing a zh-HK translation instead of English.

Also, please double‑check that all other locales define chat.features.modeChanged so this header doesn’t fall back to a missing key in some languages, in line with the “consistent key structure across locales” guideline.

src/renderer/src/i18n/ko-KR/toolCall.json (1)

11-18: ToolCall keys added correctly; consider localizing new Korean strings

The additional keys for terminal/file operations (terminalOutput, fileOperation, fileRead, fileWrite, filePath, success, failed) align with the expanded tool-call UI and follow the existing key structure.

Right now, all of these values are English in the ko-KR locale. To provide a consistent localized experience, consider translating these into Korean, keeping the placeholders and semantics intact (e.g., keep {} variables as-is).

Also, ensure the same key set is present in other locales so tool-call UIs don’t hit missing translations. Based on learnings, consistent key structure across locales is expected.

src/renderer/src/i18n/ja-JP/plan.json (1)

1-4: ja-JP plan keys are correct; recommend localizing values

The title and completed keys match other locales and will integrate fine with t('plan.title') / t('plan.completed').

To align with the localization guidelines and the zh-CN variant, consider replacing the English values with Japanese translations while keeping the same keys, so ja-JP users don’t see English labels in the plan UI.

src/renderer/src/i18n/ru-RU/plan.json (1)

1-4: ru-RU plan keys are consistent; recommend Russian translations

The ru-RU plan.json uses the same keys (title, completed) as other locales, which is good for structural consistency.

For better localization, consider providing Russian translations for these values instead of the current English strings, keeping the key structure unchanged to satisfy cross-locale consistency.

test/main/presenter/llmProviderPresenter/acpContentMapper.test.ts (1)

195-237: LGTM! Mode handling tests are well-structured.

Tests verify currentModeId population, reasoning event emission, and block extra data storage. Consider adding a test for missing currentModeId (empty/undefined) to match the empty plan entries test pattern.

src/renderer/src/components/message/MessageBlockPlan.vue (1)

73-77: Consider using the shared PlanEntry type.

A PlanEntry interface is also defined in acpContentMapper.ts. Consider importing the shared type to maintain consistency and avoid duplication.

-interface PlanEntry {
-  content: string
-  priority?: string | null
-  status?: string | null
-}
+import type { PlanEntry } from '@/presenter/llmProviderPresenter/agent/acpContentMapper'

Alternatively, if the type needs to be shared across renderer and main, consider moving it to @shared/chat.d.ts.

src/renderer/src/components/message/MessageBlockToolCall.vue (1)

204-212: Heuristic tool type detection may have false positives.

The detection logic uses simple includes() checks which could match unintended tool names. For example, isFileSystemTool would match any tool containing "read" (like "readDatabase") and isTerminalTool would match "executeQuery".

Consider using more specific patterns or checking for known tool names:

const FILE_TOOLS = ['read_file', 'write_file', 'readTextFile', 'writeTextFile']
const TERMINAL_TOOLS = ['run_command', 'execute_terminal', 'terminal_exec']

const isFileSystemTool = computed(() => {
  const name = props.block.tool_call?.name || ''
  return FILE_TOOLS.some(t => name.includes(t))
})
docs/ACP_UI_IMPLEMENTATION_SUMMARY.md (1)

115-123: Add language specifier to fenced code blocks for ASCII diagrams.

Static analysis flags these ASCII diagrams as missing a language specifier. Using text silences the lint warning and indicates these are human-readable diagrams rather than executable code.

-```
+```text
 Agent (ACP Process)
   ↓
 AcpContentMapper (处理 plan/mode 更新)
   ↓
 MessageBlock (plan 类型块)
   ↓
 MessageBlockPlan.vue (UI 渲染)

Apply the same fix to the diagram at lines 126-134.

</blockquote></details>

</blockquote></details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6aa51ef and 4915d8c.

📒 Files selected for processing (27)
  • src/renderer/src/i18n/da-DK/chat.json (1 hunks)
  • src/renderer/src/i18n/da-DK/plan.json (1 hunks)
  • src/renderer/src/i18n/da-DK/toolCall.json (1 hunks)
  • src/renderer/src/i18n/fa-IR/chat.json (1 hunks)
  • src/renderer/src/i18n/fa-IR/plan.json (1 hunks)
  • src/renderer/src/i18n/fa-IR/toolCall.json (1 hunks)
  • src/renderer/src/i18n/fr-FR/chat.json (1 hunks)
  • src/renderer/src/i18n/fr-FR/plan.json (1 hunks)
  • src/renderer/src/i18n/fr-FR/toolCall.json (1 hunks)
  • src/renderer/src/i18n/ja-JP/chat.json (1 hunks)
  • src/renderer/src/i18n/ja-JP/plan.json (1 hunks)
  • src/renderer/src/i18n/ja-JP/toolCall.json (1 hunks)
  • src/renderer/src/i18n/ko-KR/chat.json (1 hunks)
  • src/renderer/src/i18n/ko-KR/plan.json (1 hunks)
  • src/renderer/src/i18n/ko-KR/toolCall.json (1 hunks)
  • src/renderer/src/i18n/pt-BR/chat.json (1 hunks)
  • src/renderer/src/i18n/pt-BR/plan.json (1 hunks)
  • src/renderer/src/i18n/pt-BR/toolCall.json (1 hunks)
  • src/renderer/src/i18n/ru-RU/chat.json (1 hunks)
  • src/renderer/src/i18n/ru-RU/plan.json (1 hunks)
  • src/renderer/src/i18n/ru-RU/toolCall.json (1 hunks)
  • src/renderer/src/i18n/zh-HK/chat.json (1 hunks)
  • src/renderer/src/i18n/zh-HK/plan.json (1 hunks)
  • src/renderer/src/i18n/zh-HK/toolCall.json (1 hunks)
  • src/renderer/src/i18n/zh-TW/chat.json (1 hunks)
  • src/renderer/src/i18n/zh-TW/plan.json (1 hunks)
  • src/renderer/src/i18n/zh-TW/toolCall.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (17)
  • src/renderer/src/i18n/fa-IR/plan.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/da-DK/plan.json
  • src/renderer/src/i18n/ru-RU/plan.json
  • src/renderer/src/i18n/ko-KR/plan.json
  • src/renderer/src/i18n/zh-TW/chat.json
  • src/renderer/src/i18n/ja-JP/plan.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/zh-HK/plan.json
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/renderer/src/i18n/pt-BR/toolCall.json
  • src/renderer/src/i18n/zh-TW/toolCall.json
  • src/renderer/src/i18n/zh-TW/plan.json
  • src/renderer/src/i18n/zh-HK/toolCall.json
🧰 Additional context used
📓 Path-based instructions (3)
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/pt-BR/plan.json
  • src/renderer/src/i18n/da-DK/toolCall.json
  • src/renderer/src/i18n/fr-FR/plan.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/ko-KR/toolCall.json
  • src/renderer/src/i18n/fr-FR/toolCall.json
  • src/renderer/src/i18n/ja-JP/toolCall.json
  • src/renderer/src/i18n/fa-IR/toolCall.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ru-RU/toolCall.json
src/**/*

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

New features should be developed in the src directory

Files:

  • src/renderer/src/i18n/pt-BR/plan.json
  • src/renderer/src/i18n/da-DK/toolCall.json
  • src/renderer/src/i18n/fr-FR/plan.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/ko-KR/toolCall.json
  • src/renderer/src/i18n/fr-FR/toolCall.json
  • src/renderer/src/i18n/ja-JP/toolCall.json
  • src/renderer/src/i18n/fa-IR/toolCall.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ru-RU/toolCall.json
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/pt-BR/plan.json
  • src/renderer/src/i18n/da-DK/toolCall.json
  • src/renderer/src/i18n/fr-FR/plan.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/ko-KR/toolCall.json
  • src/renderer/src/i18n/fr-FR/toolCall.json
  • src/renderer/src/i18n/ja-JP/toolCall.json
  • src/renderer/src/i18n/fa-IR/toolCall.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ru-RU/toolCall.json
🧠 Learnings (7)
📚 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/renderer/src/i18n/pt-BR/plan.json
  • src/renderer/src/i18n/da-DK/toolCall.json
  • src/renderer/src/i18n/fr-FR/plan.json
  • src/renderer/src/i18n/ko-KR/toolCall.json
  • src/renderer/src/i18n/fr-FR/toolCall.json
  • src/renderer/src/i18n/ja-JP/toolCall.json
  • src/renderer/src/i18n/fa-IR/toolCall.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ru-RU/toolCall.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/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/da-DK/toolCall.json
  • src/renderer/src/i18n/fa-IR/toolCall.json
  • src/renderer/src/i18n/ru-RU/toolCall.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/fr-FR/plan.json
  • src/renderer/src/i18n/fr-FR/toolCall.json
  • src/renderer/src/i18n/fa-IR/toolCall.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/renderer/**/*.vue : All user-facing strings must use i18n keys via vue-i18n for internationalization

Applied to files:

  • src/renderer/src/i18n/fa-IR/toolCall.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} : All user-facing strings must use i18n keys with vue-i18n framework in the renderer

Applied to files:

  • src/renderer/src/i18n/fa-IR/toolCall.json
📚 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/fa-IR/toolCall.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/renderer/src/i18n/fa-IR/toolCall.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). (1)
  • GitHub Check: build-check (x64)
🔇 Additional comments (11)
src/renderer/src/i18n/ko-KR/chat.json (1)

30-31: No action needed. The new modeChanged key has been consistently added across all seven language translation files (zh-CN, en-US, ko-KR, ru-RU, zh-HK, fr-FR, fa-IR), meeting the coding guidelines for consistent key-value structure. The syntax and placement in ko-KR/chat.json are correct.

src/renderer/src/i18n/fa-IR/toolCall.json (2)

1-19: Translation coverage improved: Persian translations now provided for all keys.

This resolves the previous critical issue where new keys contained untranslated English values. All 7 flagged keys (terminalOutput, fileOperation, fileRead, fileWrite, filePath, success, failed) now have Persian translations. The file maintains consistency with the flat key-value structure used across other locale files and follows the i18n conventions properly.


13-13: The "response" translation in fa-IR is semantically correct and consistent across all locale files. The Persian translation "در حال دویدن" (literally "in the process of running") aligns with translations in all other locales (en-US: "Running...", zh-CN: "运行中", fr-FR: "En cours d'exécution", etc.), confirming that the "response" key represents the in-progress status of a tool call response, not a literal response object. No changes needed.

src/renderer/src/i18n/da-DK/toolCall.json (1)

1-19: Key consistency across all language files is maintained.

All new keys (fileOperation, filePath, fileRead, fileWrite, terminalOutput, success, failed) are present and identically named in all 11 language translation files (da-DK, en-US, fa-IR, fr-FR, ja-JP, ko-KR, pt-BR, ru-RU, zh-CN, zh-HK, zh-TW). Each file contains exactly 17 keys with consistent structure.

Note: The camelCase naming pattern (fileOperation vs file.operation) is consistent across the entire toolCall.json codebase and not introduced by this PR.

src/renderer/src/i18n/ru-RU/toolCall.json (1)

6-10: All 7 new translation keys (failed, fileOperation, filePath, fileRead, fileWrite, success, terminalOutput) have been consistently added to all language translation files in src/renderer/src/i18n, including zh-CN, en-US, ko-KR, ru-RU, zh-HK, fr-FR, fa-IR, and additional languages (da-DK, ja-JP, pt-BR, zh-TW). Consistent key-value structure is maintained across all language files.

src/renderer/src/i18n/ko-KR/toolCall.json (2)

1-19: File structure and formatting look good.

The JSON structure is valid, properly formatted, and consistent with existing translation file conventions. All keys maintain lowercase formatting appropriate for this i18n file.


6-18: No action required — key consistency verified across all language files.

All new keys (failed, fileOperation, filePath, fileRead, fileWrite, params, responseData, success, terminalOutput) are consistently present in all language translation files (en-US, zh-CN, ru-RU, zh-HK, fr-FR, fa-IR). The i18n guideline for maintaining consistent key-value structure across locales is satisfied.

src/renderer/src/i18n/fr-FR/chat.json (1)

30-31: JSON syntax and key structure look good.

The "modeChanged" key follows the existing camelCase naming convention and the parameterized value format is consistent with other entries in the file.

src/renderer/src/i18n/fr-FR/toolCall.json (1)

2-18: No action needed. The French translation uses appropriate sentence-case capitalization following French language conventions, not a deviation. Comparing en-US title-case values to localized sentence-case translations is not a valid concern—other locales (ru-RU, ko-KR) follow similar patterns where translated values use natural capitalization for their respective languages rather than mimicking English title case. All required keys are present across locales.

src/renderer/src/i18n/ja-JP/toolCall.json (2)

1-19: Key consistency verification complete — all locales are properly aligned.

All 11 supported locales (da-DK, en-US, fa-IR, fr-FR, ja-JP, ko-KR, pt-BR, ru-RU, zh-CN, zh-HK, zh-TW) contain exactly 17 keys each in toolCall.json with no missing or extra keys. The new ACP-related keys (fileOperation, filePath, fileRead, fileWrite, terminalOutput) are present and properly translated across all locales.


2-2: Fix translation accuracy to match UI context and standard Japanese terminology.

The Japanese translations contain semantic misalignments with their UI context:

  • Line 2: "calling": "電話をかける" literally means "making a phone call" and is inappropriate for tool invocation. Use "呼び出し中" or "実行中" to match English "Calling..." and Chinese "调用中".
  • Line 4: "end": "仕上げる" (to polish/finish) is non-standard UI Japanese. Use "完了" or "終了" instead, consistent with standard UI terminology.
  • Line 5: "error": "間違い" (mistake as noun) should be "エラー", the standard Japanese UI term for errors.
⛔ Skipped due to learnings
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)
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')

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/renderer/src/i18n/ru-RU/toolCall.json (1)

3-18: Rename new i18n keys to follow dot-separated, lowercase convention

Lines 6–10 and 18 still introduce/keep camelCase keys like fileOperation, filePath, fileRead, fileWrite, terminalOutput, which conflicts with the guideline to use dot-separated, lowercase hierarchical keys (e.g., common.button.submit). This was already raised in a previous review and remains unresolved.

Consider refactoring these keys (and matching them across all locales and usages in code) along the lines of:

-  "fileOperation": "Операции с файлами",
-  "filePath": "путь к файлу",
-  "fileRead": "прочитать файл",
-  "fileWrite": "записать файл",
-  "terminalOutput": "Выходной терминал"
+  "file.operation": "Операции с файлами",
+  "file.path": "путь к файлу",
+  "file.read": "прочитать файл",
+  "file.write": "записать файл",
+  "terminal.output": "Вывод терминала"

You’ll also need to update the corresponding keys in other locale files and any components that reference the old camelCase names to keep the i18n structure consistent.

Optionally, you might also polish a couple of labels for more natural Russian (e.g., Line 4 end: something like "Вызов завершен" / "Завершено" instead of "Заканчивать"), but that’s secondary compared to fixing the key naming.

As per coding guidelines and previous review comments, and based on learnings, ...

🧹 Nitpick comments (1)
src/renderer/src/i18n/zh-TW/index.ts (1)

19-19: Plan namespace wiring is consistent and correct

Importing plan from ./plan.json and exposing it as a top‑level namespace in the default export follows the same pattern as the existing i18n modules (e.g., promptSetting, toolCall). No issues from a TypeScript or i18n wiring perspective. Just ensure plan.json in zh-TW stays key‑aligned with the corresponding plan.json files in other locales to keep translations consistent.

Also applies to: 53-53

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4915d8c and e812323.

📒 Files selected for processing (11)
  • src/renderer/src/i18n/fa-IR/index.ts (2 hunks)
  • src/renderer/src/i18n/fr-FR/index.ts (2 hunks)
  • src/renderer/src/i18n/fr-FR/plan.json (1 hunks)
  • src/renderer/src/i18n/ja-JP/index.ts (2 hunks)
  • src/renderer/src/i18n/ko-KR/index.ts (2 hunks)
  • src/renderer/src/i18n/ko-KR/toolCall.json (1 hunks)
  • src/renderer/src/i18n/pt-BR/index.ts (2 hunks)
  • src/renderer/src/i18n/ru-RU/index.ts (2 hunks)
  • src/renderer/src/i18n/ru-RU/toolCall.json (1 hunks)
  • src/renderer/src/i18n/zh-HK/index.ts (2 hunks)
  • src/renderer/src/i18n/zh-TW/index.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/renderer/src/i18n/fr-FR/plan.json
🧰 Additional context used
📓 Path-based instructions (20)
**/*.{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/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
**/*.{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/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
src/renderer/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use the usePresenter.ts composable for renderer-to-main IPC communication to call presenter methods directly

Files:

  • src/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/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/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}

📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)

Write logs and comments in English

Files:

  • src/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/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/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/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/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
src/**/*

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

New features should be developed in the src directory

Files:

  • src/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
  • src/renderer/src/i18n/ru-RU/toolCall.json
  • src/renderer/src/i18n/ko-KR/toolCall.json
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/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
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/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/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 statements

Vue 3 app code in src/renderer/src should be organized into components/, stores/, views/, i18n/, lib/ directories with shell UI in src/renderer/shell/

Files:

  • src/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
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/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
  • src/renderer/src/i18n/ru-RU/toolCall.json
  • src/renderer/src/i18n/ko-KR/toolCall.json
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/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/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/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
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 in src/renderer/src/i18n

Files:

  • src/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/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/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use OxLint for linting JavaScript and TypeScript files

Files:

  • src/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/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/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use EventBus for inter-process communication events

Files:

  • src/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/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/ru-RU/toolCall.json
  • src/renderer/src/i18n/ko-KR/toolCall.json
🧠 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/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
  • src/renderer/src/i18n/ru-RU/toolCall.json
  • src/renderer/src/i18n/ko-KR/toolCall.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/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
  • src/renderer/src/i18n/ru-RU/toolCall.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/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
  • src/renderer/src/i18n/ru-RU/toolCall.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} : All user-facing strings must use i18n keys with vue-i18n framework in the renderer

Applied to files:

  • src/renderer/src/i18n/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/fa-IR/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
  • src/renderer/src/i18n/ru-RU/toolCall.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} : 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/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
📚 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/zh-TW/index.ts
  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/zh-HK/index.ts
  • src/renderer/src/i18n/ru-RU/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
  • src/renderer/src/i18n/ru-RU/toolCall.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} : Use the dynamic locale.value property to switch languages at runtime

Applied to files:

  • src/renderer/src/i18n/pt-BR/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ja-JP/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/zh-HK/index.ts
  • src/renderer/src/i18n/fr-FR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
  • src/renderer/src/i18n/ru-RU/toolCall.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/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/ru-RU/index.ts
  • src/renderer/src/i18n/ko-KR/index.ts
  • src/renderer/src/i18n/ja-JP/index.ts
  • src/renderer/src/i18n/ru-RU/toolCall.json
📚 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/**/*.{ts,tsx} : Use camelCase for variable and function names in TypeScript files

Applied to files:

  • src/renderer/src/i18n/ru-RU/toolCall.json
🔇 Additional comments (10)
src/renderer/src/i18n/fa-IR/index.ts (1)

19-19: Plan bundle wiring for fa-IR looks consistent

Importing plan and adding it to the exported locale object matches the existing pattern for other namespaces (chat, toolCall, etc.) and keeps fa-IR aligned with the other locales. Just ensure plan.json follows the same key structure as the other languages’ plan bundles so cross-locale lookups stay consistent.

Based on learnings, maintain consistent key/value structure across all locale plan.json files.

Also applies to: 53-53

src/renderer/src/i18n/pt-BR/index.ts (1)

19-55: Plan namespace wiring for pt-BR looks consistent

Importing plan and exposing it in the default export matches the pattern of other locales and cleanly plugs the new ACP plan translations into the i18n surface. No issues from a typing or structure perspective.
Based on learnings, this keeps i18n usage consistent across locales.

src/renderer/src/i18n/ko-KR/index.ts (1)

19-19: LGTM! Plan translation namespace added correctly.

The import and export of the plan translation namespace follow the established pattern perfectly and maintain consistency with other translation modules in the ko-KR locale.

Based on learnings, this change maintains the consistent key-value structure across language translation files as confirmed by the PR's cross-locale implementation.

Also applies to: 54-54

src/renderer/src/i18n/zh-HK/index.ts (1)

18-18: ACP plan namespace is wired correctly for zh-HK

The new plan import and its inclusion in the default export follow the existing locale pattern and keep zh-HK aligned with other locales and the shared plan.json structure; no issues from an i18n or typing perspective.
Based on learnings, this maintains consistent key structure across translation files.

Also applies to: 53-53

src/renderer/src/i18n/fr-FR/index.ts (2)

19-19: LGTM! Import follows the established pattern.

The import statement correctly follows the same pattern as other translation resource imports in this file.


54-54: Export integration is correct.

The plan, export on line 54 properly adds plan translations to the fr-FR locale bundle, maintaining the established pattern. The plan.json file exists with French translations ("plan.title": "planification des missions", "plan.completed": "Complété"), and all 11 locales consistently include the plan.json file.

src/renderer/src/i18n/ja-JP/index.ts (1)

19-19: LGTM. The import and export of the plan module follows the established pattern and is consistent across all supported locales (da-DK, en-US, fa-IR, fr-FR, ja-JP, ko-KR, pt-BR, ru-RU, zh-CN, zh-HK, zh-TW).

src/renderer/src/i18n/ko-KR/toolCall.json (2)

5-5: Replace "error" translation from "실수" to "오류" for semantic accuracy.

In Korean UI contexts, "실수" (mistake/oversight made by a person) is semantically incorrect for a system error message. The appropriate technical term is "오류" (system/technical error), which aligns with the English "Error" value. Additionally, line 6 "failed": "실패하다" uses an infinitive verb form and should be "실패" or "실패했음" (noun/past form) to match standard Korean UI conventions.

Likely an incorrect or invalid review comment.


6-18: Translation keys are consistent across all locale files.

All 7 required locale files (en-US, zh-CN, ko-KR, ru-RU, zh-HK, fr-FR, fa-IR) contain the identical 17-key structure for toolCall.json, including all newly added/modified keys (failed, fileOperation, filePath, fileRead, fileWrite, responseData, success, terminalOutput). Consistency is maintained across all locales.

src/renderer/src/i18n/ru-RU/index.ts (1)

18-18: Wire-up of plan namespace for ru-RU looks correct

Importing plan and adding it to the default export is consistent with the existing pattern for other namespaces; nothing else to change here.

Also applies to: 52-52

"title": "도구 호출",
"clickToView": "세부 정보를 보려면 클릭하세요",
"error": "실수",
"failed": "실패하다",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix infinitive verb form in Korean translation.

"실패하다" uses the infinitive marker "하다". For UI status terminology, use the noun form "실패" instead to match the English "failed" state indicator semantics.

-  "failed": "실패하다",
+  "failed": "실패",
📝 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.

Suggested change
"failed": "실패하다",
"failed": "실패",
🤖 Prompt for AI Agents
In src/renderer/src/i18n/ko-KR/toolCall.json around line 6, the Korean
translation uses the infinitive verb form "실패하다" for the key "failed"; change it
to the noun/state form "실패" to match the English status semantics (replace
"실패하다" with "실패").

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e812323 and 1c824f9.

📒 Files selected for processing (24)
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts (3 hunks)
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts (8 hunks)
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts (4 hunks)
  • src/main/presenter/llmProviderPresenter/index.ts (1 hunks)
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts (1 hunks)
  • src/main/presenter/threadPresenter/index.ts (1 hunks)
  • src/renderer/src/components/chat-input/ChatInput.vue (3 hunks)
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts (1 hunks)
  • src/renderer/src/components/chat-input/composables/useAcpWorkdir.ts (0 hunks)
  • src/renderer/src/i18n/da-DK/chat.json (1 hunks)
  • src/renderer/src/i18n/en-US/chat.json (1 hunks)
  • src/renderer/src/i18n/fa-IR/chat.json (1 hunks)
  • src/renderer/src/i18n/fr-FR/chat.json (1 hunks)
  • src/renderer/src/i18n/fr-FR/plan.json (1 hunks)
  • src/renderer/src/i18n/ja-JP/chat.json (1 hunks)
  • src/renderer/src/i18n/ko-KR/chat.json (1 hunks)
  • src/renderer/src/i18n/pt-BR/chat.json (1 hunks)
  • src/renderer/src/i18n/ru-RU/chat.json (1 hunks)
  • src/renderer/src/i18n/zh-CN/chat.json (1 hunks)
  • src/renderer/src/i18n/zh-HK/chat.json (1 hunks)
  • src/renderer/src/i18n/zh-TW/chat.json (1 hunks)
  • src/shared/types/presenters/legacy.presenters.d.ts (2 hunks)
  • src/shared/types/presenters/llmprovider.presenter.d.ts (1 hunks)
  • src/shared/types/presenters/thread.presenter.d.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/renderer/src/components/chat-input/composables/useAcpWorkdir.ts
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/renderer/src/i18n/fr-FR/plan.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/en-US/chat.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/zh-TW/chat.json
  • src/renderer/src/i18n/pt-BR/chat.json
🧰 Additional context used
📓 Path-based instructions (35)
**/*.{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/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
**/*.{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/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
**/*.{js,ts,jsx,tsx,mjs,cjs}

📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)

Write logs and comments in English

Files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
src/shared/**/*.d.ts

📄 CodeRabbit inference engine (.cursor/rules/electron-best-practices.mdc)

Define type definitions in shared/*.d.ts files for objects exposed by the main process to the renderer process

Files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
src/**/*

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

New features should be developed in the src directory

Files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/zh-CN/chat.json
src/shared/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

Shared type definitions and utilities between main and renderer processes should be placed in src/shared

Files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
src/shared/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Shared types and utilities should be placed in src/shared/

Files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.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/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use OxLint for linting JavaScript and TypeScript files

Files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use EventBus for inter-process communication events

Files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/threadPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
src/main/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use EventBus from src/main/eventbus.ts for main-to-renderer communication, broadcasting events via mainWindow.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 in src/main/ with presenters in presenter/ (Window/Tab/Thread/Mcp/Config/LLMProvider) and eventbus.ts for app events
Use the Presenter pattern in the main process for UI coordination

Files:

  • src/main/presenter/threadPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/threadPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
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/threadPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
src/main/presenter/llmProviderPresenter/index.ts

📄 CodeRabbit inference engine (.cursor/rules/llm-agent-loop.mdc)

src/main/presenter/llmProviderPresenter/index.ts: In src/main/presenter/llmProviderPresenter/index.ts (startStreamCompletion), implement the Agent loop that manages the overall conversation flow, including multiple rounds of LLM calls and tool usage, maintaining conversationMessages history, calling provider.coreStream() on each iteration, and controlling the loop using needContinueConversation and toolCallCount (compared against MAX_TOOL_CALLS)
In src/main/presenter/llmProviderPresenter/index.ts, listen for standardized events yielded by coreStream and handle them accordingly: buffer text content (currentContent), handle tool_call_start/chunk/end events by collecting tool details and calling presenter.mcpPresenter.callTool, send frontend events via eventBus with tool call status, format tool results for the next LLM call, and set needContinueConversation = true
In src/main/presenter/llmProviderPresenter/index.ts, handle reasoning, text, image_data, and usage events by processing and forwarding them through STREAM_EVENTS.RESPONSE events to the frontend
In src/main/presenter/llmProviderPresenter/index.ts, handle stop events by checking stop_reason: if 'tool_use', add the buffered assistant message and prepare for the next loop iteration; otherwise, add the final assistant message and exit the loop

Files:

  • src/main/presenter/llmProviderPresenter/index.ts
src/main/presenter/llmProviderPresenter/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/llm-agent-loop.mdc)

Define the standardized LLMCoreStreamEvent interface with fields: type (text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data), content (for text), reasoning_content (for reasoning), tool_call_id, tool_call_name, tool_call_arguments_chunk (for streaming), tool_call_arguments_complete (for complete arguments), error_message, usage object with token counts, stop_reason (tool_use | max_tokens | stop_sequence | error | complete), and image_data object with Base64-encoded data and mimeType

Files:

  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
**/*Provider**/index.ts

📄 CodeRabbit inference engine (.cursor/rules/provider-guidelines.mdc)

**/*Provider**/index.ts: Output only discriminated union LLMCoreStreamEvent in Provider implementations, do not use single interface with optional fields
Use factory methods createStreamEvent.* to construct events in Provider implementations, avoid direct field pollution
Text events: emit multiple text chunks in arrival order
Reasoning events: reasoning is optional; if provided, ensure it contains the complete chain
Tool call events: strictly follow sequence tool_call_start → tool_call_chunk* → tool_call_end, ensure tool_call_id is required and stable
Stop events: emit stop at stream end with stop_reason value from {tool_use, max_tokens, stop_sequence, error, complete}
Usage events: send usage once before or at stream end with prompt_tokens, completion_tokens, and total_tokens
Rate limit events: send rate_limit event when reaching limit threshold with fields {providerId, qpsLimit, currentQps, queueLength, estimatedWaitTime?}, do not block event channel
Error handling: use error event uniformly to carry error messages, avoid mixing errors into other event fields
Error termination: after fatal error occurs, emit stop event as needed and terminate the stream
Image events: image_data event must provide data (Base64 encoded) and mimeType fields; control single frame size and frequency to avoid blocking
Do not emit AssistantMessageBlock or any UI types from Provider implementations to UI layer
Do not introduce renderer dependencies inside Provider implementations
Every event construction in Provider implementations must use factory functions
Tool call IDs in Provider implementations must be globally unique and stable, with chunks arriving strictly in order
Error scenarios in Provider implementations must have corresponding stop_reason and error message
Provider implementations must emit at least one usage event if the provider has statistics capability
Provide rate_limit events in Provider implementations...

Files:

  • src/main/presenter/llmProviderPresenter/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/fa-IR/chat.json
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/zh-CN/chat.json
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/fa-IR/chat.json
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/zh-CN/chat.json
src/renderer/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use the usePresenter.ts composable for renderer-to-main IPC communication to call presenter methods directly

Files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.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/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
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/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.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/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
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 statements

Vue 3 app code in src/renderer/src should be organized into components/, stores/, views/, i18n/, lib/ directories with shell UI in src/renderer/shell/

Files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/**/composables/*.ts

📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)

src/renderer/**/composables/*.ts: Use camelCase for composables (e.g., useAuthState.ts)
Use VueUse for common composables and utility functions
Implement custom composables for reusable logic

Files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
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/components/chat-input/composables/useAcpMode.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/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.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 in src/renderer/src/i18n

Files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
src/main/presenter/llmProviderPresenter/providers/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/main/presenter/llmProviderPresenter/providers/*.ts: Each LLM provider must implement the coreStream method following the standardized event interface for tool calling and response streaming
Convert MCP tools to provider-specific formats and normalize streaming responses to standard events in each provider implementation

src/main/presenter/llmProviderPresenter/providers/*.ts: In Provider implementations (src/main/presenter/llmProviderPresenter/providers/*.ts), the coreStream(messages, modelId, temperature, maxTokens) method should perform a single-pass streaming API request for each conversation round without containing multi-turn tool call loop logic
In Provider implementations, handle native tool support by converting MCP tools to Provider format using convertToProviderTools and including them in the API request; for Providers without native function call support, prepare messages using prepareFunctionCallPrompt before making the API call
In Provider implementations, parse Provider-specific data chunks from the streaming response and yield standardized LLMCoreStreamEvent objects conforming to the standard stream event interface, including text, reasoning, tool calls, usage, errors, stop reasons, and image data
In Provider implementations, include helper methods for Provider-specific operations such as formatMessages, convertToProviderTools, parseFunctionCalls, and prepareFunctionCallPrompt

Files:

  • src/main/presenter/llmProviderPresenter/providers/acpProvider.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/src/components/chat-input/ChatInput.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/src/components/chat-input/ChatInput.vue
src/renderer/src/**/*.vue

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

Use scoped styles to prevent CSS conflicts between Vue components

Files:

  • src/renderer/src/components/chat-input/ChatInput.vue
src/renderer/src/components/**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

src/renderer/src/components/**/*.vue: Use Tailwind for styles in Vue components
Vue component files must use PascalCase naming (e.g., ChatInput.vue)

Files:

  • src/renderer/src/components/chat-input/ChatInput.vue
🧠 Learnings (30)
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms

Applied to files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, include helper methods for Provider-specific operations such as `formatMessages`, `convertToProviderTools`, `parseFunctionCalls`, and `prepareFunctionCallPrompt`

Applied to files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`

Applied to files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, handle native tool support by converting MCP tools to Provider format using `convertToProviderTools` and including them in the API request; for Providers without native function call support, prepare messages using `prepareFunctionCallPrompt` before making the API call

Applied to files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts` (`startStreamCompletion`), implement the Agent loop that manages the overall conversation flow, including multiple rounds of LLM calls and tool usage, maintaining `conversationMessages` history, calling `provider.coreStream()` on each iteration, and controlling the loop using `needContinueConversation` and `toolCallCount` (compared against `MAX_TOOL_CALLS`)

Applied to files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/main/presenter/llmProviderPresenter/providers/*.ts : Convert MCP tools to provider-specific formats and normalize streaming responses to standard events in each provider implementation

Applied to files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/**/*.ts : Define the standardized `LLMCoreStreamEvent` interface with fields: `type` (text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data), `content` (for text), `reasoning_content` (for reasoning), `tool_call_id`, `tool_call_name`, `tool_call_arguments_chunk` (for streaming), `tool_call_arguments_complete` (for complete arguments), `error_message`, `usage` object with token counts, `stop_reason` (tool_use | max_tokens | stop_sequence | error | complete), and `image_data` object with Base64-encoded data and mimeType

Applied to files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations (`src/main/presenter/llmProviderPresenter/providers/*.ts`), the `coreStream(messages, modelId, temperature, maxTokens)` method should perform a *single-pass* streaming API request for each conversation round without containing multi-turn tool call loop logic

Applied to files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.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/main/presenter/llmProviderPresenter/providers/*.ts : Each LLM provider must implement the `coreStream` method following the standardized event interface for tool calling and response streaming

Applied to files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, parse Provider-specific data chunks from the streaming response and `yield` standardized `LLMCoreStreamEvent` objects conforming to the standard stream event interface, including text, reasoning, tool calls, usage, errors, stop reasons, and image data

Applied to files:

  • src/shared/types/presenters/llmprovider.presenter.d.ts
  • src/main/presenter/llmProviderPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/**/*.ts : Use the `usePresenter.ts` composable for renderer-to-main IPC communication to call presenter methods directly

Applied to files:

  • src/main/presenter/threadPresenter/index.ts
  • src/shared/types/presenters/thread.presenter.d.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, handle `reasoning`, `text`, `image_data`, and `usage` events by processing and forwarding them through `STREAM_EVENTS.RESPONSE` events to the frontend

Applied to files:

  • src/main/presenter/threadPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to {src/main/presenter/**/*.ts,src/renderer/**/*.ts} : Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs

Applied to files:

  • src/shared/types/presenters/thread.presenter.d.ts
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
📚 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/main/**/*.ts : Use the Presenter pattern in the main process for UI coordination

Applied to files:

  • src/shared/types/presenters/thread.presenter.d.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 : 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/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/zh-CN/chat.json
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use VueUse for common composables and utility functions

Applied to files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use camelCase for composables (e.g., useAuthState.ts)

Applied to files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:27:45.545Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:45.545Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Use the Composition API for better code organization and reusability in Vue.js applications

Applied to files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.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} : Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files

Applied to files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
📚 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} : Use TypeScript with Vue 3 Composition API for the renderer application

Applied to files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Implement custom composables for reusable logic

Applied to files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Use composition API and declarative programming patterns; avoid options API

Applied to files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/(components|composables)/**/*.{ts,vue} : Utilize Nuxt's auto-imports feature for components and composables

Applied to files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/(components|composables)/**/*.{ts,vue} : Use Nuxt's auto-imports for components and composables

Applied to files:

  • src/renderer/src/components/chat-input/composables/useAcpMode.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/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
📚 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/components/**/*.vue : Vue component files must use PascalCase naming (e.g., `ChatInput.vue`)

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.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} : Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,vue} : Use Iconify/Vue for icon implementation

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:27:39.200Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/provider-guidelines.mdc:0-0
Timestamp: 2025-11-25T05:27:39.200Z
Learning: Applies to **/*Provider**/index.ts : Output only discriminated union `LLMCoreStreamEvent` in Provider implementations, do not use single interface with optional fields

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/ru-RU/chat.json
  • src/renderer/src/i18n/zh-CN/chat.json
🧬 Code graph analysis (3)
src/renderer/src/components/chat-input/composables/useAcpMode.ts (1)
src/renderer/src/composables/usePresenter.ts (1)
  • usePresenter (103-105)
src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts (3)
src/main/presenter/llmProviderPresenter/agent/acpTerminalManager.ts (1)
  • AcpTerminalManager (33-244)
src/main/presenter/llmProviderPresenter/agent/acpFsHandler.ts (1)
  • AcpFsHandler (21-115)
src/main/presenter/llmProviderPresenter/agent/acpCapabilities.ts (1)
  • buildClientCapabilities (14-31)
src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts (2)
src/shared/types/core/llm-events.ts (2)
  • LLMCoreStreamEvent (87-98)
  • createStreamEvent (100-154)
src/shared/chat.d.ts (1)
  • AssistantMessageBlock (84-147)
🪛 Biome (2.1.2)
src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts

[error] 68-68: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

⏰ 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). (1)
  • GitHub Check: build-check (x64)
🔇 Additional comments (23)
src/renderer/src/i18n/da-DK/chat.json (1)

6-7: Translation keys follow established patterns and are properly structured.

The new keys (modeChanged, acpMode, acpModeTooltip, etc.) are added under appropriate hierarchical sections and follow the existing camelCase naming convention used throughout the file. The placeholder syntax {mode} is consistent with other parameterized keys like {seconds} and {count}.

Verify that these translation keys are consistently implemented across all supported locales (en-US, ko-KR, ru-RU, zh-HK, fr-FR, fa-IR, etc.) as mentioned in the PR summary. Also confirm that the new plan.json file is properly imported in the da-DK locale setup file.

Also applies to: 14-20

src/renderer/src/i18n/fa-IR/chat.json (1)

24-30: Verified: Persian translations for ACP mode and mode change keys are consistent.

The new ACP mode-related keys (acpMode, acpModeTooltip, acpModeSwitched, acpModeDefault, acpModeAcceptEdits, acpModePlan, acpModeBypassPermissions) and the features.modeChanged key are properly translated to Persian, maintaining consistency with the rest of the file and aligning with the broader i18n additions across all locales mentioned in the PR.

Also applies to: 37-37

src/renderer/src/i18n/zh-CN/chat.json (2)

23-23: Naming conventions are consistent with existing translation structure.

The new ACP-related translation keys (acpMode, acpModeTooltip, acpModeSwitched, etc.) follow the established camelCase naming pattern used throughout the file. Placeholder syntax using curly braces (e.g., {mode}, {path}) aligns with existing patterns like {count} and {seconds}. JSON hierarchy structure is properly maintained.

Also applies to: 24-30


24-30: No action needed. All new ACP translation keys (acpMode, acpModeTooltip, acpModeSwitched, acpModeDefault, acpModeAcceptEdits, acpModePlan, acpModeBypassPermissions, acpWorkdirCurrent, artifactThinking, modeChanged) have been properly added to all 11 language files (da-DK, en-US, fa-IR, fr-FR, ja-JP, ko-KR, pt-BR, ru-RU, zh-CN, zh-HK, zh-TW). The consistent key-value structure requirement is satisfied.

src/shared/types/presenters/llmprovider.presenter.d.ts (1)

230-234: LGTM! Well-defined ACP session mode API.

The new public methods extend the ACP session mode management surface cleanly. The type definitions are precise and the nullable return type for getAcpSessionModes properly handles the case where no session exists.

src/shared/types/presenters/thread.presenter.d.ts (1)

180-184: LGTM! Consistent API extension across presenter interfaces.

The method signatures match those added to ILlmProviderPresenter, maintaining consistency across the presenter layer and enabling ACP mode operations through the thread path.

src/main/presenter/threadPresenter/index.ts (1)

763-772: LGTM! Clean delegation pattern.

The implementations follow the established pattern of delegating to llmProviderPresenter for ACP operations, consistent with other ACP methods like getAcpWorkdir and setAcpWorkdir.

src/main/presenter/llmProviderPresenter/providers/acpProvider.ts (1)

659-695: LGTM! Solid implementation of ACP session mode management.

The methods properly:

  • Validate session existence before operations
  • Handle errors with appropriate logging and propagation
  • Return null gracefully when no session exists (getSessionModes)
  • Update local state after successful backend calls (setSessionMode)
src/main/presenter/llmProviderPresenter/index.ts (1)

482-499: LGTM! Consistent delegation to ACP provider.

The implementations follow the established pattern:

  • setAcpSessionMode throws an error if the ACP provider is unavailable (appropriate for mutations)
  • getAcpSessionModes returns null if the ACP provider is unavailable (graceful for queries)
  • Clean delegation to the provider instance methods
src/renderer/src/components/chat-input/ChatInput.vue (1)

150-171: LGTM! Well-integrated ACP mode UI.

The changes successfully replace the previous workdir button with ACP mode functionality:

  • Appropriate icon choice (zap) for mode cycling
  • Rich tooltip showing current mode name and description
  • Clean integration with the new useAcpMode composable
  • Consistent with existing UI patterns

Also applies to: 392-392, 609-612

src/renderer/src/i18n/ru-RU/chat.json (1)

23-30: LGTM! Proper Russian translations for ACP mode keys.

All new ACP mode keys are correctly translated to Russian:

  • Mode names and tooltips properly localized
  • Placeholders like {mode} correctly preserved
  • Consistent with the translation patterns in the file

The previous issue with modeChanged being in English has been resolved.

Also applies to: 37-37

src/shared/types/presenters/legacy.presenters.d.ts (2)

874-878: LGTM! Consistent API extension for ACP session modes.

The new setAcpSessionMode and getAcpSessionModes methods follow the established patterns in this interface, with appropriate Promise-based return types and nullable responses.


1003-1007: LGTM! Consistent with ILlmProviderPresenter additions.

The IThreadPresenter interface correctly mirrors the ACP session mode methods from ILlmProviderPresenter, maintaining API consistency between the presenter layers.

src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts (3)

5-17: LGTM! Well-structured interface additions.

The PlanEntry interface and MappedContent extensions are clearly documented with optional fields. The nullable types (string | null) for priority and status align with the ACP schema's optional nature.


185-206: Consider potential issue with empty reasoning event for plan blocks.

The createStreamEvent.reasoning('') at line 200 emits an empty reasoning event before the plan block. This seems intentional for signaling, but verify that downstream consumers (in the renderer) handle empty reasoning content gracefully without displaying empty UI elements.


208-226: LGTM! Mode update handling is correctly implemented.

The handleModeUpdate method properly stores the mode ID in the payload and emits both a reasoning event and a structured block with the mode_change extra data, enabling proper UI rendering of mode transitions.

src/main/presenter/llmProviderPresenter/agent/acpSessionManager.ts (3)

24-31: LGTM! AcpSessionRecord properly extended with mode metadata.

The new optional fields follow TypeScript conventions for optional interface properties and align with the ACP protocol's mode support.


159-160: Good placement of workdir registration.

Registering the session workdir with the process manager before persisting session data ensures fs/terminal operations are available immediately when the session becomes active.


219-231: LGTM! Safe extraction of mode data from ACP response.

The optional chaining (modes?.availableModes?.map) correctly handles cases where the ACP agent doesn't support modes. The fallback to empty string for missing descriptions is a sensible default.

src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts (4)

146-156: LGTM! Comprehensive cleanup on shutdown.

The shutdown sequence properly releases terminal manager resources, clears all per-session state maps, and handles the existing cleanup. The ordering ensures no resource leaks.


200-207: LGTM! Per-session resource cleanup is thorough.

The clearSession method properly removes workdir mappings, FS handlers, and releases session terminals. The fire-and-forget pattern with void for terminal release is appropriate since it's non-blocking cleanup.


229-232: LGTM! Proper capability negotiation with ACP agent.

Using buildClientCapabilities with explicit enableFs and enableTerminal flags clearly communicates the client's capabilities to the agent, enabling proper fs/terminal operation routing.


569-594: LGTM! Client proxy methods properly delegate to handlers.

The fs and terminal operations are correctly routed to their respective handlers. Error handling is inherited from AcpFsHandler and AcpTerminalManager, which throw RequestError for protocol-compliant error responses.

Comment on lines 66 to 71
default:
console.debug('[ACP] Unhandled session update', update.sessionUpdate)
// Handle any unrecognized session update types
const sessionUpdate = (update as { sessionUpdate?: string }).sessionUpdate
console.warn('[ACP] Unhandled session update type:', sessionUpdate)
console.debug('[ACP] Full update data:', JSON.stringify(update))
break
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Wrap switch case declaration in a block to fix correctness issue.

The const sessionUpdate declaration in the default case is accessible to other switch clauses, which can lead to subtle bugs. As flagged by static analysis, wrap the declaration in a block to restrict its scope.

       default:
+        {
-        // Handle any unrecognized session update types
-        const sessionUpdate = (update as { sessionUpdate?: string }).sessionUpdate
-        console.warn('[ACP] Unhandled session update type:', sessionUpdate)
-        console.debug('[ACP] Full update data:', JSON.stringify(update))
+          // Handle any unrecognized session update types
+          const sessionUpdate = (update as { sessionUpdate?: string }).sessionUpdate
+          console.warn('[ACP] Unhandled session update type:', sessionUpdate)
+          console.debug('[ACP] Full update data:', JSON.stringify(update))
+        }
         break
🧰 Tools
🪛 Biome (2.1.2)

[error] 68-68: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

🤖 Prompt for AI Agents
In src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts around
lines 66 to 71, the default switch case declares const sessionUpdate at function
scope which can leak into other cases; fix by wrapping the default case body in
its own block (add { ... } around the const and the console calls) so
sessionUpdate is block-scoped and cannot collide with other case declarations.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts (1)

67-72: Wrap switch case declaration in a block to fix correctness issue.

The const sessionUpdate declaration in the default case is accessible to other switch clauses, which can lead to subtle bugs. As flagged by static analysis, wrap the declaration in a block to restrict its scope.

       default:
+        {
-        // Handle any unrecognized session update types
-        const sessionUpdate = (update as { sessionUpdate?: string }).sessionUpdate
-        console.warn('[ACP] Unhandled session update type:', sessionUpdate)
-        console.debug('[ACP] Full update data:', JSON.stringify(update))
+          // Handle any unrecognized session update types
+          const sessionUpdate = (update as { sessionUpdate?: string }).sessionUpdate
+          console.warn('[ACP] Unhandled session update type:', sessionUpdate)
+          console.debug('[ACP] Full update data:', JSON.stringify(update))
+        }
         break
🧹 Nitpick comments (4)
src/renderer/src/components/chat-input/ChatInput.vue (1)

196-223: Well-structured ACP mode switcher with proper i18n and accessibility.

The implementation follows existing patterns in the file (e.g., Model Selector) and correctly uses i18n for all user-facing strings. Minor suggestion: consider adding a guard for the description content to avoid rendering an empty paragraph.

-                <p v-if="acpMode.currentModeInfo.value" class="text-xs text-muted-foreground mt-1">
+                <p v-if="acpMode.currentModeInfo.value?.description" class="text-xs text-muted-foreground mt-1">
                   {{ acpMode.currentModeInfo.value.description }}
                 </p>
src/renderer/src/components/message/MessageBlockToolCall.vue (1)

194-226: Consider terminal resize handling for responsive layouts.

The terminal is initialized with fixed dimensions derived from container size at mount time. If the container resizes (e.g., window resize), the terminal won't adapt. Consider using a FitAddon from @xterm/addon-fit for proper responsive behavior.

src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts (1)

191-212: Consider removing the empty reasoning event emission.

Line 206 emits createStreamEvent.reasoning('') with empty content, which may clutter the event stream without providing value. If this is a placeholder for plan events, consider using a dedicated event type or removing it entirely.

     // Create dedicated plan block
-    payload.events.push(createStreamEvent.reasoning('')) // Empty event for plan
     payload.blocks.push(
       this.createBlock('plan', '', {
         extra: { plan_entries: payload.planEntries }
       })
     )
src/renderer/src/components/artifacts/MermaidArtifact.vue (1)

133-142: Translate comment to English.

The watch logic is correct. Minor issue: the comment on line 133 is in Chinese; per coding guidelines, new code should use English comments.

-// 监听内容变化和预览状态变化
+// Watch for content and preview state changes to trigger re-render
 watch(
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c824f9 and b14f0dd.

📒 Files selected for processing (7)
  • package.json (1 hunks)
  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts (6 hunks)
  • src/renderer/src/components/artifacts/MermaidArtifact.vue (3 hunks)
  • src/renderer/src/components/chat-input/ChatInput.vue (3 hunks)
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts (1 hunks)
  • src/renderer/src/components/message/MessageBlockToolCall.vue (3 hunks)
  • src/renderer/src/i18n/ko-KR/toolCall.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • package.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/renderer/src/i18n/ko-KR/toolCall.json
  • src/renderer/src/components/chat-input/composables/useAcpMode.ts
🧰 Additional context used
📓 Path-based instructions (25)
**/*.{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/llmProviderPresenter/agent/acpContentMapper.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.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/llmProviderPresenter/agent/acpContentMapper.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/llmProviderPresenter/agent/acpContentMapper.ts
src/main/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use EventBus from src/main/eventbus.ts for main-to-renderer communication, broadcasting events via mainWindow.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 in src/main/ with presenters in presenter/ (Window/Tab/Thread/Mcp/Config/LLMProvider) and eventbus.ts for app events
Use the Presenter pattern in the main process for UI coordination

Files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/llmProviderPresenter/agent/acpContentMapper.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/llmProviderPresenter/agent/acpContentMapper.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/llmProviderPresenter/agent/acpContentMapper.ts
src/main/presenter/llmProviderPresenter/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/llm-agent-loop.mdc)

Define the standardized LLMCoreStreamEvent interface with fields: type (text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data), content (for text), reasoning_content (for reasoning), tool_call_id, tool_call_name, tool_call_arguments_chunk (for streaming), tool_call_arguments_complete (for complete arguments), error_message, usage object with token counts, stop_reason (tool_use | max_tokens | stop_sequence | error | complete), and image_data object with Base64-encoded data and mimeType

Files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
src/**/*

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

New features should be developed in the src directory

Files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.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/llmProviderPresenter/agent/acpContentMapper.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/llmProviderPresenter/agent/acpContentMapper.ts
  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use OxLint for linting JavaScript and TypeScript files

Files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/llmProviderPresenter/agent/acpContentMapper.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use EventBus for inter-process communication events

Files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.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/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
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/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
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/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.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/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
src/renderer/src/**/*.vue

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

Use scoped styles to prevent CSS conflicts between Vue components

Files:

  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
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 statements

Vue 3 app code in src/renderer/src should be organized into components/, stores/, views/, i18n/, lib/ directories with shell UI in src/renderer/shell/

Files:

  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.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/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
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/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.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 in src/renderer/src/i18n

Files:

  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
src/renderer/src/components/**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

src/renderer/src/components/**/*.vue: Use Tailwind for styles in Vue components
Vue component files must use PascalCase naming (e.g., ChatInput.vue)

Files:

  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
🧠 Learnings (28)
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, listen for standardized events yielded by `coreStream` and handle them accordingly: buffer text content (`currentContent`), handle `tool_call_start/chunk/end` events by collecting tool details and calling `presenter.mcpPresenter.callTool`, send frontend events via `eventBus` with tool call status, format tool results for the next LLM call, and set `needContinueConversation = true`

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/**/*.ts : Define the standardized `LLMCoreStreamEvent` interface with fields: `type` (text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data), `content` (for text), `reasoning_content` (for reasoning), `tool_call_id`, `tool_call_name`, `tool_call_arguments_chunk` (for streaming), `tool_call_arguments_complete` (for complete arguments), `error_message`, `usage` object with token counts, `stop_reason` (tool_use | max_tokens | stop_sequence | error | complete), and `image_data` object with Base64-encoded data and mimeType

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/main/presenter/llmProviderPresenter/providers/*.ts : Convert MCP tools to provider-specific formats and normalize streaming responses to standard events in each provider implementation

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts` (`startStreamCompletion`), implement the Agent loop that manages the overall conversation flow, including multiple rounds of LLM calls and tool usage, maintaining `conversationMessages` history, calling `provider.coreStream()` on each iteration, and controlling the loop using `needContinueConversation` and `toolCallCount` (compared against `MAX_TOOL_CALLS`)

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, include helper methods for Provider-specific operations such as `formatMessages`, `convertToProviderTools`, `parseFunctionCalls`, and `prepareFunctionCallPrompt`

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, parse Provider-specific data chunks from the streaming response and `yield` standardized `LLMCoreStreamEvent` objects conforming to the standard stream event interface, including text, reasoning, tool calls, usage, errors, stop reasons, and image data

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : In Provider implementations, handle native tool support by converting MCP tools to Provider format using `convertToProviderTools` and including them in the API request; for Providers without native function call support, prepare messages using `prepareFunctionCallPrompt` before making the API call

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : In `src/main/presenter/llmProviderPresenter/index.ts`, handle `reasoning`, `text`, `image_data`, and `usage` events by processing and forwarding them through `STREAM_EVENTS.RESPONSE` events to the frontend

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:39.200Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/provider-guidelines.mdc:0-0
Timestamp: 2025-11-25T05:27:39.200Z
Learning: Applies to **/*Provider**/index.ts : Output only discriminated union `LLMCoreStreamEvent` in Provider implementations, do not use single interface with optional fields

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.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/main/presenter/llmProviderPresenter/providers/*.ts : Each LLM provider must implement the `coreStream` method following the standardized event interface for tool calling and response streaming

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 Learning: 2025-11-25T05:27:39.200Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/provider-guidelines.mdc:0-0
Timestamp: 2025-11-25T05:27:39.200Z
Learning: Applies to **/*Provider**/index.ts : Tool call events: strictly follow sequence `tool_call_start → tool_call_chunk* → tool_call_end`, ensure `tool_call_id` is required and stable

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts
📚 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/components/**/*.vue : Vue component files must use PascalCase naming (e.g., `ChatInput.vue`)

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:27:45.545Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:45.545Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Use the Composition API for better code organization and reusability in Vue.js applications

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Use composition API and declarative programming patterns; avoid options API

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.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} : Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,vue} : Use Iconify/Vue for icon implementation

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use VueUse for common composables and utility functions

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use camelCase for composables (e.g., useAuthState.ts)

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Implement custom composables for reusable logic

Applied to files:

  • src/renderer/src/components/chat-input/ChatInput.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Import Icon component from 'iconify/vue' and use with lucide icons following pattern '{collection}:{icon-name}'

Applied to files:

  • src/renderer/src/components/message/MessageBlockToolCall.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} : Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files

Applied to files:

  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 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/components/message/MessageBlockToolCall.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Prefer 'lucide:' icon family as the primary choice for Iconify icons

Applied to files:

  • src/renderer/src/components/message/MessageBlockToolCall.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Use template syntax for declarative rendering

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,vue} : Leverage ref, reactive, and computed for reactive state management

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Use <script setup> syntax for concise component definitions

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:27:45.545Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:45.545Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Leverage Vue's built-in reactivity system for efficient data handling

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
🧬 Code graph analysis (1)
src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts (2)
src/shared/types/core/llm-events.ts (1)
  • createStreamEvent (100-154)
src/shared/chat.d.ts (1)
  • AssistantMessageBlock (84-147)
🪛 Biome (2.1.2)
src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts

[error] 69-69: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

⏰ 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). (1)
  • GitHub Check: build-check (x64)
🔇 Additional comments (12)
src/renderer/src/components/chat-input/ChatInput.vue (2)

398-398: LGTM!

The import follows the established pattern for composable imports in this file.


615-618: LGTM!

The initialization follows the same pattern as useAcpWorkdir and correctly uses the shared activeModelSource and conversationId computed refs, ensuring consistent reactive behavior across ACP features.

src/renderer/src/components/message/MessageBlockToolCall.vue (4)

29-40: LGTM - Terminal output UI section.

The terminal output section properly integrates with the template, using correct i18n translation via t('toolCall.terminalOutput') and lucide icons per guidelines.


75-78: LGTM - Appropriate imports for terminal functionality.

Imports for Vue lifecycle hooks and xterm.js are correctly added.


161-173: Improved parseJson with safer fallback handling.

The function now properly handles non-object primitives by wrapping them in { raw: ... }, providing consistent output for the JsonObject component.


175-192: LGTM - Terminal detection and params computation.

The isTerminalTool computed property uses a reasonable heuristic for terminal-related tools. The hasParams logic correctly handles arrays, objects, and strings.

src/main/presenter/llmProviderPresenter/agent/acpContentMapper.ts (4)

5-18: LGTM - Well-structured interfaces for plan and mode support.

The PlanEntry interface and extended MappedContent provide clean typing for the new ACP plan/mode features.


176-184: LGTM - Improved tool call parameter handling.

The logic correctly prioritizes stringifyToolParams output and uses paramsCaptured to prevent duplicate emissions. The fallback to contentChunk when params haven't been captured maintains backward compatibility.


214-232: LGTM - Clean mode update handling.

The method properly stores the mode ID and emits a reasoning block with mode change metadata for UI visibility.


389-418: LGTM - Robust parameter extraction with proper fallbacks.

The method handles multiple input sources (rawInput, raw_input, locations, title) with appropriate error handling via try-catch blocks. The use of (update as any) is acceptable given the schema's dynamic nature.

src/renderer/src/components/artifacts/MermaidArtifact.vue (2)

3-7: Clean approach replacing iframe with direct DOM rendering.

The switch from iframe-based rendering to a direct div container with proper Tailwind styling for SVG elements is a good improvement for maintainability and performance.


102-131: Good error handling and safe DOM manipulation.

The rendering flow properly sanitizes content before setting it, uses safe textContent instead of innerHTML, and correctly leverages i18n for error messages. The error display is created safely using DOM APIs.

Comment on lines 36 to 85
/**
* 过滤 Mermaid 内容中的危险 HTML 标签和属性,防止 XSS 攻击
* 参考 svgSanitizer.ts 和 deeplinkPresenter 的实现
*/
const sanitizeMermaidContent = (content: string): string => {
if (!content || typeof content !== 'string') {
return ''
}
let sanitized = content
// 移除危险的 HTML 标签及其内容
const dangerousTags = [
// Script 标签 - 允许执行 JavaScript
/<script[^>]*>[\s\S]*?<\/script>/gi,
// Iframe 标签 - 可以嵌入恶意内容
/<iframe[^>]*>[\s\S]*?<\/iframe>/gi,
// Object 和 Embed 标签 - 可以执行代码
/<object[^>]*>[\s\S]*?<\/object>/gi,
/<embed[^>]*[^>]*>/gi,
// Form 标签 - 可能用于 CSRF
/<form[^>]*>[\s\S]*?<\/form>/gi,
// Link 标签 - 可能加载恶意样式或脚本
/<link[^>]*>/gi,
// Style 标签 - 可能包含恶意 CSS
/<style[^>]*>[\s\S]*?<\/style>/gi,
// Meta 标签 - 可能用于重定向或执行
/<meta[^>]*>/gi,
// Img 标签 - PoC 中使用的攻击向量,带事件处理器特别危险
/<img[^>]*>/gi
]
// 移除危险标签
for (const pattern of dangerousTags) {
sanitized = sanitized.replace(pattern, '')
}
// 移除所有事件处理器属性 (on* 属性)
// 这包括 onerror, onclick, onload, onmouseover 等
sanitized = sanitized.replace(/on\w+\s*=\s*["'][^"']*["']/gi, '')
// 移除危险的协议
const dangerousProtocols = [/javascript\s*:/gi, /vbscript\s*:/gi, /data\s*:\s*text\/html/gi]
for (const pattern of dangerousProtocols) {
sanitized = sanitized.replace(pattern, '')
}
return sanitized
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Use English for comments in new code; improve event handler regex.

Per coding guidelines, new code should use English for comments instead of Chinese.

Additionally, the event handler regex on line 75 only catches quoted attribute values. Unquoted values like onerror=alert(1) (valid HTML5) would bypass this check.

-/**
- * 过滤 Mermaid 内容中的危险 HTML 标签和属性,防止 XSS 攻击
- * 参考 svgSanitizer.ts 和 deeplinkPresenter 的实现
- */
+/**
+ * Sanitize Mermaid content by removing dangerous HTML tags and attributes to prevent XSS attacks.
+ * References svgSanitizer.ts and deeplinkPresenter implementation.
+ */
 const sanitizeMermaidContent = (content: string): string => {
   // ... existing code ...

-  // 移除危险的 HTML 标签及其内容
+  // Remove dangerous HTML tags and their content
   const dangerousTags = [
-    // Script 标签 - 允许执行 JavaScript
+    // Script tags - allow JavaScript execution
     /<script[^>]*>[\s\S]*?<\/script>/gi,
-    // Iframe 标签 - 可以嵌入恶意内容
+    // Iframe tags - can embed malicious content
     // ... similarly translate other comments ...
   ]

-  // 移除危险标签
+  // Remove dangerous tags
   for (const pattern of dangerousTags) {
     sanitized = sanitized.replace(pattern, '')
   }

-  // 移除所有事件处理器属性 (on* 属性)
-  // 这包括 onerror, onclick, onload, onmouseover 等
-  sanitized = sanitized.replace(/on\w+\s*=\s*["'][^"']*["']/gi, '')
+  // Remove all event handler attributes (on* attributes)
+  // This includes onerror, onclick, onload, onmouseover, etc.
+  // Handle both quoted and unquoted attribute values
+  sanitized = sanitized.replace(/\bon\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, '')

-  // 移除危险的协议
+  // Remove dangerous protocols
   const dangerousProtocols = [/javascript\s*:/gi, /vbscript\s*:/gi, /data\s*:\s*text\/html/gi]
   // ...
 }

Based on learnings, use English for all new comments as per coding guidelines.

📝 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.

Suggested change
/**
* 过滤 Mermaid 内容中的危险 HTML 标签和属性,防止 XSS 攻击
* 参考 svgSanitizer.ts 和 deeplinkPresenter 的实现
*/
const sanitizeMermaidContent = (content: string): string => {
if (!content || typeof content !== 'string') {
return ''
}
let sanitized = content
// 移除危险的 HTML 标签及其内容
const dangerousTags = [
// Script 标签 - 允许执行 JavaScript
/<script[^>]*>[\s\S]*?<\/script>/gi,
// Iframe 标签 - 可以嵌入恶意内容
/<iframe[^>]*>[\s\S]*?<\/iframe>/gi,
// Object 和 Embed 标签 - 可以执行代码
/<object[^>]*>[\s\S]*?<\/object>/gi,
/<embed[^>]*[^>]*>/gi,
// Form 标签 - 可能用于 CSRF
/<form[^>]*>[\s\S]*?<\/form>/gi,
// Link 标签 - 可能加载恶意样式或脚本
/<link[^>]*>/gi,
// Style 标签 - 可能包含恶意 CSS
/<style[^>]*>[\s\S]*?<\/style>/gi,
// Meta 标签 - 可能用于重定向或执行
/<meta[^>]*>/gi,
// Img 标签 - PoC 中使用的攻击向量,带事件处理器特别危险
/<img[^>]*>/gi
]
// 移除危险标签
for (const pattern of dangerousTags) {
sanitized = sanitized.replace(pattern, '')
}
// 移除所有事件处理器属性 (on* 属性)
// 这包括 onerror, onclick, onload, onmouseover 等
sanitized = sanitized.replace(/on\w+\s*=\s*["'][^"']*["']/gi, '')
// 移除危险的协议
const dangerousProtocols = [/javascript\s*:/gi, /vbscript\s*:/gi, /data\s*:\s*text\/html/gi]
for (const pattern of dangerousProtocols) {
sanitized = sanitized.replace(pattern, '')
}
return sanitized
}
/**
* Sanitize Mermaid content by removing dangerous HTML tags and attributes to prevent XSS attacks.
* References svgSanitizer.ts and deeplinkPresenter implementation.
*/
const sanitizeMermaidContent = (content: string): string => {
if (!content || typeof content !== 'string') {
return ''
}
let sanitized = content
// Remove dangerous HTML tags and their content
const dangerousTags = [
// Script tags - allow JavaScript execution
/<script[^>]*>[\s\S]*?<\/script>/gi,
// Iframe tags - can embed malicious content
/<iframe[^>]*>[\s\S]*?<\/iframe>/gi,
// Object and Embed tags - can execute code
/<object[^>]*>[\s\S]*?<\/object>/gi,
/<embed[^>]*[^>]*>/gi,
// Form tags - can be used for CSRF
/<form[^>]*>[\s\S]*?<\/form>/gi,
// Link tags - can load malicious styles or scripts
/<link[^>]*>/gi,
// Style tags - may contain malicious CSS
/<style[^>]*>[\s\S]*?<\/style>/gi,
// Meta tags - can be used for redirects or execution
/<meta[^>]*>/gi,
// Img tags - attack vectors used in PoC, especially dangerous with event handlers
/<img[^>]*>/gi
]
// Remove dangerous tags
for (const pattern of dangerousTags) {
sanitized = sanitized.replace(pattern, '')
}
// Remove all event handler attributes (on* attributes)
// This includes onerror, onclick, onload, onmouseover, etc.
// Handle both quoted and unquoted attribute values
sanitized = sanitized.replace(/\bon\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, '')
// Remove dangerous protocols
const dangerousProtocols = [/javascript\s*:/gi, /vbscript\s*:/gi, /data\s*:\s*text\/html/gi]
for (const pattern of dangerousProtocols) {
sanitized = sanitized.replace(pattern, '')
}
return sanitized
}

Comment on lines 87 to 100
// 初始化 mermaid,使用更合适的配置
onMounted(() => {
mermaid.initialize({
startOnLoad: false,
theme: isDarkTheme.value ? 'dark' : 'default',
startOnLoad: true,
theme: document.documentElement.classList.contains('dark') ? 'dark' : 'default',
securityLevel: 'strict',
fontFamily: 'system-ui, -apple-system, sans-serif'
fontFamily: 'inherit'
})
if (props.isPreview && props.block.content) {
renderDiagram()
// 初始渲染
if (props.isPreview) {
nextTick(() => renderDiagram())
}
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

mermaid.js startOnLoad true vs manual mermaid.run() conflict

💡 Result:

Short answer

  • startOnLoad: true makes Mermaid auto-run on DOMContentLoaded; calling mermaid.run()/mermaid.render() yourself while startOnLoad is true can produce duplicate/race behaviour in some versions. Disable the automatic run and initialize manually to avoid conflicts. [1][2][3]

Why

  • startOnLoad triggers Mermaid to scan and render on page load. mermaid.run() also scans and renders (it marks processed elements with data-processed to avoid reprocessing). In practice this is safe if you only call run after load — but there have been race/duplicate-render bugs and differences between the public mermaid.render wrapper and mermaidAPI.render that caused "already registered" / duplicate-ID / parallel-render errors in some releases. [1][2][3]

Recommendation (concise)

  • Use explicit initialization and manual runs:
    1. mermaid.initialize({ startOnLoad: false, ...config });
    2. call mermaid.run({ querySelector: '.mermaid' }) (or mermaid.render for single diagrams) when you need to render (e.g., after dynamic content is inserted).
  • This avoids auto-run vs manual-run collisions and gives you control over timing (especially important for single-page apps, dynamic content, hidden containers, or parallel renders). [1][2][3]

If you need an example or have a specific Mermaid version/usage (CDN, ESM, SPA framework), tell me the version and environment and I’ll give a minimal snippet.

Sources

  • Mermaid usage / initialize & startOnLoad docs. [1]
  • mermaid.run / API docs (describes marking processed elements). [2]
  • GitHub discussion about render concurrency / differences between render wrappers (duplicate registration / race issues). [3]

🏁 Script executed:

cat -n src/renderer/src/components/artifacts/MermaidArtifact.vue

Repository: ThinkInAIXYZ/deepchat

Length of output: 4875


Fix Chinese comments and change startOnLoad to false to avoid conflicts with manual rendering.

The startOnLoad: true setting conflicts with the manual mermaid.run() calls in renderDiagram(), potentially causing race conditions or duplicate renders. Additionally, replace all Chinese comments with English and make theme detection reactive to support dark mode toggling.

-// 初始化 mermaid,使用更合适的配置
+// Initialize mermaid with appropriate configuration
 onMounted(() => {
   mermaid.initialize({
-    startOnLoad: true,
+    startOnLoad: false,
     theme: document.documentElement.classList.contains('dark') ? 'dark' : 'default',
     securityLevel: 'strict',
     fontFamily: 'inherit'
   })

-  // 初始渲染
+  // Initial render
   if (props.isPreview) {
     nextTick(() => renderDiagram())
   }
 })

To support reactive theme changes, add a watcher that re-initializes mermaid and re-renders when the document's dark mode class changes.

🤖 Prompt for AI Agents
In src/renderer/src/components/artifacts/MermaidArtifact.vue around lines
87–100, replace the Chinese comments with English, set mermaid.initialize's
startOnLoad to false to avoid conflicts with manual rendering, and make theme
detection reactive: detect dark-mode changes (e.g., via a MutationObserver on
document.documentElement.classList or a reactive prefers-color-scheme listener),
and when the theme changes re-initialize mermaid with the new theme and call the
existing renderDiagram() to re-render diagrams; ensure the
MutationObserver/listener is cleaned up on unmounted.

Comment on lines +228 to +246
// Watch for expanded state and initialize terminal
watch(
[isExpanded, () => props.block.tool_call?.response],
() => {
if (isExpanded.value && isTerminalTool.value) {
nextTick(() => {
initTerminal()
})
}
},
{ immediate: true }
)
onBeforeUnmount(() => {
if (terminal) {
terminal.dispose()
terminal = null
}
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Terminal memory leak: dispose existing terminal before re-initialization.

When the response changes while the panel is expanded, initTerminal() creates a new Terminal instance without disposing the previous one. This leaks DOM nodes and event listeners.

 // Watch for expanded state and initialize terminal
 watch(
   [isExpanded, () => props.block.tool_call?.response],
   () => {
     if (isExpanded.value && isTerminalTool.value) {
       nextTick(() => {
+        // Dispose existing terminal before creating new one
+        if (terminal) {
+          terminal.dispose()
+          terminal = null
+        }
         initTerminal()
       })
+    } else if (terminal) {
+      // Clean up when collapsed
+      terminal.dispose()
+      terminal = null
     }
   },
   { immediate: true }
 )
📝 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.

Suggested change
// Watch for expanded state and initialize terminal
watch(
[isExpanded, () => props.block.tool_call?.response],
() => {
if (isExpanded.value && isTerminalTool.value) {
nextTick(() => {
initTerminal()
})
}
},
{ immediate: true }
)
onBeforeUnmount(() => {
if (terminal) {
terminal.dispose()
terminal = null
}
})
// Watch for expanded state and initialize terminal
watch(
[isExpanded, () => props.block.tool_call?.response],
() => {
if (isExpanded.value && isTerminalTool.value) {
nextTick(() => {
// Dispose existing terminal before creating new one
if (terminal) {
terminal.dispose()
terminal = null
}
initTerminal()
})
} else if (terminal) {
// Clean up when collapsed
terminal.dispose()
terminal = null
}
},
{ immediate: true }
)
onBeforeUnmount(() => {
if (terminal) {
terminal.dispose()
terminal = null
}
})
🤖 Prompt for AI Agents
In src/renderer/src/components/message/MessageBlockToolCall.vue around lines 228
to 246, the watcher calls initTerminal() when the response changes while
expanded but does not dispose the existing terminal, causing DOM/event-listener
leaks; before creating a new Terminal (either inside initTerminal() or right
before calling it in the watcher) check if a previous terminal exists and call
terminal.dispose(), remove any associated DOM nodes/listeners and set terminal =
null, then proceed to create and initialize the new Terminal instance so the old
instance is fully cleaned up.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/presenter/configPresenter/acpInitHelper.ts (1)

599-625: PATH key inconsistency could cause runtime failures.

After normalization sets env[normalizedPath.key] at line 581, subsequent code uses hardcoded or platform-derived PATH keys:

  1. Line 611: Hardcodes pathKey = 'Path' for Windows system install handling
  2. Line 637: Derives pathKey from platform check
  3. This creates multiple PATH-like variables if normalizedPath.key differs from the hardcoded/derived key

Impact: Builtin runtime paths (UV, Node) may not be in the PATH actually used by the shell, causing agent initialization to fail when tools aren't found.

Apply this refactor to use normalizedPath.key consistently:

+  // Store normalized PATH key for consistent usage
+  const normalizedPathKey = normalizedPath.key
+
   // Add registry environment variables if using builtin runtime
   if (useBuiltinRuntime) {
     // ... registry config ...
     
     // On Windows, if app is installed in system directory, set npm prefix to user directory
     // to avoid permission issues when installing global packages
     if (process.platform === 'win32' && this.runtimeHelper.isInstalledInSystemDirectory()) {
       const userNpmPrefix = this.runtimeHelper.getUserNpmPrefix()
 
       if (userNpmPrefix) {
         env.npm_config_prefix = userNpmPrefix
         env.NPM_CONFIG_PREFIX = userNpmPrefix
         console.log(
           '[ACP Init] Set NPM prefix to user directory (system install detected):',
           userNpmPrefix
         )
 
         // Add user npm bin directory to PATH
-        const pathKey = 'Path'
         const separator = ';'
-        const existingPath = env[pathKey] || ''
+        const existingPath = env[normalizedPathKey] || ''
         const userNpmBinPath = userNpmPrefix
 
         // Ensure the user npm bin path is at the beginning of PATH
         if (existingPath) {
-          env[pathKey] = [userNpmBinPath, existingPath].filter(Boolean).join(separator)
+          env[normalizedPathKey] = [userNpmBinPath, existingPath].filter(Boolean).join(separator)
         } else {
-          env[pathKey] = userNpmBinPath
+          env[normalizedPathKey] = userNpmBinPath
         }
 
         console.log('[ACP Init] Added user npm bin directory to PATH:', userNpmBinPath)
       }
     }
   }
 
   // Add custom environment variables from profile
   if (profile.env) {
     const customEnvCount = Object.entries(profile.env).filter(
       ([, value]) => value !== undefined && value !== ''
     ).length
     Object.entries(profile.env).forEach(([key, value]) => {
       if (value !== undefined && value !== '') {
         if (['PATH', 'Path', 'path'].includes(key)) {
           // Merge PATH variables
-          const pathKey = process.platform === 'win32' ? 'Path' : 'PATH'
           const separator = process.platform === 'win32' ? ';' : ':'
-          const existingPath = env[pathKey] || env[normalizedPath.key] || ''
-          env[pathKey] = [value, existingPath].filter(Boolean).join(separator)
+          const existingPath = env[normalizedPathKey] || ''
+          env[normalizedPathKey] = [value, existingPath].filter(Boolean).join(separator)
           console.log('[ACP Init] Merged custom PATH from profile:', {
             customPath: value,
-            mergedPathLength: env[pathKey].length
+            mergedPathLength: env[normalizedPathKey].length
           })
         } else {
           env[key] = value

Also applies to: 635-644

🧹 Nitpick comments (1)
src/renderer/settings/components/AcpProfileManagerDialog.vue (1)

116-129: Env masking helper works but consider tightening masking + empty-value handling

The new maskValue helper improves things by not dumping full env values into the UI, and the integration into formatEnv looks correct. Two small, non-blocking points to consider:

  1. Amount of secret revealed
    Exposing the first 10 characters of every value might still be more than you want for API keys/tokens. You could:

    • Either fully mask ('***') or
    • Only show a very short, fixed prefix (e.g. 3–4 chars) if you still need some visual differentiation.
  2. Empty/undefined values semantics
    if (!val) return '' means explicit empty-string envs render as KEY= with nothing else. If you want to make “intentionally empty” clearer, you might render a placeholder like <empty> or *** instead.

Example tweak (keeping the behavior very close but a bit stricter on masking and clearer on empties):

-  const maskValue = (val: string | undefined | null) => {
-    if (!val) return ''
-    const str = String(val)
-    return str.length <= 10 ? str : `${str.slice(0, 10)}***`
-  }
+  const maskValue = (val: string | undefined | null) => {
+    if (val === '' || val === null || val === undefined) return '<empty>'
+    const str = String(val)
+    // Only show a short prefix for privacy; always indicate masking
+    const prefix = str.slice(0, 4)
+    return `${prefix}***`
+  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b14f0dd and 0f10a04.

📒 Files selected for processing (2)
  • src/main/presenter/configPresenter/acpInitHelper.ts (7 hunks)
  • src/renderer/settings/components/AcpProfileManagerDialog.vue (1 hunks)
🧰 Additional context used
📓 Path-based instructions (20)
**/*.{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/acpInitHelper.ts
  • src/renderer/settings/components/AcpProfileManagerDialog.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/acpInitHelper.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/acpInitHelper.ts
src/main/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use EventBus from src/main/eventbus.ts for main-to-renderer communication, broadcasting events via mainWindow.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 in src/main/ with presenters in presenter/ (Window/Tab/Thread/Mcp/Config/LLMProvider) and eventbus.ts for app events
Use the Presenter pattern in the main process for UI coordination

Files:

  • src/main/presenter/configPresenter/acpInitHelper.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/acpInitHelper.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/acpInitHelper.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/acpInitHelper.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/acpInitHelper.ts
src/**/*

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

New features should be developed in the src directory

Files:

  • src/main/presenter/configPresenter/acpInitHelper.ts
  • src/renderer/settings/components/AcpProfileManagerDialog.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/acpInitHelper.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/acpInitHelper.ts
  • src/renderer/settings/components/AcpProfileManagerDialog.vue
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use OxLint for linting JavaScript and TypeScript files

Files:

  • src/main/presenter/configPresenter/acpInitHelper.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/acpInitHelper.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use EventBus for inter-process communication events

Files:

  • src/main/presenter/configPresenter/acpInitHelper.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/AcpProfileManagerDialog.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/AcpProfileManagerDialog.vue
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/settings/components/AcpProfileManagerDialog.vue
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 statements

Vue 3 app code in src/renderer/src should be organized into components/, stores/, views/, i18n/, lib/ directories with shell UI in src/renderer/shell/

Files:

  • src/renderer/settings/components/AcpProfileManagerDialog.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/settings/components/AcpProfileManagerDialog.vue
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/settings/components/AcpProfileManagerDialog.vue
🧠 Learnings (1)
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms

Applied to files:

  • src/main/presenter/configPresenter/acpInitHelper.ts
🧬 Code graph analysis (1)
src/main/presenter/configPresenter/acpInitHelper.ts (1)
src/main/presenter/llmProviderPresenter/agent/shellEnvHelper.ts (1)
  • getShellEnvironment (160-240)
⏰ 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). (1)
  • GitHub Check: build-check (x64)
🔇 Additional comments (5)
src/main/presenter/configPresenter/acpInitHelper.ts (5)

10-10: LGTM: Import for shell environment integration.

The import of getShellEnvironment is appropriate for the new shell environment merging functionality and aligns with the async changes to buildEnvironmentVariables.


242-247: LGTM: Async/await usage is correct.

Both call sites properly await buildEnvironmentVariables, which is now async. The containing methods are already async, so the usage is correct.

Also applies to: 274-279


493-498: LGTM: Async method signature.

The method signature correctly changed to async with Promise<Record<string, string>> return type, which is necessary for the shell environment fetching.


519-541: LGTM: Shell environment merging logic.

The shell environment integration is well-implemented:

  • Collects existing PATH-like keys to preserve them
  • Merges non-PATH variables from shell environment
  • Prepends shell PATH for proper precedence
  • Includes appropriate error handling with warning

542-581: LGTM: PATH preparation and normalization.

The PATH assembly and normalization logic is sound:

  • Combines existing paths, shell paths, and default paths
  • Prepends builtin runtime paths when configured
  • Uses runtimeHelper.normalizePathEnv() for platform-appropriate key handling

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/renderer/src/components/artifacts/MermaidArtifact.vue (1)

36-85: Address previously flagged issues: translate comments to English and fix regex pattern.

The Chinese comments and the event handler regex issue (line 75 only catches quoted attribute values, missing unquoted onerror=alert(1)) were flagged in a previous review. Please apply the suggested fixes from that review.

src/renderer/src/components/message/MessageBlockToolCall.vue (1)

194-205: Dispose terminal on collapse as well to fully avoid lingering instances

initTerminal now correctly disposes any existing instance before re-creating, and onBeforeUnmount cleans up on component teardown. However, when the panel is collapsed, the watcher stops calling initTerminal, so the terminal instance remains alive (though only one per component) until unmount or the next expand.

To eagerly free resources on collapse, you can extend the watcher to dispose when isExpanded becomes false:

 watch(
   [isExpanded, () => props.block.tool_call?.response],
   () => {
-    if (isExpanded.value && isTerminalTool.value) {
-      nextTick(() => {
-        initTerminal()
-      })
-    }
+    if (isExpanded.value && isTerminalTool.value) {
+      nextTick(() => {
+        initTerminal()
+      })
+    } else if (terminal) {
+      try {
+        terminal.dispose()
+      } catch (error) {
+        console.warn('[MessageBlockToolCall] Failed to dispose terminal on collapse:', error)
+      }
+      terminal = null
+    }
   },
   { immediate: true }
 )

Also applies to: 240-251

🧹 Nitpick comments (6)
src/renderer/src/components/artifacts/MermaidArtifact.vue (1)

164-173: Translate comment to English and await the async call.

Line 164 has a Chinese comment that should be in English per coding guidelines. Additionally, renderDiagram() returns a Promise but is not awaited, which could lead to unhandled promise rejections in edge cases.

-// 监听内容变化和预览状态变化
+// Watch for content and preview state changes
 watch(
   [() => props.block.content, () => props.isPreview],
   async ([newContent, newIsPreview], [oldContent, oldIsPreview]) => {
     if (newIsPreview && (newContent !== oldContent || newIsPreview !== oldIsPreview)) {
       await nextTick()
-      renderDiagram()
+      await renderDiagram()
     }
   }
 )

Based on learnings, use English for all new comments as per coding guidelines.

src/renderer/src/components/message/MessageBlockToolCall.vue (1)

55-56: Use English for new/updated comments to align with project guidelines

Lines like the response/terminal comment and the parseJson comment are (partially) in Chinese, while the current guidelines say new comments should be in English.

This is minor but easy to fix by rephrasing:

-          <!-- 响应 (hide for terminal tools as output is shown above) -->
+          <!-- Response (hidden for terminal tools as output is shown above) -->
@@
-// 解析JSON为对象;解析失败时回退原文
+// Parse JSON into an object; fall back to raw text on parse failure

Based on learnings, new comments in *.ts/*.vue files should be written in English.

Also applies to: 161-161

src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts (4)

81-89: Per-session FS handler and restricted fallback workspace look good; consider per-session fallback dirs

The new registerSessionWorkdir, getFsHandler, and getFallbackWorkdir flow correctly constrains ACP file access to a configured workspace, and the fallback now uses an app-scoped temp directory instead of an unrestricted root, which addresses the earlier security concern about workspaceRoot: null.

Two small improvements you might consider:

  • Make the fallback workspace per-session (e.g., append sessionId under deepchat-acp/sessions) so sessions don’t share a single temp directory and to avoid cross-session collisions.
  • Given the JSDoc comment mentions “before any fs/terminal operations,” it might be worth either wiring the same sessionWorkdirs into terminal cwd defaults (see below) or relaxing the comment to “fs operations” so it reflects current behavior.

Overall, the security posture of FS access is much better than the previous unrestricted fallback.

Also applies to: 91-107, 109-122


164-174: Ensure agent-level cleanup also releases FS handlers, workdirs, and terminals

shutdown() and clearSession() correctly clear sessionWorkdirs, fsHandlers, and per-session terminals, but clearSessionsForAgent() (used from release() and the child exit handler) only removes listeners and permission resolvers. Any sessions associated with that agent will still have:

  • Entries in sessionWorkdirs and fsHandlers
  • Potentially active terminals tracked by AcpTerminalManager

This can lead to resource leaks if an agent process is killed or exits unexpectedly.

A simple way to align cleanup paths is to delegate through clearSession for all affected sessionIds, e.g.:

  private clearSessionsForAgent(agentId: string): void {
-    for (const [sessionId, entry] of this.sessionListeners.entries()) {
-      if (entry.agentId === agentId) {
-        this.sessionListeners.delete(sessionId)
-      }
-    }
-
-    for (const [sessionId, entry] of this.permissionResolvers.entries()) {
-      if (entry.agentId === agentId) {
-        this.permissionResolvers.delete(sessionId)
-      }
-    }
+    const sessionIds = new Set<string>()
+
+    for (const [sessionId, entry] of this.sessionListeners.entries()) {
+      if (entry.agentId === agentId) {
+        sessionIds.add(sessionId)
+      }
+    }
+
+    for (const [sessionId, entry] of this.permissionResolvers.entries()) {
+      if (entry.agentId === agentId) {
+        sessionIds.add(sessionId)
+      }
+    }
+
+    for (const sessionId of sessionIds) {
+      this.clearSession(sessionId)
+    }
  }

This keeps all session-scoped cleanup logic in one place and avoids leaking terminals or FS state when an agent goes away.

Also applies to: 218-225, 651-663


247-250: Init capabilities & logging are solid; consider typing initResult instead of casting

Wiring buildClientCapabilities({ enableFs: true, enableTerminal: true }) into connection.initialize and then logging session/models/modes from the init result gives good observability and matches the new FS/terminal features.

The only minor concern is the const resultData = initResult as unknown as { ... } cast; it bypasses type checking. If the SDK exposes a concrete type for the initialize response, using that here (or at least a narrower alias) would help catch drift if the protocol changes, while preserving the same runtime behavior.

If such a type is not available, what you have is acceptable, especially since all accesses are optional and guarded.

Also applies to: 264-292


582-612: Client proxy FS/terminal wiring works; consider defaulting terminal cwd to session workdir

The new client proxy methods for readTextFile/writeTextFile and terminal operations are wired correctly:

  • FS calls go through getFsHandler(params.sessionId)AcpFsHandler, so they benefit from the workspace sandboxing you’ve added.
  • Terminal calls are delegated to AcpTerminalManager as expected.

One improvement to align terminal behavior with your session workdir model:

  • Right now, createTerminal forwards params as-is, and AcpTerminalManager defaults cwd to process.cwd() when params.cwd is absent.
  • Since you’re already tracking sessionWorkdirs, you could default terminal cwd to the registered workdir (or the fallback workspace) when the caller does not explicitly specify a cwd, keeping shell commands scoped similarly to file operations.

For example:

      // Terminal operations
      createTerminal: async (params) => {
-        return this.terminalManager.createTerminal(params)
+        const finalParams = { ...params }
+        if (!finalParams.cwd && finalParams.sessionId) {
+          const workdir = this.sessionWorkdirs.get(finalParams.sessionId)
+          if (workdir) {
+            finalParams.cwd = workdir
+          }
+        }
+        return this.terminalManager.createTerminal(finalParams)
      },

This would make terminal execution semantics more predictable and better sandboxed per session without breaking callers that explicitly set cwd.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f10a04 and 86ef7f8.

📒 Files selected for processing (4)
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts (8 hunks)
  • src/renderer/src/components/artifacts/MermaidArtifact.vue (3 hunks)
  • src/renderer/src/components/message/MessageBlockToolCall.vue (3 hunks)
  • src/renderer/src/i18n/fa-IR/chat.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/renderer/src/i18n/fa-IR/chat.json
🧰 Additional context used
📓 Path-based instructions (25)
**/*.{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/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.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/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.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/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
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/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
src/**/*

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

New features should be developed in the src directory

Files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.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/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.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/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
src/renderer/src/**/*.vue

📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)

Use scoped styles to prevent CSS conflicts between Vue components

Files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
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 statements

Vue 3 app code in src/renderer/src should be organized into components/, stores/, views/, i18n/, lib/ directories with shell UI in src/renderer/shell/

Files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.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/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
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/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.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 in src/renderer/src/i18n

Files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
src/renderer/src/components/**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

src/renderer/src/components/**/*.vue: Use Tailwind for styles in Vue components
Vue component files must use PascalCase naming (e.g., ChatInput.vue)

Files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
src/**/*.{ts,tsx,vue,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with single quotes, no semicolons, and 100 character width

Files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
**/*.{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/llmProviderPresenter/agent/acpProcessManager.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/llmProviderPresenter/agent/acpProcessManager.ts
src/main/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use EventBus from src/main/eventbus.ts for main-to-renderer communication, broadcasting events via mainWindow.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 in src/main/ with presenters in presenter/ (Window/Tab/Thread/Mcp/Config/LLMProvider) and eventbus.ts for app events
Use the Presenter pattern in the main process for UI coordination

Files:

  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.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/llmProviderPresenter/agent/acpProcessManager.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/llmProviderPresenter/agent/acpProcessManager.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/llmProviderPresenter/agent/acpProcessManager.ts
src/main/presenter/llmProviderPresenter/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/llm-agent-loop.mdc)

Define the standardized LLMCoreStreamEvent interface with fields: type (text | reasoning | tool_call_start | tool_call_chunk | tool_call_end | error | usage | stop | image_data), content (for text), reasoning_content (for reasoning), tool_call_id, tool_call_name, tool_call_arguments_chunk (for streaming), tool_call_arguments_complete (for complete arguments), error_message, usage object with token counts, stop_reason (tool_use | max_tokens | stop_sequence | error | complete), and image_data object with Base64-encoded data and mimeType

Files:

  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
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/llmProviderPresenter/agent/acpProcessManager.ts
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use OxLint for linting JavaScript and TypeScript files

Files:

  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.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/llmProviderPresenter/agent/acpProcessManager.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use EventBus for inter-process communication events

Files:

  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
🧠 Learnings (18)
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Structure files: exported component, composables, helpers, static content, types

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,vue} : Use Iconify/Vue for icon implementation

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Use template syntax for declarative rendering

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:27:45.545Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:45.545Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Use the Composition API for better code organization and reusability in Vue.js applications

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 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/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:26:15.929Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/development-setup.mdc:0-0
Timestamp: 2025-11-25T05:26:15.929Z
Learning: Applies to **/*.{js,ts,jsx,tsx,mjs,cjs} : Write logs and comments in English

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.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} : Import and use useI18n() composable with the t() function to access translations in Vue components and TypeScript files

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.{ts,vue} : Leverage ref, reactive, and computed for reactive state management

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Use <script setup> syntax for concise component definitions

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:27:45.545Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:27:45.545Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Leverage Vue's built-in reactivity system for efficient data handling

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/composables/*.ts : Use VueUse for common composables and utility functions

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.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} : Avoid hardcoding user-facing text and ensure all user-visible text uses the i18n translation system

Applied to files:

  • src/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Import Icon component from 'iconify/vue' and use with lucide icons following pattern '{collection}:{icon-name}'

Applied to files:

  • src/renderer/src/components/message/MessageBlockToolCall.vue
📚 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/components/message/MessageBlockToolCall.vue
📚 Learning: 2025-11-25T05:28:04.454Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-11-25T05:28:04.454Z
Learning: Applies to src/renderer/**/*.vue : Prefer 'lucide:' icon family as the primary choice for Iconify icons

Applied to files:

  • src/renderer/src/components/message/MessageBlockToolCall.vue
📚 Learning: 2025-11-25T05:27:12.209Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-11-25T05:27:12.209Z
Learning: Implement separation of concerns where `src/main/presenter/llmProviderPresenter/index.ts` manages the Agent loop and conversation history, while Provider files handle LLM API interactions, Provider-specific request/response formatting, tool definition conversion, and native vs non-native tool call mechanisms

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.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/main/presenter/mcpPresenter/**/*.ts : Register new MCP tools in `mcpPresenter/index.ts` after implementing them in `inMemoryServers/`

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
📚 Learning: 2025-11-25T05:26:24.867Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/electron-best-practices.mdc:0-0
Timestamp: 2025-11-25T05:26:24.867Z
Learning: Applies to {src/main/presenter/**/*.ts,src/renderer/**/*.ts} : Implement proper inter-process communication (IPC) patterns using Electron's ipcRenderer and ipcMain APIs

Applied to files:

  • src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts
🧬 Code graph analysis (1)
src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts (3)
src/main/presenter/llmProviderPresenter/agent/acpTerminalManager.ts (1)
  • AcpTerminalManager (33-244)
src/main/presenter/llmProviderPresenter/agent/acpFsHandler.ts (1)
  • AcpFsHandler (21-115)
src/main/presenter/llmProviderPresenter/agent/acpCapabilities.ts (1)
  • buildClientCapabilities (14-31)
🔇 Additional comments (7)
src/renderer/src/components/artifacts/MermaidArtifact.vue (6)

1-14: LGTM!

Template uses declarative rendering with proper conditional display for preview vs code modes. Tailwind CSS classes are well-structured for layout and overflow handling.


16-32: LGTM!

Proper use of Vue 3 Composition API with <script setup>, TypeScript props definition, and i18n integration via useI18n() composable.


87-120: LGTM!

Theme reactivity implementation is well done with MutationObserver watching for dark-mode class changes. The startOnLoad: false configuration correctly avoids conflicts with manual mermaid.run() calls. Proper cleanup is handled in onBeforeUnmount.


122-131: LGTM!

Proper initialization sequence with mermaid setup, theme watcher registration, and conditional initial render using nextTick for DOM readiness.


133-162: LGTM!

Secure rendering pipeline with proper sanitization, defensive null checks, and safe error handling using textContent (preventing XSS). User-facing error messages correctly use i18n via t() function.


175-180: LGTM!

Proper cleanup of the MutationObserver in onBeforeUnmount prevents memory leaks.

src/renderer/src/components/message/MessageBlockToolCall.vue (1)

29-40: Terminal tool output block wiring looks solid

The dedicated terminal section, conditional response visibility for terminal tools, and use of t('toolCall.terminalOutput') with lucide icons and Tailwind classes are all consistent with renderer/i18n/Iconify guidelines.

Based on learnings, the i18n and Iconify usage here matches the expected patterns.

Also applies to: 53-56

@zerob13 zerob13 merged commit a53e67d into dev Dec 3, 2025
2 checks passed
@zerob13 zerob13 deleted the feat/full-acp-support branch December 13, 2025 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants