-
Notifications
You must be signed in to change notification settings - Fork 14.3k
fix(computer-use): 修复权限检查和应用列表获取的问题 #157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -159,25 +159,33 @@ export const apps: AppsAPI = { | |
|
|
||
| async listInstalled() { | ||
| try { | ||
| const result = await osascript(` | ||
| tell application "System Events" | ||
| set appList to "" | ||
| repeat with appFile in (every file of folder "Applications" of startup disk whose name ends with ".app") | ||
| set appPath to POSIX path of (appFile as alias) | ||
| set appName to name of appFile | ||
| set appList to appList & appPath & "|" & appName & "\\n" | ||
| end repeat | ||
| return appList | ||
| end tell | ||
| `) | ||
| return result.split('\n').filter(Boolean).map(line => { | ||
| const [path, name] = line.split('|', 2) | ||
| const displayName = (name ?? '').replace(/\.app$/, '') | ||
| return { | ||
| bundleId: `com.app.${displayName.toLowerCase().replace(/\s+/g, '-')}`, | ||
| displayName, | ||
| path: path ?? '', | ||
| // Use mdls to enumerate apps and get real bundle identifiers. | ||
| // The previous AppleScript approach generated fake bundle IDs | ||
| // (com.app.display-name) which prevented request_access from matching | ||
| // apps by their real bundle ID (e.g. com.google.Chrome). | ||
| const dirs = ['/Applications', '~/Applications', '/System/Applications'] | ||
| const allApps: InstalledApp[] = [] | ||
| for (const dir of dirs) { | ||
| const expanded = dir.startsWith('~') ? join(process.env.HOME ?? '~', dir.slice(1)) : dir | ||
| const proc = Bun.spawn( | ||
| ['bash', '-c', `for f in "${expanded}"/*.app; do [ -d "$f" ] || continue; bid=$(mdls -name kMDItemCFBundleIdentifier "$f" 2>/dev/null | sed 's/.*= "//;s/"//'); name=$(basename "$f" .app); echo "$f|$name|$bid"; done`], | ||
| { stdout: 'pipe', stderr: 'pipe' }, | ||
| ) | ||
| const text = await new Response(proc.stdout).text() | ||
| await proc.exited | ||
| for (const line of text.split('\n').filter(Boolean)) { | ||
| const [path, displayName, bundleId] = line.split('|', 3) | ||
| if (path && displayName && bundleId && bundleId !== '(null)') { | ||
| allApps.push({ bundleId, displayName, path }) | ||
|
Comment on lines
+171
to
+179
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't use the bundle directory name as
🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
| } | ||
| // Deduplicate by bundleId (prefer /Applications over ~/Applications) | ||
| const seen = new Set<string>() | ||
| return allApps.filter(app => { | ||
| if (seen.has(app.bundleId)) return false | ||
| seen.add(app.bundleId) | ||
| return true | ||
| }) | ||
| } catch { | ||
| return [] | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scan nested app folders too.
Line 171 only matches
*.appdirectly under each root. That misses common locations like/System/Applications/Utilities/Terminal.appand vendor subfolders under/Applications, so those apps never reachlistInstalled()and cannot be granted/launched later.🤖 Prompt for AI Agents