Skip to content

fix(acp): align client runtime#1614

Merged
zerob13 merged 2 commits into
devfrom
fix/acp-agent-compress-check
May 12, 2026
Merged

fix(acp): align client runtime#1614
zerob13 merged 2 commits into
devfrom
fix/acp-agent-compress-check

Conversation

@zerob13
Copy link
Copy Markdown
Collaborator

@zerob13 zerob13 commented May 12, 2026

Summary by CodeRabbit

  • New Features

    • New ACP runtime/prompt turn lifecycle with persisted turn start/finish and debug event logging
    • ACP context-budget bypass for oversized ACP prompts
  • Bug Fixes

    • Stronger workspace path/realpath guards and terminal cwd scoping
    • Avoids warmup throwaway sessions and prevents re-initializing ready connections
    • Ensures prompt turn persistence is awaited before sending prompts
  • Documentation

    • Added ACP runtime/spec/plan and context-bypass design docs
  • Tests

    • Added focused ACP unit/regression tests and coverage for cwd, fs, debug, and prompt flows

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

📝 Walkthrough

Walkthrough

This PR adds an internal AcpClientPresenter runtime boundary, implements an ACP-specific context-budget bypass in AgentRuntimePresenter, persists ACP prompt turns to a new SQLite table, hardens workspace path and terminal cwd handling, instruments ACP process/session debug events, rewires AcpProvider to use the presenter, updates renderer/i18n, and adds tests and docs.

Changes

ACP Client Runtime Refactor & Context Budget Bypass

