Skip to content

fix(cua): upgrade to 0.12.6 with supervised lifecycle - #2052

Merged
yyhhyyyyyy merged 17 commits into
devfrom
fix/2039-plugin-runtime-lifecycle
Jul 28, 2026
Merged

fix(cua): upgrade to 0.12.6 with supervised lifecycle#2052
yyhhyyyyyy merged 17 commits into
devfrom
fix/2039-plugin-runtime-lifecycle

Conversation

@yyhhyyyyyy

@yyhhyyyyyy yyhhyyyyyy commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #2039 by upgrading the bundled CUA runtime to 0.12.6 and introducing a single lifecycle boundary for plugin-owned external processes.

CUA now starts on demand instead of during plugin activation, preventing the legacy eager-start behavior that could disrupt Linux/X11 desktop sessions.

Changes

  • Added a runtime supervisor as the sole lifecycle owner of plugin-managed MCP processes.
  • Added static tool discovery and on-demand startup for CUA while keeping Feishu eager.
  • Added crash sentinels, fingerprint-bound quarantine, explicit runtime retry, and per-spawn integrity verification.
  • Restricted inherited runtime environments without changing ordinary user-configured MCP behavior.
  • Updated CUA packaging and protocol integration for upstream 0.12.6, including macOS signing contracts and removal of the Windows UIAccess worker.
  • Added model-facing CUA adapters for empty element_token, structured tool results, and opt-in screenshot grounding.
  • Added runtime status, “Test runtime,” and recoverable “Retry runtime” UI actions.
  • Added lifecycle, security, migration, packaging, adapter, and UI regression coverage.

Closes #2039

Summary by CodeRabbit

  • New Features
    • Added supervised, on-demand Computer Use runtime support across macOS, Windows, and Linux with embedded runtime lifecycle management and tool-catalog validation.
    • Introduced runtime integrity verification and stricter per-tool policies for browser/computer actions.
    • Expanded Computer Use guidance and improved screenshot/structured-result handling, including stale-token retry behavior.
    • Added support for many new AI models and updated capability metadata.
  • Bug Fixes
    • Prevented unsafe or unauthorized runtime starts and blocked modified/stale runtime artifacts.
  • UI
    • Added runtime “Ready on demand” and “Quarantined” states, plus “Test Runtime” and “Retry Runtime” actions with new localized messaging.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2ca46066-4939-484e-956b-218bbe878fee

📥 Commits

Reviewing files that changed from the base of the PR and between 5700383 and 30794dd.

📒 Files selected for processing (3)
  • src/main/mcp/mcpClient.ts
  • test/main/mcp/mcpClient.test.ts
  • test/main/scripts/packagePlugin.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/main/mcp/mcpClient.test.ts
  • test/main/scripts/packagePlugin.test.ts

📝 Walkthrough

Walkthrough

This PR adds supervised lifecycle management for plugin-owned runtimes, upgrades CUA to embedded driver 0.12.6 operation, introduces static catalog and integrity validation, updates MCP ownership and policies, adds runtime diagnostics UI, refreshes CUA documentation, and updates provider model metadata.

Changes

Plugin External Runtime Lifecycle and CUA 0.12.6

