mirror of
https://github.com/NanmiCoder/claude-code-haha.git
synced 2026-10-10 20:03:13 +08:00
feat: let users opt out of bundled Computer Use
Computer Use is useful when explicitly needed, but exposing its MCP tools by default creates unnecessary desktop-control surface for users who want coding-only sessions. This adds a shared disable path for CLI flags, environment, and desktop settings while keeping preauthorized app state in one config file. The same change also preserves Windows and WSL shell startup behavior by applying the MSYS argument-conversion guard only on WSL-bound launches. Constraint: Computer Use MCP must not be exposed to the Coding Agent when disabled Constraint: Desktop settings and CLI sessions need to read the same persisted Computer Use config Rejected: Environment-only disable switch | desktop users need a persistent Settings control Rejected: Remove Computer Use setup entirely | enabled sessions still need the existing built-in MCP path Confidence: high Scope-risk: moderate Directive: Keep every new Computer Use entrypoint wired through loadStoredComputerUseConfig or the CLI disable flag before adding MCP tools Tested: bun test src/utils/computerUse/gates.test.ts src/utils/computerUse/preauthorizedConfig.test.ts src/server/__tests__/computer-use-api.test.ts src/utils/shell/wslInterop.test.ts desktop/src/pages/ComputerUseSettings.test.tsx Tested: bun run check:server; bun run check:desktop; bun run check:docs; bun run check:policy; bun run check:native; git diff --check Tested: SKIP_INSTALL=1 ./desktop/scripts/build-macos-arm64.sh; codesign verify; hdiutil verify; built CLI Computer Use E2E exposure and disable checks Not-tested: Full screenshot/control action after granting macOS Screen Recording permission on this machine
This commit is contained in:
@@ -27,10 +27,7 @@ import { registerEscHotkey } from './escHotkey.js';
|
||||
import { getChicagoCoordinateMode } from './gates.js';
|
||||
import { getComputerUseHostAdapter } from './hostAdapter.js';
|
||||
import { getComputerUseMCPRenderingOverrides } from './toolRendering.js';
|
||||
import { resolveStoredComputerUseConfig } from './preauthorizedConfig.js';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { homedir } from 'node:os';
|
||||
import { loadStoredComputerUseConfig } from './preauthorizedConfig.js';
|
||||
type CallOverride = Pick<Tool, 'call'>['call'];
|
||||
type Binding = {
|
||||
ctx: ComputerUseSessionContext;
|
||||
@@ -270,30 +267,11 @@ async function runDesktopPermissionDialog(
|
||||
* immediately — no runtime permission dialog needed.
|
||||
*/
|
||||
async function loadPreAuthorizedApps(): Promise<void> {
|
||||
let config:
|
||||
| {
|
||||
authorizedApps?: { bundleId: string; displayName: string }[]
|
||||
grantFlags?: { clipboardRead?: boolean; clipboardWrite?: boolean; systemKeyCombos?: boolean }
|
||||
}
|
||||
| undefined
|
||||
|
||||
try {
|
||||
const configPath = join(
|
||||
process.env.CLAUDE_CONFIG_DIR ?? join(homedir(), '.claude'),
|
||||
'cc-haha',
|
||||
'computer-use-config.json',
|
||||
)
|
||||
const raw = await readFile(configPath, 'utf8')
|
||||
config = JSON.parse(raw) as typeof config
|
||||
} catch {
|
||||
// Config doesn't exist yet — still honor desktop defaults for grant flags.
|
||||
}
|
||||
|
||||
if (!currentToolUseContext) {
|
||||
return
|
||||
}
|
||||
|
||||
const resolved = resolveStoredComputerUseConfig(config)
|
||||
const resolved = await loadStoredComputerUseConfig()
|
||||
const apps = resolved.authorizedApps.map(a => ({
|
||||
bundleId: a.bundleId,
|
||||
displayName: a.displayName,
|
||||
|
||||
Reference in New Issue
Block a user