Layer / File(s) Summary
Architecture & implementation docs
docs/architecture/acp-client-runtime/*, docs/issues/acp-context-budget-bypass/*, docs/issues/acp-pr-1614-review-fixes/*
Adds planning/spec/tasks documents describing the ACP client runtime boundary, context-budget bypass behavior, and PR review-fix checklist.
Types, shared contracts and presenter types
src/main/presenter/acpClientPresenter/types.ts, src/shared/contracts/acp.ts, src/shared/types/presenters/legacy.presenters.d.ts, src/main/presenter/acpClientPresenter/registry/index.ts
Defines ACP presenter types, DeepChatAgentEvent contract, expands AcpDebugEventKind, and adds ACP turn payload typings and registry re-export.
AcpClientPresenter, prompt controller, mapper, handlers
src/main/presenter/acpClientPresenter/index.ts, src/main/presenter/acpClientPresenter/session/AcpPromptController.ts, src/main/presenter/acpClientPresenter/mapper/AcpEventMapper.ts, src/main/presenter/acpClientPresenter/handlers/index.ts
Introduces AcpClientPresenter facade, AcpPromptController for per-session turns, AcpEventMapper for session notifications, and handler re-exports.
Connection manager and debug log
src/main/presenter/acpClientPresenter/connection/AcpConnectionManager.ts, src/main/presenter/acpClientPresenter/connection/AcpDebugLog.ts
Adds AcpConnectionManager and AcpDebugLog for lifecycle management and per-agent debug event storage.
Session runtime and ACP turn persistence
src/main/presenter/acpClientPresenter/session/AcpSessionRuntime.ts, src/main/presenter/sqlitePresenter/tables/acpTurns.ts, src/main/presenter/sqlitePresenter/index.ts, src/main/presenter/sqlitePresenter/schemaCatalog.ts, src/main/presenter/llmProviderPresenter/acp/acpSessionPersistence.ts
Adds AcpSessionRuntime, AcpTurnsTable schema and APIs, registers table in schema catalog, and exposes start/finish turn persistence methods.
Filesystem path guards and AcpFsHandler integration
src/main/presenter/acpClientPresenter/workspace/AcpPathGuard.ts, src/main/presenter/llmProviderPresenter/acp/acpFsHandler.ts
Introduces AcpPathGuard enforcing realpath and parent discovery checks and integrates it into AcpFsHandler read/write validation.
AcpProcessManager instrumentation & terminal cwd hardening
src/main/presenter/llmProviderPresenter/acp/acpProcessManager.ts
Persists agentCapabilities/authMethods from init, adds debug event APIs and instrumentation, hardens terminal cwd resolution to enforce session workdir boundaries, and removes warmup probing.
AcpSessionManager lifecycle & MCP resolution
src/main/presenter/llmProviderPresenter/acp/acpSessionManager.ts
Refactors initializeSession/createSession to accept hooks and detachHandlers, attaches hooks early for persisted sessions, and adds resolveMcpServersForAgent for MCP selection/filtering.
AcpProvider wiring & prompt turn lifecycle
src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
Rewires AcpProvider to use AcpClientPresenter/promptController, sources debug events from processManager, resolves workdir/MCP servers, registers session workdir, and manages prompt turns with persistence helpers.
DeepChat context-budget bypass for ACP
src/main/presenter/agentRuntimePresenter/index.ts, src/main/presenter/agentRuntimePresenter/process.ts
Adds shouldBypassDeepChatContextBudget and resolveDeepChatContextBudgetLength; propagates contextBudgetLength in processMessage/runStreamForMessage/resumeAssistantMessage to use effectively unbounded context for ACP and skip preflight/compaction/fitting when bypassing.
ConfigPresenter ACP refresh sequencing
src/main/presenter/configPresenter/index.ts
Awaits refreshAcpProviderAgents in repairAcpAgent and makes refresh flow async/await to ensure sequencing.
Renderer UI updates & i18n
src/renderer/settings/components/AcpDebugDialog.vue, src/renderer/settings/components/AcpSettings.vue, src/renderer/src/i18n/*/settings.json
Allows initialize action before ready, simplifies initialize payload, adds lifecycle/stderr event tones, debounces AGENTS_CHANGED reload with cleanup, and extends locale files with lifecycle/stderr keys.
Tests
test/main/presenter/*
Adds/extends tests covering debug actions, prompt/turn persistence and ordering, AcpFsHandler symlink escape checks, terminal cwd normalization/fallback, warmup behavior, and AgentRuntimePresenter bypass/compaction behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🐰 I hopped through runtime halls anew,
Guards set firm and logs in view.
Turns now saved, budgets stretched wide,
ACP runs smooth — the warren’s pride.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix(acp): align client runtime' is concise and clearly references the main change: aligning the ACP client runtime. It accurately summarizes the primary work across documentation, core runtime implementation, and supporting fixes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/acp-agent-compress-check

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
Copy Markdown
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: 12

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/acp/acpProcessManager.ts (1)

704-715: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clear the initialize timeout timer after Promise.race settles

The timeout handle is never cleared, so each successful init leaves a live timer until expiry.

Suggested fix
-      const timeoutPromise = new Promise<never>((_, reject) => {
-        setTimeout(() => {
+      let timeoutHandle: NodeJS.Timeout | null = null
+      const timeoutPromise = new Promise<never>((_, reject) => {
+        timeoutHandle = setTimeout(() => {
           reject(
             new Error(
               `[ACP] Connection initialization timeout after ${timeoutMs}ms for agent ${agent.id}`
             )
           )
         }, timeoutMs)
       })
-
-      const initResult = await Promise.race([initPromise, timeoutPromise])
+      const initResult = await Promise.race([initPromise, timeoutPromise])
+      if (timeoutHandle) {
+        clearTimeout(timeoutHandle)
+      }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/presenter/llmProviderPresenter/acp/acpProcessManager.ts` around
lines 704 - 715, The timeout created in timeoutPromise uses setTimeout but never
clears the timer, leaving a dangling handle; update the logic around
Promise.race([initPromise, timeoutPromise]) (symbols: timeoutPromise,
initPromise, setTimeout, timeoutMs, agent.id) to capture the timer id when
creating the timeout and ensure clearTimeout(timerId) is called once the race
settles (either in a finally block or immediately after awaiting initResult) so
the timer is always cleared whether initPromise wins or the timeout rejects.
🧹 Nitpick comments (1)
src/main/presenter/acpClientPresenter/types.ts (1)

28-42: ⚡ Quick win

Avoid maintaining two DeepChatAgentEvent unions in parallel.

This local union now overlaps with src/shared/contracts/acp.ts; keeping both as separate sources of truth creates easy drift risk across boundaries.

♻️ Suggested refactor
+import type { DeepChatAgentEvent as SharedDeepChatAgentEvent } from '@shared/contracts/acp'
 import type { AssistantMessageBlock } from '@shared/chat'

-export type DeepChatAgentEvent =
-  | { type: 'message.delta'; conversationId: string; text: string }
-  | { type: 'content.block'; conversationId: string; block: AssistantMessageBlock }
+export type DeepChatAgentEvent =
+  | SharedDeepChatAgentEvent
   | {
       type: 'tool.created' | 'tool.updated'
       conversationId: string
       toolCallId?: string
       block: AssistantMessageBlock
     }
-  | { type: 'plan.updated'; conversationId: string; entries: unknown[] }
-  | { type: 'terminal.updated'; conversationId: string; terminal: unknown }
-  | { type: 'permission.requested'; conversationId: string; request: unknown }
-  | { type: 'config.updated'; conversationId: string; configState: AcpConfigState }
-  | { type: 'turn.completed'; conversationId: string; stopReason: string }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/presenter/acpClientPresenter/types.ts` around lines 28 - 42, You
have duplicated the DeepChatAgentEvent union locally which overlaps the shared
contract; remove the local type declaration in types.ts and instead import the
canonical DeepChatAgentEvent from the shared contracts module (the exported
union for agent events) and re-export or use that type from here, ensuring all
references in this file point to the imported DeepChatAgentEvent; this keeps a
single source of truth and prevents drift between the local types and the shared
contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/presenter/llmProviderPresenter/acp/acpProcessManager.ts`:
- Around line 216-219: The current resolveCwdInsideWorkdir resolves cwd against
the process cwd which rejects valid relative cwd values; change the logic in
resolveCwdInsideWorkdir so that resolvedCwd uses path.resolve(workdir, cwd)
(i.e. resolve cwd relative to the session workdir when cwd is relative) before
calling isPathInside; keep the existing isPathInside(resolvedWorkdir,
resolvedCwd) check and return null if the resolved path is outside.

In `@src/main/presenter/llmProviderPresenter/acp/acpSessionManager.ts`:
- Around line 357-359: The detachHandlers disposal loop can throw and abort the
fallback to creating a new session; update the code around
detachHandlers?.forEach((dispose) => dispose()) so each disposer call is wrapped
in its own try/catch (or otherwise guarded) to swallow/non-fatally log errors
and continue, then set detachHandlers = undefined and call
this.processManager.clearSession(persistedSessionId) regardless; ensure you
reference and modify the dispose invocation site (detachHandlers.forEach) and
preserve the subsequent clearSession(persistedSessionId) and newSession fallback
flow.
- Around line 202-205: The catch currently calls await
this.processManager.unbindProcess(agent.id, conversationId) and then throws
error, but if unbindProcess itself throws it will replace the original
initialization error; change the catch to capture the original initialization
error into a variable (e.g., const initError = error), then call unbindProcess
inside its own try/catch and if unbindProcess throws, log or attach that cleanup
error but rethrow the original initError so the original failure is preserved;
update the catch block around the promise where
this.processManager.unbindProcess(agent.id, conversationId) is invoked to
implement this pattern.

In `@src/main/presenter/llmProviderPresenter/providers/acpProvider.ts`:
- Around line 894-900: The code is calling sessionPersistence.startTurn and
finishTurn fire-and-forget which can drop errors and allow races; change those
calls to await the Promise returned by sessionPersistence.startTurn(...) and
sessionPersistence.finishTurn(...) and wrap them in try/catch so persistence
errors are logged/propagated instead of being silent; ensure any code that calls
finishTurn awaits the awaited startTurn when sequencing is required (e.g., in
the same flow that uses startTurn/finishTurn), and apply the same change to the
other occurrences referenced by startTurn/finishTurn in this file (the blocks
around the other spots noted).

In `@src/renderer/src/i18n/da-DK/settings.json`:
- Line 1310: The "lifecycle" label in the settings i18n JSON is still in
English; update the value for the "lifecycle" key in
src/renderer/src/i18n/da-DK/settings.json (the JSON entry with "lifecycle":
"Lifecycle") to the Danish translation (e.g., "lifecycle": "Livscyklus") so the
event-kind labels stay localized and consistent with the surrounding entries.

In `@src/renderer/src/i18n/fa-IR/settings.json`:
- Line 1403: The "lifecycle" label in settings.json is still English; update the
value for the "lifecycle" key in src/renderer/src/i18n/fa-IR/settings.json to a
Persian translation to match surrounding entries (e.g., replace "Lifecycle" with
the appropriate Persian term), ensuring the JSON string remains properly quoted
and the file stays valid.

In `@src/renderer/src/i18n/fr-FR/settings.json`:
- Line 1403: Update the fr-FR localization for the key "lifecycle" in
settings.json by replacing the English value "Lifecycle" with the French
translation (e.g., "Cycle de vie") so the "lifecycle" label is localized
consistently in the fr-FR locale.

In `@src/renderer/src/i18n/he-IL/settings.json`:
- Line 1377: The "lifecycle" label in eventKinds (key "lifecycle") is still
English; replace the value "Lifecycle" with the appropriate Hebrew translation
to match sibling labels (update the "lifecycle" entry so eventKinds.lifecycle
shows the Hebrew string).

In `@src/renderer/src/i18n/ja-JP/settings.json`:
- Line 1403: The "lifecycle" string key is still in English; update the
localization for the "lifecycle" key in the ja-JP settings JSON (the "lifecycle"
property) to a Japanese translation such as "ライフサイクル" so it matches adjacent
event-kind labels and UI consistency.

In `@src/renderer/src/i18n/ko-KR/settings.json`:
- Line 1403: The "lifecycle" label in the ko-KR localization is still in
English; update the settings.json entry for the "lifecycle" key to a Korean
translation (for example, replace "Lifecycle" with "라이프사이클" or another
appropriate Korean term) so the event-kind labels are fully localized; locate
the "lifecycle" key in src/renderer/src/i18n/ko-KR/settings.json and change its
value to the Korean string.

In `@src/renderer/src/i18n/pt-BR/settings.json`:
- Line 1403: The "lifecycle" entry in the pt-BR locale map is still in English;
update the value for the "lifecycle" key in the settings.json locale object to
Portuguese (e.g., "Ciclo de vida") so the UI string for lifecycle is fully
localized in pt-BR and matches the other translated keys.

In `@src/renderer/src/i18n/ru-RU/settings.json`:
- Line 1403: The "lifecycle" entry in the Russian locale map is still in
English; update the value for the "lifecycle" key (the string "Lifecycle") to
the appropriate Russian translation (e.g., "Жизненный цикл") so the ru-RU
settings.json contains fully localized text for the lifecycle label.

---

Outside diff comments:
In `@src/main/presenter/llmProviderPresenter/acp/acpProcessManager.ts`:
- Around line 704-715: The timeout created in timeoutPromise uses setTimeout but
never clears the timer, leaving a dangling handle; update the logic around
Promise.race([initPromise, timeoutPromise]) (symbols: timeoutPromise,
initPromise, setTimeout, timeoutMs, agent.id) to capture the timer id when
creating the timeout and ensure clearTimeout(timerId) is called once the race
settles (either in a finally block or immediately after awaiting initResult) so
the timer is always cleared whether initPromise wins or the timeout rejects.

---

Nitpick comments:
In `@src/main/presenter/acpClientPresenter/types.ts`:
- Around line 28-42: You have duplicated the DeepChatAgentEvent union locally
which overlaps the shared contract; remove the local type declaration in
types.ts and instead import the canonical DeepChatAgentEvent from the shared
contracts module (the exported union for agent events) and re-export or use that
type from here, ensuring all references in this file point to the imported
DeepChatAgentEvent; this keeps a single source of truth and prevents drift
between the local types and the shared contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8fffba05-13fb-4af4-9941-35787f30be3c

📥 Commits

Reviewing files that changed from the base of the PR and between dcc8432 and 7a2cb28.

📒 Files selected for processing (47)
  • docs/architecture/acp-client-runtime/plan.md
  • docs/architecture/acp-client-runtime/spec.md
  • docs/architecture/acp-client-runtime/tasks.md
  • docs/issues/acp-context-budget-bypass/plan.md
  • docs/issues/acp-context-budget-bypass/spec.md
  • docs/issues/acp-context-budget-bypass/tasks.md
  • src/main/presenter/acpClientPresenter/connection/AcpConnectionManager.ts
  • src/main/presenter/acpClientPresenter/connection/AcpDebugLog.ts
  • src/main/presenter/acpClientPresenter/handlers/index.ts
  • src/main/presenter/acpClientPresenter/index.ts
  • src/main/presenter/acpClientPresenter/mapper/AcpEventMapper.ts
  • src/main/presenter/acpClientPresenter/registry/index.ts
  • src/main/presenter/acpClientPresenter/session/AcpPromptController.ts
  • src/main/presenter/acpClientPresenter/session/AcpSessionRuntime.ts
  • src/main/presenter/acpClientPresenter/types.ts
  • src/main/presenter/acpClientPresenter/workspace/AcpPathGuard.ts
  • src/main/presenter/agentRuntimePresenter/index.ts
  • src/main/presenter/agentRuntimePresenter/process.ts
  • src/main/presenter/configPresenter/index.ts
  • src/main/presenter/llmProviderPresenter/acp/acpFsHandler.ts
  • src/main/presenter/llmProviderPresenter/acp/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/acp/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/acp/acpSessionPersistence.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/main/presenter/sqlitePresenter/index.ts
  • src/main/presenter/sqlitePresenter/schemaCatalog.ts
  • src/main/presenter/sqlitePresenter/tables/acpTurns.ts
  • src/renderer/settings/components/AcpDebugDialog.vue
  • src/renderer/settings/components/AcpSettings.vue
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/shared/contracts/acp.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • test/main/presenter/acpProvider.test.ts
  • test/main/presenter/agentRuntimePresenter/agentRuntimePresenter.test.ts
  • test/main/presenter/llmProviderPresenter/acp/acpProcessManager.test.ts
  • test/main/presenter/llmProviderPresenter/acpFsHandler.test.ts

Comment thread src/main/presenter/llmProviderPresenter/acp/acpProcessManager.ts
Comment thread src/main/presenter/llmProviderPresenter/acp/acpSessionManager.ts
Comment thread src/main/presenter/llmProviderPresenter/acp/acpSessionManager.ts Outdated
Comment thread src/main/presenter/llmProviderPresenter/providers/acpProvider.ts Outdated
Comment thread src/renderer/src/i18n/da-DK/settings.json Outdated
Comment thread src/renderer/src/i18n/he-IL/settings.json Outdated
Comment thread src/renderer/src/i18n/ja-JP/settings.json Outdated
Comment thread src/renderer/src/i18n/ko-KR/settings.json Outdated
Comment thread src/renderer/src/i18n/pt-BR/settings.json Outdated
Comment thread src/renderer/src/i18n/ru-RU/settings.json Outdated
Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/presenter/llmProviderPresenter/acp/acpProcessManager.ts`:
- Around line 240-243: In the catch block that handles canonicalization of the
terminal cwd in acpProcessManager.ts (the block catching errors for variable cwd
and returning resolvedCwd), change the fallback to return null instead of
resolvedCwd so callers can trigger their fallback-to-session-workdir logic;
ensure the catch still logs the error (e.g., the existing console.warn using cwd
and error) but returns null to avoid propagating an invalid/unsafe resolvedCwd
value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 671c80b3-754b-403f-85a0-c9f4a89407c4

📥 Commits

Reviewing files that changed from the base of the PR and between 7a2cb28 and a41332f.

📒 Files selected for processing (18)
  • docs/issues/acp-pr-1614-review-fixes/plan.md
  • docs/issues/acp-pr-1614-review-fixes/spec.md
  • docs/issues/acp-pr-1614-review-fixes/tasks.md
  • src/main/presenter/acpClientPresenter/types.ts
  • src/main/presenter/llmProviderPresenter/acp/acpProcessManager.ts
  • src/main/presenter/llmProviderPresenter/acp/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • test/main/presenter/acpProvider.test.ts
  • test/main/presenter/acpSessionManager.test.ts
  • test/main/presenter/llmProviderPresenter/acp/acpProcessManager.test.ts
✅ Files skipped from review due to trivial changes (8)
  • docs/issues/acp-pr-1614-review-fixes/tasks.md
  • docs/issues/acp-pr-1614-review-fixes/plan.md
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/main/presenter/acpClientPresenter/types.ts
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/he-IL/settings.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • test/main/presenter/llmProviderPresenter/acp/acpProcessManager.test.ts
  • src/main/presenter/llmProviderPresenter/acp/acpSessionManager.ts
  • src/main/presenter/llmProviderPresenter/providers/acpProvider.ts

Comment on lines +240 to +243
} catch (error) {
console.warn(`[ACP] Failed to resolve terminal cwd "${cwd}":`, error)
return resolvedCwd
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve safe fallback when cwd canonicalization fails.

If canonicalization throws, this currently returns resolvedCwd, which bypasses the caller’s fallback-to-session-workdir path. Return null here so invalid/unsafe error-path cwd values cannot slip through.

Suggested fix
     } catch (error) {
       console.warn(`[ACP] Failed to resolve terminal cwd "${cwd}":`, error)
-      return resolvedCwd
+      return null
     }
📝 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
} catch (error) {
console.warn(`[ACP] Failed to resolve terminal cwd "${cwd}":`, error)
return resolvedCwd
}
} catch (error) {
console.warn(`[ACP] Failed to resolve terminal cwd "${cwd}":`, error)
return null
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/presenter/llmProviderPresenter/acp/acpProcessManager.ts` around
lines 240 - 243, In the catch block that handles canonicalization of the
terminal cwd in acpProcessManager.ts (the block catching errors for variable cwd
and returning resolvedCwd), change the fallback to return null instead of
resolvedCwd so callers can trigger their fallback-to-session-workdir logic;
ensure the catch still logs the error (e.g., the existing console.warn using cwd
and error) but returns null to avoid propagating an invalid/unsafe resolvedCwd
value.

@zerob13 zerob13 merged commit cb80c58 into dev May 12, 2026
3 checks passed
@zhangmo8 zhangmo8 deleted the fix/acp-agent-compress-check branch May 12, 2026 07:51
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.

1 participant