mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
fix(computer-use): 修复权限检查和应用列表获取的问题 (#157)
* docs: update contributors * fix(computer-use): 修复权限检查和应用列表获取的问题 修复 macOS 平台下权限检查的 JXA 回退逻辑,确保在没有原生模块时仍能正确检测权限 改进应用列表获取方式,使用 mdls 获取真实的 bundleId 而非生成伪 ID * docs: update contributors * docs: update contributors * docs: update contributors --------- Co-authored-by: mcjjin <8590489+mcjjin@users.noreply.github.com> Co-authored-by: claude-code-best <claude-code-best@proton.me> Co-authored-by: claude-code-best <272536312+claude-code-best@users.noreply.github.com>
This commit is contained in:
@@ -26,7 +26,7 @@ export function registerEscHotkey(onEscape: () => void): boolean {
|
||||
if (process.platform !== 'darwin') return false
|
||||
if (registered) return true
|
||||
const cu = requireComputerUseSwift()
|
||||
if (!(cu as any).hotkey.registerEscape(onEscape)) {
|
||||
if (!(cu as any).hotkey?.registerEscape(onEscape)) {
|
||||
// CGEvent.tapCreate failed — typically missing Accessibility permission.
|
||||
// CU still works, just without ESC abort. Mirrors Cowork's escAbort.ts:81.
|
||||
logForDebugging('[cu-esc] registerEscape returned false', { level: 'warn' })
|
||||
@@ -41,7 +41,7 @@ export function registerEscHotkey(onEscape: () => void): boolean {
|
||||
export function unregisterEscHotkey(): void {
|
||||
if (!registered) return
|
||||
try {
|
||||
(requireComputerUseSwift() as any).hotkey.unregister()
|
||||
(requireComputerUseSwift() as any).hotkey?.unregister()
|
||||
} finally {
|
||||
releasePump()
|
||||
registered = false
|
||||
@@ -51,5 +51,5 @@ export function unregisterEscHotkey(): void {
|
||||
|
||||
export function notifyExpectedEscape(): void {
|
||||
if (!registered) return
|
||||
(requireComputerUseSwift() as any).hotkey.notifyExpectedEscape()
|
||||
(requireComputerUseSwift() as any).hotkey?.notifyExpectedEscape()
|
||||
}
|
||||
|
||||
@@ -27,6 +27,38 @@ class DebugLogger implements Logger {
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// JXA-based TCC permission probes (fallback when native .node module absent)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Probe accessibility by asking System Events for a process list. */
|
||||
function checkAccessibilityJXA(): boolean {
|
||||
try {
|
||||
const result = Bun.spawnSync({
|
||||
cmd: ['osascript', '-e', 'tell application "System Events" to get name of every process whose background only is false'],
|
||||
stdout: 'pipe',
|
||||
stderr: 'pipe',
|
||||
})
|
||||
return result.exitCode === 0
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/** Probe screen recording by attempting a 1x1 screencapture. */
|
||||
function checkScreenRecordingJXA(): boolean {
|
||||
try {
|
||||
const result = Bun.spawnSync({
|
||||
cmd: ['screencapture', '-x', '-R', '0,0,1,1', '/dev/null'],
|
||||
stdout: 'pipe',
|
||||
stderr: 'pipe',
|
||||
})
|
||||
return result.exitCode === 0
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let cached: ComputerUseHostAdapter | undefined
|
||||
|
||||
/**
|
||||
@@ -47,8 +79,19 @@ export function getComputerUseHostAdapter(): ComputerUseHostAdapter {
|
||||
ensureOsPermissions: async () => {
|
||||
if (process.platform !== 'darwin') return { granted: true }
|
||||
const cu = requireComputerUseSwift()
|
||||
const accessibility = (cu as any).tcc.checkAccessibility()
|
||||
const screenRecording = (cu as any).tcc.checkScreenRecording()
|
||||
const tcc = (cu as any).tcc
|
||||
// Native Swift .node module provides tcc.checkAccessibility/checkScreenRecording.
|
||||
// When absent (decompiled/reverse-engineered build), fall back to JXA probes.
|
||||
if (tcc) {
|
||||
const accessibility = tcc.checkAccessibility()
|
||||
const screenRecording = tcc.checkScreenRecording()
|
||||
return accessibility && screenRecording
|
||||
? { granted: true }
|
||||
: { granted: false, accessibility, screenRecording }
|
||||
}
|
||||
// JXA fallback: try to query System Events (accessibility) and screencapture (screen recording).
|
||||
const accessibility = checkAccessibilityJXA()
|
||||
const screenRecording = checkScreenRecordingJXA()
|
||||
return accessibility && screenRecording
|
||||
? { granted: true }
|
||||
: { granted: false, accessibility, screenRecording }
|
||||
|
||||
Reference in New Issue
Block a user