Skip to content

Conversation

@zerob13
Copy link
Collaborator

@zerob13 zerob13 commented Jan 6, 2026

Summary by CodeRabbit

  • New Features

    • Toggleable function-calling flow for assistant/tool interactions.
    • File-system tools can operate within an optional per-conversation base directory.
  • Changes

    • Chat tabs now create new instances instead of reusing existing chats.
    • Tab move/activation behavior adjusted to avoid duplicate activation when relocating tabs.
    • Tooltip visibility simplified for better cross-platform consistency.
  • Bug Fixes

    • Prevented URL/title updates for local/internal tabs.
  • Tests

    • Added tests covering function-calling flows and tab behaviors.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 6, 2026

📝 Walkthrough

Walkthrough

Adds a function-calling toggle in post-tool message construction, changes message sequencing for function-call vs fallback flows, tightens tab/window activation and local-tab handling, adjusts chat tab deduplication, and introduces per-conversation/baseDirectory workdir handling while changing several agent filesystem/command tool behaviors.

Changes

Cohort / File(s) Summary
Message building & tests
src/main/presenter/agentPresenter/message/messageBuilder.ts, test/main/presenter/agentPresenter/messageBuilder.test.ts
Adds supportsFunctionCall flag to choose between native function-calling (assistant message with tool_calls + separate tool message, stable tool_call_id via nanoid) and legacy serialized function_call_record fallback; tests cover enabled/disabled flows and empty upstream id.
Agent Bash handler (workdir removal)
src/main/presenter/agentPresenter/acp/agentBashHandler.ts
Removes workdir support and path-validation helpers; always uses first allowed directory as cwd; eliminates fs/promises usage and related validation logic; schema no longer accepts workdir.
Agent FileSystem handler (baseDirectory additions)
src/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts
Adds optional baseDirectory?: string parameter to public methods and path validation, resolves relative paths against baseDirectory (or default allowed dir), strengthens symlink/parent checks, and adjusts read/list and error formats.
Agent Tool Manager (dynamic workdir)
src/main/presenter/agentPresenter/acp/agentToolManager.ts
Removes tool-level workdir option; adds private getWorkdirForConversation and passes resolved per-conversation baseDirectory into filesystem tool calls.
Tab presenter: local tab guard & move behavior
src/main/presenter/tabPresenter.ts
Skips URL/title updates and TITLE_UPDATED emission for local:// tabs; when moving tabs to new windows, stop auto-activating moved tab in new window.
Window presenter: moved-tab activation & overlay cleanup
src/main/presenter/windowPresenter/index.ts
Condition activateTabId on forMovedTab to avoid double activation; remove macOS Mission Control visibility calls for tooltip overlay.
Tab store: deduplication change
src/renderer/shell/stores/tab.ts
Introduces shouldDeduplicate guard so chat viewType skips deduplication (allows new chat tabs instead of reusing existing ones).

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Ctx as PostToolExecutionContext
    participant Builder as MessageBuilder
    participant Tool as ToolExecutor
    participant Messages as MessageQueue

    User->>Ctx: tool execution completes (result + metadata)
    Ctx->>Builder: buildPostToolExecutionContext(ctx)
    Builder->>Builder: check supportsFunctionCall flag

    alt supportsFunctionCall == true
        rect rgb(200,220,255)
            Note over Builder,Messages: Native function-calling flow
            Builder->>Builder: ensure/generate tool_call_id (nanoid if missing)
            Builder->>Messages: push assistant msg with tool_calls (name + args)
            Builder->>Messages: push tool msg with tool response (tool_call_id)
            Builder->>Tool: (tool response already present) finalize sequence
        end
    else supportsFunctionCall == false
        rect rgb(255,230,200)
            Note over Builder,Messages: Legacy serialized fallback
            Builder->>Builder: serialize function_call_record into assistant content
            Builder->>Messages: push assistant msg (embedded serialized record)
            Builder->>Messages: push user prompt msg to continue flow
        end
    end

    Builder->>Ctx: return updated message sequence
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 Hopping through messages, I find my way,

tool_call IDs dancing, nanoid at play,
Chat tabs blossom, dedup left behind,
Local tabs rest—no title to bind,
A rabbit celebrates the build today! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title is vague and generic, using non-specific terms like 'window and toolcall bug' that don't convey meaningful information about the substantial changes across multiple files and systems. Consider a more descriptive title that captures the primary change, such as 'refactor: add function-calling support and improve tool management' or 'feat: implement per-conversation working directories and function-calling flows'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings

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: 0