Layer / File(s) Summary
Runtime supervision and safety
src/main/plugin/runtimeSupervisor.ts, src/main/plugin/cuaEmbeddedAdapter.ts, src/main/plugin/cuaRuntimeIntegrity.ts
Plugin runtimes use supervised registration, start/stop/reconciliation, sentinel and quarantine state, fingerprint validation, endpoint handshakes, stale recovery, and integrity checks.
MCP ownership, catalogs, policies, and dispatch
src/main/mcp/*, src/main/plugin/toolCatalog.ts, src/main/plugin/toolPolicyStore.ts, src/shared/types/*
MCP integrates trusted ownership, on-demand catalog discovery, live schema verification, minimal environments, closed per-tool policies, structured results, and CUA ownership metadata.
Packaging and CUA configuration
scripts/build-cua-plugin-runtime.mjs, scripts/package-plugin.mjs, plugins/cua/*, plugins/cua/vendor/cua-driver/upstream.json
Packaging pins driver 0.12.6, generates catalogs and integrity descriptors, removes the Windows UIA worker, validates target artifacts, and configures embedded on-demand execution.
Plugin lifecycle and diagnostics UI
src/main/plugin/index.ts, src/renderer/src/pages/plugins/*, plugins/cua/settings/*, src/renderer/src/i18n/*
Activation errors, lifecycle states, quarantine, integrity failures, test/retry actions, and platform diagnostics are exposed through plugin settings APIs and views.
CUA model-facing compatibility
src/main/plugin/cuaToolAdapter.ts, src/main/agent/deepchat/runtime/toolAdapters.ts, plugins/cua/skills/*
CUA arguments, structured window-state projections, screenshots, visual grounding, stale-token handling, browser bindings, session behavior, and untrusted observations are adapted and documented.
Validation and metadata refresh
test/main/*, test/renderer/*, resources/model-db/providers.json, scripts/fetch-provider-db.mjs
Lifecycle, adapter, integrity, catalog, packaging, MCP, renderer, and provider-database coverage is expanded.
Architecture and release documentation
docs/architecture/plugin-external-runtime-lifecycle/*, docs/features/cua-cross-platform-computer-use/*
Architecture, task checklists, compatibility contracts, packaging gates, release constraints, and remaining native validation items are documented.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The large resources/model-db/providers.json update adds many unrelated model metadata changes that are not needed for the CUA fix. Split the provider database/model metadata changes into a separate PR unless they are required for the CUA runtime work.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: upgrading CUA to 0.12.6 with supervised lifecycle handling.
Linked Issues check ✅ Passed The changes prevent eager CUA startup and add integrity, quarantine, and recovery handling that directly address the black-screen crash.
✨ 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/2039-plugin-runtime-lifecycle

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (1)
src/main/mcp/serverManager.ts (1)

250-288: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Reuse the adapter’s config override on guarded restarts.

CuaEmbeddedRuntimeAdapter.start() emits command/args via configOverride, but ServerManager.startServer() falls back to existingClient.serverConfig when a non-running client still exists. A stale guarded restart can connect the MCP proxy with the persisted config instead of the adapter-supplied endpoint config; stop/evict the existing client before reconnecting with the override. Also merge env keys deeply instead of replacing them.

🤖 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/mcp/serverManager.ts` around lines 250 - 288, Update startServer so
a non-running existing client is stopped and evicted before restarting, ensuring
the supplied configOverride is applied instead of reusing
existingClient.serverConfig. Preserve the existing running-client fast path, and
merge configOverride.env with the persisted environment keys rather than
replacing the entire env object.
🧹 Nitpick comments (11)
test/main/plugin/cuaEmbeddedAdapter.test.ts (1)

315-332: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: inject requestMetadata here to avoid a real connect against a fixed /tmp path.

This case relies on the default dependency attempting a real connection to the hardcoded /tmp/deepchat-cua-123-aabbccddeeff.sock. It passes because the path is normally absent, but a leftover socket/file on a developer or CI machine would change the outcome. The neighbouring tests already stub requestMetadata; doing the same here keeps it hermetic.

🤖 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 `@test/main/plugin/cuaEmbeddedAdapter.test.ts` around lines 315 - 332, Update
the test around CuaEmbeddedRuntimeAdapter.recoverStaleLaunch to inject a
requestMetadata stub, matching the neighboring tests. Ensure the stub avoids any
real connection to the fixed endpoint while preserving the identity-matching
recovery assertions.
src/main/plugin/cuaEmbeddedAdapter.ts (1)

386-386: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Nit: local endpointIdentity shadows the module-level helper of the same name.

No behavioral issue here (the helper is reached via dependencies.captureEndpointIdentity), but the shadowing makes Lines 439/453 harder to read and is a trap for future edits. Consider renaming the local to capturedIdentity.

🤖 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/plugin/cuaEmbeddedAdapter.ts` at line 386, Rename the local
endpointIdentity variable in the relevant adapter flow to capturedIdentity, and
update all references such as those near lines 439 and 453 while preserving the
existing dependencies.captureEndpointIdentity helper usage.
src/main/plugin/cuaRuntimeIntegrity.ts (1)

299-308: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider a timeout for codesign/plutil invocations.

runCommand runs on the pre-spawn verification path for every guarded start. Without timeout, a hung codesign (e.g. blocked on a stapling/keychain prompt) leaves the runtime start pending indefinitely with no error surfaced to the supervisor.

♻️ Proposed change
 const runCommand = async (command: string, args: string[]): Promise<CommandResult> => {
   const result = await execFileAsync(command, args, {
     encoding: 'utf8',
-    maxBuffer: COMMAND_OUTPUT_LIMIT
+    maxBuffer: COMMAND_OUTPUT_LIMIT,
+    timeout: COMMAND_TIMEOUT_MS
   })
🤖 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/plugin/cuaRuntimeIntegrity.ts` around lines 299 - 308, Update
runCommand to provide a finite timeout when invoking codesign/plutil through
execFileAsync, ensuring hung verification commands reject and surface an error
to the supervisor instead of blocking startup indefinitely. Preserve the
existing output conversion and COMMAND_OUTPUT_LIMIT settings.
src/main/plugin/cuaToolAdapter.ts (1)

3-3: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicate CUA_PLUGIN_ID constant.

src/main/plugin/index.ts (Line 42) declares its own const CUA_PLUGIN_ID = 'com.deepchat.plugins.cua'. Import the exported one here instead to keep a single source of truth.

🤖 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/plugin/cuaToolAdapter.ts` at line 3, Remove the duplicate
CUA_PLUGIN_ID declaration from src/main/plugin/index.ts and import the exported
CUA_PLUGIN_ID from cuaToolAdapter.ts instead, preserving all existing usages and
the single shared value.
test/main/plugin/pluginService.test.ts (1)

1366-1375: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer behavioral assertions over source-text matching.

Grepping src/main/plugin/index.ts for identifiers like this.runtimeSupervisor.registerServer couples the suite to source formatting: destructuring the supervisor or renaming a private helper breaks this test without any behavior change. The supervisor wiring is already covered behaviorally at Lines 762-775 and 894-919 via the runtimeSupervisor mock; consider dropping the string checks (or keeping only the startPluginMcpServersIfReady removal check as a temporary migration guard).

As per coding guidelines, "Keep committed tests lean and focused on project reliability, stability, and observable contracts; remove temporary checks that only test implementation internals before handoff."

🤖 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 `@test/main/plugin/pluginService.test.ts` around lines 1366 - 1375, Replace the
source-text identifier assertions in the test case with behavioral coverage
using the existing runtimeSupervisor mock and related tests around plugin
registration and reconciliation. Remove checks for helper names and
registerServer/reconcilePlugin source strings; retain the
startPluginMcpServersIfReady absence check only if it is still required as a
temporary migration guard.

Source: Coding guidelines

test/main/scripts/packagePlugin.test.ts (1)

277-299: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add the negative case for a missing Apple Team ID.

createDarwinSigningContract hard-fails distribution packaging when DEEPCHAT_APPLE_NOTARY_TEAM_ID is absent or malformed, but no test covers it — a regression there would silently emit an ad-hoc/null-team descriptor for a release artifact.

As per coding guidelines, "Add the smallest regression test for user-visible behavior or a documented contract."

💚 Suggested test
it('rejects macOS distribution packaging without a valid Apple Team ID', async () => {
  const fixture = await createCuaPluginFixture()
  const outDir = path.join(fixture.root, 'out')

  const result = runPackagePlugin(fixture.pluginDir, outDir, 'darwin', 'arm64', {
    purpose: 'distribution',
    env: { DEEPCHAT_APPLE_NOTARY_TEAM_ID: '' }
  })

  expect(result.status).not.toBe(0)
  expect(result.stderr).toContain('requires a valid Apple Team ID')
})
🤖 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 `@test/main/scripts/packagePlugin.test.ts` around lines 277 - 299, Add a
regression test alongside the existing macOS distribution packaging test that
invokes runPackagePlugin with an empty DEEPCHAT_APPLE_NOTARY_TEAM_ID, then
assert the process fails and stderr contains “requires a valid Apple Team ID.”

Source: Coding guidelines

scripts/build-cua-plugin-runtime.mjs (1)

714-718: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Move the native-target guard before download/stage/sign.

This condition depends only on targetPlatform/targetArch versus the host, yet it fires after downloading, extracting, staging, codesigning, and smoke-checking. Hoisting it next to the arg parsing (around Line 679) fails fast and avoids leaving a signed-but-unusable runtime dir behind for cross-target invocations.

Also note Line 727: fs.stat on Line 726 already throws for a missing executable, so the fsSync.existsSync check is unreachable.

♻️ Proposed hoist
-    smokeCheck(executable, targetPlatform, targetArch)
-    if (!canRunTarget(targetPlatform, targetArch)) {
-      throw new Error(
-        `CUA MCP tool catalog must be generated on its native target; host is ${process.platform}/${process.arch}, target is ${targetPlatform}/${targetArch}`
-      )
-    }
+    smokeCheck(executable, targetPlatform, targetArch)

Add near the top of main() (after targetArch is normalized):

if (!canRunTarget(targetPlatform, targetArch)) {
  throw new Error(
    `CUA MCP tool catalog must be generated on its native target; host is ${process.platform}/${process.arch}, target is ${targetPlatform}/${targetArch}`
  )
}
🤖 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 `@scripts/build-cua-plugin-runtime.mjs` around lines 714 - 718, Move the
canRunTarget guard from the late build flow into main(), immediately after
targetArch is normalized, so cross-target invocations fail before download,
staging, signing, or smoke checks. Preserve the existing error message and
remove the later duplicate guard; also remove the redundant fsSync.existsSync
check near fs.stat because fs.stat already rejects missing executables.
src/main/mcp/toolManager.ts (3)

1021-1027: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Drop the now-unused _serverConfig parameter.

prepareToolArguments no longer reads the server config; removing the parameter (and the argument at Line 851) keeps the signature honest.

🤖 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/mcp/toolManager.ts` around lines 1021 - 1027, Remove the unused
_serverConfig parameter from prepareToolArguments and remove the corresponding
argument at its call site around line 851, preserving the remaining parameter
order and behavior.

433-449: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate predicate, and plugin-owned servers bypass enabledServerIds gating.

isServerConfigAllowedByContext is now byte-identical to isServerAllowedByContext apart from an unused _serverConfig parameter — collapse the two and drop the dead parameter at the call sites (Lines 626, 789).

Separately, please confirm the exemption at Line 434/445 is intended: any supervisor-available plugin server is allowed regardless of an agent's configured enabledServerIds, so an agent with a restricted MCP allowlist can still reach CUA tools.

🤖 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/mcp/toolManager.ts` around lines 433 - 449, Collapse
isServerConfigAllowedByContext into isServerAllowedByContext, remove the unused
_serverConfig parameter, and update the call sites around the referenced usages
to call the shared predicate. Preserve the current
pluginOwnership.isServerAvailable exemption so supervisor-available plugin
servers remain allowed regardless of enabledServerIds.

162-189: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Diagnostics call has no timeout/abort.

client.callTool('check_permissions', …) at Line 180 (and the listTools() inside verifyCatalogTool) can hang indefinitely if the runtime is wedged, leaving the settings "Test runtime" action spinning with no way to cancel. Consider passing an AbortSignal with a bounded timeout through to verifyCatalogTool/callTool.

🤖 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/mcp/toolManager.ts` around lines 162 - 189, Add a bounded timeout
with an AbortSignal to checkPluginRuntimePermissions, and propagate that signal
through verifyCatalogTool and the client.callTool('check_permissions', ...)
invocation. Ensure both the listTools validation and diagnostics call terminate
when the timeout expires, preserving the existing permission and error handling
behavior.
test/main/mcp/toolManager.test.ts (1)

92-131: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Helper can't express "owned but unavailable", leaving the quarantine path untested.

isServerAvailable is hardwired to ownsServer, so no test exercises the branches this PR adds for a quarantined/unavailable plugin server: the skip in loadToolSources (toolManager.ts Lines 344-350) and the "is no longer available" throw in resolveToolClient (Lines 939-941). Allowing an unavailable set in the helper would make that regression cheap to cover.

🤖 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 `@test/main/mcp/toolManager.test.ts` around lines 92 - 131, The
createToolManager test helper currently couples server ownership with
availability, preventing tests from modeling quarantined servers. Add an
optional unavailable-server set to createToolManager and make isServerAvailable
return false for those names while preserving ownership behavior; use it to
cover the unavailable branches in loadToolSources and resolveToolClient.
🤖 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 `@resources/model-db/providers.json`:
- Around line 258595-258614: Add a meaningful type field with value "tts" to
every listed TTS model object, including tts-1, tts-1-hd, tts-1-1106, and
tts-1-hd-1106 across the referenced ranges. Place it alongside the existing cost
and model metadata so sanitizeAggregate preserves the TTS classification.

In `@src/main/mcp/index.ts`:
- Around line 781-808: Update the startup flow spanning startServerDirect,
ServerManager, and McpClient.connect so waitForConnection preserves access to
the underlying connection completion after a soft timeout; do not read
getConnectionCompletion() only after connectPromise may have been cleared by
finally. Propagate the wait requirement through ServerManager/McpClient.connect,
or retain the completion until startServerDirect has accounted for it, ensuring
the CUA path waits for and handles the real connection result instead of
throwing a missing-completion error.

In `@src/main/plugin/index.ts`:
- Around line 327-332: Clear the plugin’s entry from activationErrors when
explicitly disabling it in the flow containing this.upsertInstallation and
disableByOwner(pluginId). Ensure buildPluginListItem no longer surfaces the
stale activation error after disable, while preserving the existing disable and
installation-update behavior.

---

Outside diff comments:
In `@src/main/mcp/serverManager.ts`:
- Around line 250-288: Update startServer so a non-running existing client is
stopped and evicted before restarting, ensuring the supplied configOverride is
applied instead of reusing existingClient.serverConfig. Preserve the existing
running-client fast path, and merge configOverride.env with the persisted
environment keys rather than replacing the entire env object.

---

Nitpick comments:
In `@scripts/build-cua-plugin-runtime.mjs`:
- Around line 714-718: Move the canRunTarget guard from the late build flow into
main(), immediately after targetArch is normalized, so cross-target invocations
fail before download, staging, signing, or smoke checks. Preserve the existing
error message and remove the later duplicate guard; also remove the redundant
fsSync.existsSync check near fs.stat because fs.stat already rejects missing
executables.

In `@src/main/mcp/toolManager.ts`:
- Around line 1021-1027: Remove the unused _serverConfig parameter from
prepareToolArguments and remove the corresponding argument at its call site
around line 851, preserving the remaining parameter order and behavior.
- Around line 433-449: Collapse isServerConfigAllowedByContext into
isServerAllowedByContext, remove the unused _serverConfig parameter, and update
the call sites around the referenced usages to call the shared predicate.
Preserve the current pluginOwnership.isServerAvailable exemption so
supervisor-available plugin servers remain allowed regardless of
enabledServerIds.
- Around line 162-189: Add a bounded timeout with an AbortSignal to
checkPluginRuntimePermissions, and propagate that signal through
verifyCatalogTool and the client.callTool('check_permissions', ...) invocation.
Ensure both the listTools validation and diagnostics call terminate when the
timeout expires, preserving the existing permission and error handling behavior.

In `@src/main/plugin/cuaEmbeddedAdapter.ts`:
- Line 386: Rename the local endpointIdentity variable in the relevant adapter
flow to capturedIdentity, and update all references such as those near lines 439
and 453 while preserving the existing dependencies.captureEndpointIdentity
helper usage.

In `@src/main/plugin/cuaRuntimeIntegrity.ts`:
- Around line 299-308: Update runCommand to provide a finite timeout when
invoking codesign/plutil through execFileAsync, ensuring hung verification
commands reject and surface an error to the supervisor instead of blocking
startup indefinitely. Preserve the existing output conversion and
COMMAND_OUTPUT_LIMIT settings.

In `@src/main/plugin/cuaToolAdapter.ts`:
- Line 3: Remove the duplicate CUA_PLUGIN_ID declaration from
src/main/plugin/index.ts and import the exported CUA_PLUGIN_ID from
cuaToolAdapter.ts instead, preserving all existing usages and the single shared
value.

In `@test/main/mcp/toolManager.test.ts`:
- Around line 92-131: The createToolManager test helper currently couples server
ownership with availability, preventing tests from modeling quarantined servers.
Add an optional unavailable-server set to createToolManager and make
isServerAvailable return false for those names while preserving ownership
behavior; use it to cover the unavailable branches in loadToolSources and
resolveToolClient.

In `@test/main/plugin/cuaEmbeddedAdapter.test.ts`:
- Around line 315-332: Update the test around
CuaEmbeddedRuntimeAdapter.recoverStaleLaunch to inject a requestMetadata stub,
matching the neighboring tests. Ensure the stub avoids any real connection to
the fixed endpoint while preserving the identity-matching recovery assertions.

In `@test/main/plugin/pluginService.test.ts`:
- Around line 1366-1375: Replace the source-text identifier assertions in the
test case with behavioral coverage using the existing runtimeSupervisor mock and
related tests around plugin registration and reconciliation. Remove checks for
helper names and registerServer/reconcilePlugin source strings; retain the
startPluginMcpServersIfReady absence check only if it is still required as a
temporary migration guard.

In `@test/main/scripts/packagePlugin.test.ts`:
- Around line 277-299: Add a regression test alongside the existing macOS
distribution packaging test that invokes runPackagePlugin with an empty
DEEPCHAT_APPLE_NOTARY_TEAM_ID, then assert the process fails and stderr contains
“requires a valid Apple Team ID.”
🪄 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 Plus

Run ID: 2da7a71a-297f-419b-8584-878b19de7178

📥 Commits

Reviewing files that changed from the base of the PR and between 082edea and 6750aa7.

📒 Files selected for processing (88)
  • docs/architecture/plugin-external-runtime-lifecycle/plan.md
  • docs/architecture/plugin-external-runtime-lifecycle/spec.md
  • docs/architecture/plugin-external-runtime-lifecycle/tasks.md
  • docs/features/cua-cross-platform-computer-use/plan.md
  • docs/features/cua-cross-platform-computer-use/spec.md
  • docs/features/cua-cross-platform-computer-use/tasks.md
  • plugins/cua/build/entitlements.plist
  • plugins/cua/mcp/cua-driver.json
  • plugins/cua/plugin.json
  • plugins/cua/policies/tool-policy.json
  • plugins/cua/settings/assets/index.css
  • plugins/cua/settings/assets/index.js
  • plugins/cua/settings/index.html
  • plugins/cua/skills/computer-use/README.md
  • plugins/cua/skills/computer-use/SKILL.md
  • plugins/cua/skills/computer-use/TESTS.md
  • plugins/cua/skills/computer-use/WEB_APPS.md
  • plugins/cua/vendor/cua-driver/upstream.json
  • resources/acp-registry/registry.json
  • resources/model-db/providers.json
  • scripts/build-cua-plugin-runtime.mjs
  • scripts/cua-macos-contract.mjs
  • scripts/cua-tool-catalog-contract.mjs
  • scripts/package-plugin.mjs
  • scripts/plugin.mjs
  • src/main/agent/deepchat/loop/ports.ts
  • src/main/agent/deepchat/runtime/deferredToolExecutor.ts
  • src/main/agent/deepchat/runtime/dispatch.ts
  • src/main/agent/deepchat/runtime/toolAdapters.ts
  • src/main/agent/deepchat/runtime/toolRuntimeBindings.ts
  • src/main/agent/shared/process/processTree.ts
  • src/main/app/composition.ts
  • src/main/mcp/index.ts
  • src/main/mcp/mcpClient.ts
  • src/main/mcp/processEnvironment.ts
  • src/main/mcp/serverManager.ts
  • src/main/mcp/toolManager.ts
  • src/main/plugin/cuaEmbeddedAdapter.ts
  • src/main/plugin/cuaRuntimeIntegrity.ts
  • src/main/plugin/cuaToolAdapter.ts
  • src/main/plugin/index.ts
  • src/main/plugin/runtimeSupervisor.ts
  • src/main/plugin/toolCatalog.ts
  • src/main/plugin/toolPolicyStore.ts
  • src/preload/plugin-settings-preload.ts
  • src/renderer/settings/components/PluginsSettings.vue
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/de-DE/settings.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/es-ES/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/id-ID/settings.json
  • src/renderer/src/i18n/it-IT/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/vi-VN/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/renderer/src/pages/plugins/OfficialPluginDetailPage.vue
  • src/shared/types/core/mcp.ts
  • src/shared/types/mcp.ts
  • src/shared/types/plugin.ts
  • test/main/agent/deepchat/runtime/toolAdapters.test.ts
  • test/main/agent/shared/process/processTree.test.ts
  • test/main/mcp/mcpClient.test.ts
  • test/main/mcp/mcpService.test.ts
  • test/main/mcp/processEnvironment.test.ts
  • test/main/mcp/toolManager.test.ts
  • test/main/plugin/cuaEmbeddedAdapter.test.ts
  • test/main/plugin/cuaRuntimeIntegrity.test.ts
  • test/main/plugin/cuaToolAdapter.test.ts
  • test/main/plugin/pluginService.test.ts
  • test/main/plugin/runtimeSupervisor.test.ts
  • test/main/plugin/toolCatalog.test.ts
  • test/main/scripts/buildCuaPluginRuntime.test.ts
  • test/main/scripts/packagePlugin.test.ts
  • test/main/scripts/verifyCuaMacosHelper.test.ts
  • test/renderer/components/OfficialPluginDetailPage.test.ts
  • test/renderer/plugins/cuaSettings.test.ts
  • test/renderer/stores/mcpStore.test.ts

Comment thread resources/model-db/providers.json Outdated
Comment thread src/main/mcp/index.ts
Comment thread src/main/plugin/index.ts

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
src/main/plugin/cuaEmbeddedAdapter.ts (1)

353-380: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Serialize start and stop transitions.

Two concurrent start() calls can both observe no running daemon and spawn independently; the final assignment at Line 446 overwrites ownership of the first process. Likewise, stop() during startup sees no running state and returns, allowing the daemon to come up after shutdown was requested. Use one lifecycle mutex/queue for both operations and add concurrent start/stop regression coverage.

Also applies to: 430-447, 488-521

🤖 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/plugin/cuaEmbeddedAdapter.ts` around lines 353 - 380, Serialize the
lifecycle transitions in the CuaEmbeddedAdapter so concurrent start() calls
cannot spawn multiple daemons and stop() cannot return before an in-progress
startup completes. Use a shared mutex or promise queue around the full start()
and stop() flows, including process creation and running-state assignment, then
add regression coverage for concurrent starts and stop-during-startup behavior.
🤖 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/mcp/mcpClient.ts`:
- Around line 1298-1303: Update the listTools catch block after
awaitWithAbort(this.checkAndHandleSessionError(error), options?.signal) to call
options?.signal?.throwIfAborted(), matching callTool. Ensure cancellation that
occurs during session-error handling is propagated before the code continues to
cache, return an empty result, or rethrow the original error.

In `@test/main/scripts/packagePlugin.test.ts`:
- Around line 287-299: Extend the policy-projection test matrix in the
platform/expectedPolicy loop to include a Darwin case with the expected macOS
target-scoped policy, ensuring Linux- and Windows-only entries are not accepted
in the Darwin artifact.

---

Outside diff comments:
In `@src/main/plugin/cuaEmbeddedAdapter.ts`:
- Around line 353-380: Serialize the lifecycle transitions in the
CuaEmbeddedAdapter so concurrent start() calls cannot spawn multiple daemons and
stop() cannot return before an in-progress startup completes. Use a shared mutex
or promise queue around the full start() and stop() flows, including process
creation and running-state assignment, then add regression coverage for
concurrent starts and stop-during-startup behavior.
🪄 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 Plus

Run ID: 0323a36b-8f0c-4735-80b5-2de63be7ff4a

📥 Commits

Reviewing files that changed from the base of the PR and between 6750aa7 and 697103b.

📒 Files selected for processing (30)
  • docs/architecture/plugin-external-runtime-lifecycle/plan.md
  • docs/architecture/plugin-external-runtime-lifecycle/spec.md
  • docs/architecture/plugin-external-runtime-lifecycle/tasks.md
  • plugins/cua/plugin.json
  • plugins/cua/policies/tool-policy.json
  • resources/model-db/providers.json
  • scripts/build-cua-plugin-runtime.mjs
  • scripts/fetch-provider-db.mjs
  • scripts/package-plugin.mjs
  • src/main/agent/deepchat/runtime/toolAdapters.ts
  • src/main/mcp/index.ts
  • src/main/mcp/mcpClient.ts
  • src/main/mcp/serverManager.ts
  • src/main/mcp/toolManager.ts
  • src/main/plugin/cuaEmbeddedAdapter.ts
  • src/main/plugin/cuaRuntimeIntegrity.ts
  • src/main/plugin/cuaToolAdapter.ts
  • src/main/plugin/index.ts
  • src/main/plugin/toolPolicyStore.ts
  • src/renderer/src/pages/plugins/OfficialPluginDetailPage.vue
  • src/renderer/src/pages/plugins/PluginsCatalogPage.vue
  • src/shared/types/plugin.ts
  • test/main/mcp/mcpClient.test.ts
  • test/main/mcp/mcpService.test.ts
  • test/main/mcp/serverManager.test.ts
  • test/main/mcp/toolManager.test.ts
  • test/main/plugin/cuaEmbeddedAdapter.test.ts
  • test/main/plugin/pluginService.test.ts
  • test/main/scripts/fetchProviderDb.test.ts
  • test/main/scripts/packagePlugin.test.ts
💤 Files with no reviewable changes (1)
  • src/main/plugin/cuaToolAdapter.ts
🚧 Files skipped from review as they are similar to previous changes (17)
  • test/main/mcp/mcpClient.test.ts
  • plugins/cua/plugin.json
  • src/renderer/src/pages/plugins/OfficialPluginDetailPage.vue
  • src/shared/types/plugin.ts
  • test/main/mcp/mcpService.test.ts
  • scripts/build-cua-plugin-runtime.mjs
  • src/main/plugin/toolPolicyStore.ts
  • src/main/agent/deepchat/runtime/toolAdapters.ts
  • docs/architecture/plugin-external-runtime-lifecycle/plan.md
  • test/main/mcp/toolManager.test.ts
  • docs/architecture/plugin-external-runtime-lifecycle/spec.md
  • scripts/package-plugin.mjs
  • docs/architecture/plugin-external-runtime-lifecycle/tasks.md
  • src/main/mcp/toolManager.ts
  • src/main/plugin/index.ts
  • test/main/plugin/pluginService.test.ts
  • src/main/mcp/index.ts

Comment thread src/main/mcp/mcpClient.ts
Comment thread test/main/scripts/packagePlugin.test.ts
@yyhhyyyyyy
yyhhyyyyyy merged commit 502c7ec into dev Jul 28, 2026
21 checks passed
@yyhhyyyyyy
yyhhyyyyyy deleted the fix/2039-plugin-runtime-lifecycle branch July 28, 2026 11:37
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.

[BUG] Black screen after enabling cua driver

1 participant