🧹 Nitpick comments (1)
test/main/presenter/agentPresenter/messageBuilder.test.ts (1)

1-86: LGTM! Comprehensive test coverage for the new function-calling flows.

The test suite effectively covers:

  • OpenAI-compatible flow with explicit tool call ID
  • Stable ID generation when upstream ID is missing
  • Fallback path for models without function-calling support

The mock strategy and dynamic imports correctly isolate the unit under test from Electron dependencies.

Consider extracting the dynamic import to a beforeEach block to reduce repetition:

🔎 Optional refactor for DRYer test setup
 describe('messageBuilder.buildPostToolExecutionContext', () => {
+  let buildPostToolExecutionContext: typeof import('@/presenter/agentPresenter/message/messageBuilder')['buildPostToolExecutionContext']
+
+  beforeEach(async () => {
+    const module = await import('@/presenter/agentPresenter/message/messageBuilder')
+    buildPostToolExecutionContext = module.buildPostToolExecutionContext
+  })
+
   it('emits assistant(tool_calls) -> tool(tool_call_id) pairing when functionCall is enabled', async () => {
-    const { buildPostToolExecutionContext } =
-      await import('@/presenter/agentPresenter/message/messageBuilder')
-
     const messages = await buildPostToolExecutionContext({
       // ...
     })
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8cc327f and 4440113.

📒 Files selected for processing (5)
  • src/main/presenter/agentPresenter/message/messageBuilder.ts
  • src/main/presenter/tabPresenter.ts
  • src/main/presenter/windowPresenter/index.ts
  • src/renderer/shell/stores/tab.ts
  • test/main/presenter/agentPresenter/messageBuilder.test.ts
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use English for logs and comments in TypeScript/JavaScript code

Files:

  • src/renderer/shell/stores/tab.ts
  • test/main/presenter/agentPresenter/messageBuilder.test.ts
  • src/main/presenter/windowPresenter/index.ts
  • src/main/presenter/agentPresenter/message/messageBuilder.ts
  • src/main/presenter/tabPresenter.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript with strict type checking enabled

Use OxLint for linting JavaScript and TypeScript files; ensure lint-staged hooks and typecheck pass before commits

Files:

  • src/renderer/shell/stores/tab.ts
  • test/main/presenter/agentPresenter/messageBuilder.test.ts
  • src/main/presenter/windowPresenter/index.ts
  • src/main/presenter/agentPresenter/message/messageBuilder.ts
  • src/main/presenter/tabPresenter.ts
**/*.{js,ts,tsx,jsx,vue,mjs,cjs}

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

All logs and comments must be in English

Files:

  • src/renderer/shell/stores/tab.ts
  • test/main/presenter/agentPresenter/messageBuilder.test.ts
  • src/main/presenter/windowPresenter/index.ts
  • src/main/presenter/agentPresenter/message/messageBuilder.ts
  • src/main/presenter/tabPresenter.ts
**/*.{js,ts,tsx,jsx,mjs,cjs}

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

Use OxLint as the linter

Files:

  • src/renderer/shell/stores/tab.ts
  • test/main/presenter/agentPresenter/messageBuilder.test.ts
  • src/main/presenter/windowPresenter/index.ts
  • src/main/presenter/agentPresenter/message/messageBuilder.ts
  • src/main/presenter/tabPresenter.ts
**/*.{js,ts,tsx,jsx,vue,json,mjs,cjs}

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

Use Prettier as the code formatter

Files:

  • src/renderer/shell/stores/tab.ts
  • test/main/presenter/agentPresenter/messageBuilder.test.ts
  • src/main/presenter/windowPresenter/index.ts
  • src/main/presenter/agentPresenter/message/messageBuilder.ts
  • src/main/presenter/tabPresenter.ts
src/renderer/shell/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Shell UI code should be located in src/renderer/shell/

Files:

  • src/renderer/shell/stores/tab.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use camelCase for variable and function names; use PascalCase for types and classes; use SCREAMING_SNAKE_CASE for constants
Configure Prettier with single quotes, no semicolons, and line width of 100 characters. Run pnpm run format after completing features

Files:

  • src/renderer/shell/stores/tab.ts
  • test/main/presenter/agentPresenter/messageBuilder.test.ts
  • src/main/presenter/windowPresenter/index.ts
  • src/main/presenter/agentPresenter/message/messageBuilder.ts
  • src/main/presenter/tabPresenter.ts
test/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files in test/ directory with corresponding structure to source files

Files:

  • test/main/presenter/agentPresenter/messageBuilder.test.ts
test/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Vitest as the testing framework for unit and integration tests

Files:

  • test/main/presenter/agentPresenter/messageBuilder.test.ts
test/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

Vitest test suites should be organized in test/main/** and test/renderer/** mirroring source structure, with file names following *.test.ts or *.spec.ts pattern

Files:

  • test/main/presenter/agentPresenter/messageBuilder.test.ts
src/main/presenter/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/main/presenter/**/*.ts: Use EventBus to broadcast events from main to renderer via mainWindow.webContents.send()
Implement one presenter per functional domain in the main process

Files:

  • src/main/presenter/windowPresenter/index.ts
  • src/main/presenter/agentPresenter/message/messageBuilder.ts
  • src/main/presenter/tabPresenter.ts
src/main/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/main/**/*.ts: Use EventBus from src/main/eventbus.ts for decoupled inter-process communication
Context isolation must be enabled with preload scripts for secure IPC communication

Electron main process code should reside in src/main/, with presenters organized in presenter/ subdirectory (Window, Tab, Thread, Mcp, Config, LLMProvider), and app events managed via eventbus.ts

Files:

  • src/main/presenter/windowPresenter/index.ts
  • src/main/presenter/agentPresenter/message/messageBuilder.ts
  • src/main/presenter/tabPresenter.ts
🧠 Learnings (3)
📚 Learning: 2025-06-21T15:48:29.950Z
Learnt from: neoragex2002
Repo: ThinkInAIXYZ/deepchat PR: 550
File: src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts:250-252
Timestamp: 2025-06-21T15:48:29.950Z
Learning: In the meeting server implementation (src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts), when multiple tabs have the same title, the user prefers to let the code silently select the first match without adding warnings or additional ambiguity handling.

Applied to files:

  • src/renderer/shell/stores/tab.ts
  • src/main/presenter/windowPresenter/index.ts
  • src/main/presenter/tabPresenter.ts
📚 Learning: 2025-08-28T05:55:31.482Z
Learnt from: zerob13
Repo: ThinkInAIXYZ/deepchat PR: 804
File: src/main/presenter/llmProviderPresenter/providers/tokenfluxProvider.ts:153-156
Timestamp: 2025-08-28T05:55:31.482Z
Learning: TokenFlux models generally support function calling by default, so it's reasonable to assume hasFunctionCalling = true for TokenFlux provider implementations in src/main/presenter/llmProviderPresenter/providers/tokenfluxProvider.ts

Applied to files:

  • src/main/presenter/agentPresenter/message/messageBuilder.ts
📚 Learning: 2026-01-05T02:40:52.831Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-05T02:40:52.831Z
Learning: Applies to src/main/presenter/configPresenter/**/*.ts : Custom prompts are managed independently of MCP through config data source using `configPresenter.getCustomPrompts()`

Applied to files:

  • src/main/presenter/agentPresenter/message/messageBuilder.ts
🧬 Code graph analysis (2)
test/main/presenter/agentPresenter/messageBuilder.test.ts (1)
src/main/presenter/agentPresenter/message/messageBuilder.ts (1)
  • buildPostToolExecutionContext (238-326)
src/main/presenter/tabPresenter.ts (3)
test/mocks/electron.ts (1)
  • BrowserWindow (36-51)
src/main/events.ts (1)
  • TAB_EVENTS (180-188)
src/renderer/src/events.ts (1)
  • TAB_EVENTS (145-152)
⏰ 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 (6)
src/renderer/shell/stores/tab.ts (1)

14-21: LGTM! Clear deduplication logic for tab types.

The guard correctly allows multiple chat and playground tabs while deduplicating other local view types (e.g., settings). This makes sense for user experience—users may want multiple chat sessions open simultaneously.

src/main/presenter/agentPresenter/message/messageBuilder.ts (3)

13-13: LGTM! Appropriate use of nanoid for stable ID generation.

Using nanoid with a fixed length (8) is a good choice for generating unique tool call IDs when the upstream doesn't provide one.


275-298: LGTM! OpenAI-compatible function-calling flow is well-structured.

The assistant → tool message pairing with matching tool_call_id correctly follows the OpenAI function-calling protocol. The fallback ID generation with nanoid(8) ensures robustness when providers don't return an ID.


317-322: Verify: Chinese prompt in fallback flow may need internationalization.

The user prompt '以上是你刚执行的工具调用及其响应信息...' is in Chinese. Per coding guidelines, comments should be in English. However, this is a user-facing LLM prompt, not a log or code comment.

Please verify:

  1. Is this intentional for specific Chinese LLM providers (e.g., DeepSeek)?
  2. Should this prompt be internationalized based on user locale or model configuration?
src/main/presenter/windowPresenter/index.ts (1)

1031-1057: LGTM! Correctly prevents duplicate tab activation for moved tabs.

The condition !options?.forMovedTab properly defers activation to the attachTab flow when a tab is dragged to a new window. This prevents the race condition where both createShellWindow and attachTab would attempt to activate the same tab.

The inline comment clearly documents the reasoning behind this change.

src/main/presenter/tabPresenter.ts (1)

696-717: LGTM! Correctly preserves local:// tab state during navigation.

The guard prevents did-navigate events from overwriting local:// URLs with internal renderer URLs (e.g., hash-based routes). This is the correct fix because:

  1. Local tabs use local:// as a logical URL scheme, not a real navigable URL
  2. Internal navigation within the renderer shouldn't modify the tab's identity
  3. Title updates for local tabs are still handled by the page-title-updated event handler, which updates state.title unconditionally for all tabs including local ones

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

🧹 Nitpick comments (1)
src/main/presenter/agentPresenter/acp/agentToolManager.ts (1)

536-548: Redundant try-catch block.

The getWorkdirForConversation method already has internal error handling that returns null on failure. The outer try-catch is redundant.

🔎 Proposed simplification
    let dynamicWorkdir: string | null = null
    if (conversationId) {
-     try {
-       dynamicWorkdir = await this.getWorkdirForConversation(conversationId)
-     } catch (error) {
-       logger.warn('[AgentToolManager] Failed to get workdir for conversation:', {
-         conversationId,
-         error
-       })
-     }
+     dynamicWorkdir = await this.getWorkdirForConversation(conversationId)
    }

    const baseDirectory = dynamicWorkdir ?? undefined
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4440113 and f1d75d3.

📒 Files selected for processing (3)
  • src/main/presenter/agentPresenter/acp/agentBashHandler.ts
  • src/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts
  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use English for logs and comments in TypeScript/JavaScript code

Files:

  • src/main/presenter/agentPresenter/acp/agentBashHandler.ts
  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
  • src/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript with strict type checking enabled

Use OxLint for linting JavaScript and TypeScript files; ensure lint-staged hooks and typecheck pass before commits

Files:

  • src/main/presenter/agentPresenter/acp/agentBashHandler.ts
  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
  • src/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts
src/main/presenter/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/main/presenter/**/*.ts: Use EventBus to broadcast events from main to renderer via mainWindow.webContents.send()
Implement one presenter per functional domain in the main process

Files:

  • src/main/presenter/agentPresenter/acp/agentBashHandler.ts
  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
  • src/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts
src/main/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/main/**/*.ts: Use EventBus from src/main/eventbus.ts for decoupled inter-process communication
Context isolation must be enabled with preload scripts for secure IPC communication

Electron main process code should reside in src/main/, with presenters organized in presenter/ subdirectory (Window, Tab, Thread, Mcp, Config, LLMProvider), and app events managed via eventbus.ts

Files:

  • src/main/presenter/agentPresenter/acp/agentBashHandler.ts
  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
  • src/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts
**/*.{js,ts,tsx,jsx,vue,mjs,cjs}

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

All logs and comments must be in English

Files:

  • src/main/presenter/agentPresenter/acp/agentBashHandler.ts
  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
  • src/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts
**/*.{js,ts,tsx,jsx,mjs,cjs}

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

Use OxLint as the linter

Files:

  • src/main/presenter/agentPresenter/acp/agentBashHandler.ts
  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
  • src/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts
**/*.{js,ts,tsx,jsx,vue,json,mjs,cjs}

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

Use Prettier as the code formatter

Files:

  • src/main/presenter/agentPresenter/acp/agentBashHandler.ts
  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
  • src/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use camelCase for variable and function names; use PascalCase for types and classes; use SCREAMING_SNAKE_CASE for constants
Configure Prettier with single quotes, no semicolons, and line width of 100 characters. Run pnpm run format after completing features

Files:

  • src/main/presenter/agentPresenter/acp/agentBashHandler.ts
  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
  • src/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts
🧠 Learnings (5)
📚 Learning: 2026-01-05T02:41:45.204Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-05T02:41:45.204Z
Learning: Applies to src/main/**/*.ts : Electron main process code should reside in `src/main/`, with presenters organized in `presenter/` subdirectory (Window, Tab, Thread, Mcp, Config, LLMProvider), and app events managed via `eventbus.ts`

Applied to files:

  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
📚 Learning: 2026-01-05T02:40:52.831Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-05T02:40:52.831Z
Learning: Applies to src/renderer/src/**/*.{ts,tsx,vue} : Use `usePresenter.ts` composable for renderer-to-main IPC communication via direct presenter method calls

Applied to files:

  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
📚 Learning: 2026-01-05T02:41:31.619Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: .cursor/rules/vue-stack-guide.mdc:0-0
Timestamp: 2026-01-05T02:41:31.619Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx} : Use `usePresenter` composable for main process communication instead of direct IPC calls

Applied to files:

  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
📚 Learning: 2026-01-05T02:40:52.831Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-05T02:40:52.831Z
Learning: Applies to src/main/presenter/**/*.ts : Implement one presenter per functional domain in the main process

Applied to files:

  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
📚 Learning: 2026-01-05T02:40:52.831Z
Learnt from: CR
Repo: ThinkInAIXYZ/deepchat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-05T02:40:52.831Z
Learning: Applies to src/main/presenter/**/*.ts : Use EventBus to broadcast events from main to renderer via `mainWindow.webContents.send()`

Applied to files:

  • src/main/presenter/agentPresenter/acp/agentToolManager.ts
🧬 Code graph analysis (1)
src/main/presenter/agentPresenter/acp/agentToolManager.ts (2)
test/mocks/electron.ts (1)
  • session (34-34)
src/main/presenter/index.ts (1)
  • presenter (297-297)
⏰ 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/main/presenter/agentPresenter/acp/agentFileSystemHandler.ts (6)

167-201: LGTM - baseDirectory integration in path validation.

The validatePath method correctly resolves relative paths against the provided baseDirectory, falling back to the first allowed directory when not specified. The existing security checks (allowed directory validation, symlink resolution, parent directory verification) remain intact.


634-652: LGTM - Consistent baseDirectory propagation.

The readFile, writeFile, listDirectory, and createDirectory methods correctly propagate the optional baseDirectory to validatePath, maintaining a consistent pattern throughout.

Also applies to: 654-662, 664-678, 680-688


690-711: LGTM - moveFiles correctly applies baseDirectory to both source and destination.

Both source paths and the constructed destination path are resolved against the same baseDirectory, ensuring consistent path scoping.


816-846: LGTM - Recursive tree building with proper path validation.

The buildTree inner function correctly captures baseDirectory from the closure and validates each path in the recursive traversal.


861-873: LGTM - globSearch root resolution handles all cases.

The search root is correctly resolved:

  1. If root is provided, it's validated with baseDirectory
  2. Otherwise, baseDirectory is used (or falls back to allowedDirectories[0])

The subsequent validatePath calls at line 901 work correctly since glob results are absolute paths (absolute: true in options).


713-749: LGTM - Remaining methods follow consistent pattern.

The editText, grepSearch, textReplace, and getFileInfo methods all correctly accept and propagate baseDirectory to path validation.

Also applies to: 751-793, 795-814, 848-859

src/main/presenter/agentPresenter/acp/agentToolManager.ts (3)

254-281: LGTM - Per-conversation workdir resolution.

The getWorkdirForConversation method correctly retrieves the working directory based on the conversation's chat mode:

  • For acp agent: looks up workdir from acpWorkdirMap using the model ID
  • For agent: returns agentWorkspacePath

Error handling with null fallback is appropriate.


576-582: Verify: execute_command does not respect per-conversation workdir.

While all file system tools receive the dynamic baseDirectory, the execute_command tool uses the bash handler's fixed cwd (set to allowedDirectories[0] at initialization). This means shell commands may execute in a different directory than where file operations are scoped.

If this is intentional (e.g., for security reasons), please add a code comment explaining the rationale. Otherwise, consider passing the workdir to the bash handler for consistency.


550-575: LGTM - Consistent baseDirectory propagation to file system tools.

All file system tool invocations correctly pass the baseDirectory derived from the conversation's workdir configuration.

src/main/presenter/agentPresenter/acp/agentBashHandler.ts (3)

21-25: LGTM - Simplified command execution schema.

The schema correctly defines the required fields for command execution without the previously removed workdir field.


52-52: LGTM - Fixed cwd from allowed directories.

Using allowedDirectories[0] as the working directory is safe since allowed directories are validated and normalized at construction time. This simplification removes per-command workdir logic.

Also applies to: 75-75


46-166: LGTM - Robust command execution with proper safeguards.

The implementation includes:

  • Permission checking before execution
  • Timeout handling with graceful kill followed by SIGKILL
  • Output truncation at 30KB
  • Terminal snippet emission for UI updates
  • Proper process registration/unregistration for lifecycle management

@zerob13 zerob13 merged commit f99e4f6 into dev Jan 6, 2026
2 checks passed
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